X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=cgi.c;h=0583f88a345c17daab459877f2e6f051d7f913fe;hp=526381fca9bd55cf82448c2e2d11a7d11e580c8c;hb=58842b486231d1910f7d11132f55e805ec333ed4;hpb=2942491e2f149f232fc55b984bbf4aa93621eb90 diff --git a/cgi.c b/cgi.c index 526381fc..0583f88a 100644 --- a/cgi.c +++ b/cgi.c @@ -1,4 +1,4 @@ -const char cgi_rcs[] = "$Id: cgi.c,v 1.124 2009/06/12 11:03:03 fabiankeil Exp $"; +const char cgi_rcs[] = "$Id: cgi.c,v 1.130 2011/04/19 13:00:47 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgi.c,v $ @@ -49,6 +49,10 @@ const char cgi_rcs[] = "$Id: cgi.c,v 1.124 2009/06/12 11:03:03 fabiankeil Exp $" #include #include +#ifdef FEATURE_COMPRESSION +#include +#endif + #include "project.h" #include "cgi.h" #include "list.h" @@ -553,7 +557,7 @@ static struct http_response *dispatch_known_cgi(struct client_state * csp, if (!err) { /* It worked */ - rsp->reason = RSP_REASON_CGI_CALL; + rsp->crunch_reason = CGI_CALL; return finish_http_response(csp, rsp); } else @@ -876,7 +880,7 @@ struct http_response *error_response(struct client_state *csp, if (!strcmp(templatename, "no-such-domain")) { rsp->status = strdup("404 No such domain"); - rsp->reason = RSP_REASON_NO_SUCH_DOMAIN; + rsp->crunch_reason = NO_SUCH_DOMAIN; } else if (!strcmp(templatename, "forwarding-failed")) { @@ -938,22 +942,22 @@ struct http_response *error_response(struct client_state *csp, } rsp->status = strdup("503 Forwarding failure"); - rsp->reason = RSP_REASON_FORWARDING_FAILED; + rsp->crunch_reason = FORWARDING_FAILED; } else if (!strcmp(templatename, "connect-failed")) { rsp->status = strdup("503 Connect failed"); - rsp->reason = RSP_REASON_CONNECT_FAILED; + rsp->crunch_reason = CONNECT_FAILED; } else if (!strcmp(templatename, "connection-timeout")) { rsp->status = strdup("504 Connection timeout"); - rsp->reason = RSP_REASON_CONNECTION_TIMEOUT; + rsp->crunch_reason = CONNECTION_TIMEOUT; } else if (!strcmp(templatename, "no-server-data")) { rsp->status = strdup("502 No data received from server or forwarder"); - rsp->reason = RSP_REASON_NO_SERVER_DATA; + rsp->crunch_reason = NO_SERVER_DATA; } if (rsp->status == NULL) @@ -1053,7 +1057,7 @@ void cgi_init_error_messages(void) strlen(cgi_error_memory_response->head); cgi_error_memory_response->content_length = strlen(cgi_error_memory_response->body); - cgi_error_memory_response->reason = RSP_REASON_OUT_OF_MEMORY; + cgi_error_memory_response->crunch_reason = OUT_OF_MEMORY; } @@ -1224,7 +1228,7 @@ jb_err cgi_error_unknown(const struct client_state *csp, rsp->content_length = 0; rsp->head_length = 0; rsp->is_static = 0; - rsp->reason = RSP_REASON_INTERNAL_ERROR; + rsp->crunch_reason = INTERNAL_ERROR; snprintf(errnumbuf, sizeof(errnumbuf), "%d", error_to_report); @@ -1362,7 +1366,7 @@ char *add_help_link(const char *item, string_join (&result, string_toupper(item)); string_append(&result, "\">"); string_append(&result, item); - string_append(&result, " "); + string_append(&result, ""); return result; } @@ -1479,6 +1483,59 @@ static void get_locale_time(char *buf, size_t buffer_size) } + +#ifdef FEATURE_COMPRESSION +/********************************************************************* + * + * Function : compress_buffer + * + * Description : Compresses the content of a buffer with zlib's deflate + * Allocates a new buffer for the result, free'ing it is + * up to the caller. + * + * XXX: We should add a config option for the + * compression level. + * + * + * Parameters : + * 1 : buffer = buffer whose content should be compressed + * 2 : buffer_length = length of the buffer + * + * Returns : NULL on error, otherwise a pointer to the compressed + * content of the input buffer. + * + *********************************************************************/ +char *compress_buffer(char *buffer, size_t *buffer_length) +{ + char *compressed_buffer; + size_t new_length = *buffer_length; + + compressed_buffer = malloc(new_length); + if (NULL == compressed_buffer) + { + log_error(LOG_LEVEL_FATAL, + "Out of memory allocation compression buffer."); + } + + if (Z_OK != compress2((Bytef *)compressed_buffer, &new_length, + (Bytef *)buffer, *buffer_length, Z_DEFAULT_COMPRESSION)) + { + log_error(LOG_LEVEL_ERROR, "Error in compress2()"); + freez(compressed_buffer); + return NULL; + } + + log_error(LOG_LEVEL_RE_FILTER, + "Compressed content from %d to %d bytes.", *buffer_length, new_length); + + *buffer_length = new_length; + + return compressed_buffer; + +} +#endif + + /********************************************************************* * * Function : finish_http_response @@ -1524,6 +1581,23 @@ struct http_response *finish_http_response(const struct client_state *csp, struc { rsp->content_length = rsp->body ? strlen(rsp->body) : 0; } + +#ifdef FEATURE_COMPRESSION + if (!err && (csp->flags & CSP_FLAG_CLIENT_SUPPORTS_DEFLATE) + && (rsp->content_length > LOWER_LENGTH_LIMIT_FOR_COMRPESSION)) + { + char *compressed_content; + + compressed_content = compress_buffer(rsp->body, &rsp->content_length); + if (NULL != compressed_content) + { + freez(rsp->body); + rsp->body = compressed_content; + } + err = enlist_unique_header(rsp->headers, "Content-Encoding", "deflate"); + } +#endif + if (!err) { snprintf(buf, sizeof(buf), "Content-Length: %d", (int)rsp->content_length); @@ -1636,13 +1710,10 @@ struct http_response *finish_http_response(const struct client_state *csp, struc if (!err) err = enlist_unique_header(rsp->headers, "Pragma", "no-cache"); } - /* - * Quoting RFC 2616: - * - * HTTP/1.1 applications that do not support persistent connections MUST - * include the "close" connection option in every message. - */ - if (!err) err = enlist_unique_header(rsp->headers, "Connection", "close"); + if (!err && !(csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)) + { + err = enlist_unique_header(rsp->headers, "Connection", "close"); + } /* * Write the head @@ -1865,7 +1936,7 @@ jb_err template_load(const struct client_state *csp, char **template_ptr, * HTML template by replacing @name@ with value using * pcrs, for each item in the output map. * - * Note that a leading '$' charachter in the export map's + * Note that a leading '$' character in the export map's * values will be stripped and toggle on backreference * interpretation. *