X-Git-Url: http://www.privoxy.org/gitweb/?p=privoxy.git;a=blobdiff_plain;f=jcc.c;h=34327f280db47a94d10ad99ab7b52b62fe734a00;hp=76addcec091a49b3e29ff3b626fad690f1706fed;hb=70b5261cb9a3eb1efedfe94e1f5dc4252dbbd198;hpb=771605c78ec38dd1a37f5dff2bfa80a84d43d7b0 diff --git a/jcc.c b/jcc.c index 76addcec..34327f28 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,3 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.467 2017/06/26 12:18:21 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -6,7 +5,7 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.467 2017/06/26 12:18:21 fabiankeil Exp $" * Purpose : Main file. Contains main() method, main loop, and * the main connection-handling function. * - * Copyright : Written by and Copyright (C) 2001-2017 the + * Copyright : Written by and Copyright (C) 2001-2018 the * Privoxy team. http://www.privoxy.org/ * * Based on the Internet Junkbuster originally written @@ -128,9 +127,6 @@ const char jcc_rcs[] = "$Id: jcc.c,v 1.467 2017/06/26 12:18:21 fabiankeil Exp $" #include "client-tags.h" #endif -const char jcc_h_rcs[] = JCC_H_VERSION; -const char project_h_rcs[] = PROJECT_H_VERSION; - int daemon_mode = 1; struct client_states clients[1]; struct file_list files[1]; @@ -144,7 +140,7 @@ int urls_rejected = 0; /* total nr of urls rejected */ int g_terminate = 0; #endif -#if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA) +#if !defined(_WIN32) && !defined(__OS2__) static void sig_handler(int the_signal); #endif static int client_protocol_is_unsupported(const struct client_state *csp, char *req); @@ -167,12 +163,7 @@ static jb_socket bind_port_helper(const char *haddr, int hport, int backlog); static void bind_ports_helper(struct configuration_spec *config, jb_socket sockets[]); static void close_ports_helper(jb_socket sockets[]); static void listen_loop(void); - -#ifdef AMIGA -void serve(struct client_state *csp); -#else /* ifndef AMIGA */ static void serve(struct client_state *csp); -#endif /* def AMIGA */ #ifdef __BEOS__ static int32 server_thread(void *data); @@ -343,7 +334,7 @@ static const struct cruncher crunchers_light[] = { * * here? */ -#if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA) +#if !defined(_WIN32) && !defined(__OS2__) /********************************************************************* * * Function : sig_handler @@ -394,6 +385,42 @@ static void sig_handler(int the_signal) #endif +/********************************************************************* + * + * Function : get_write_delay + * + * Description : Parse the delay-response parameter. + * + * Parameters : + * 1 : csp = Current client state (buffers, headers, etc...) + * + * Returns : Number of milliseconds to delay writes. + * + *********************************************************************/ +static unsigned int get_write_delay(const struct client_state *csp) +{ + unsigned int delay; + char *endptr; + char *newval; + + if ((csp->action->flags & ACTION_DELAY_RESPONSE) == 0) + { + return 0; + } + newval = csp->action->string[ACTION_STRING_DELAY_RESPONSE]; + + delay = (unsigned)strtol(newval, &endptr, 0); + if (*endptr != '\0') + { + log_error(LOG_LEVEL_FATAL, + "Invalid delay-response{} parameter: '%s'", newval); + } + + return delay; + +} + + /********************************************************************* * * Function : client_protocol_is_unsupported @@ -446,7 +473,8 @@ static int client_protocol_is_unsupported(const struct client_state *csp, char * log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req); freez(req); - write_socket(csp->cfd, response, strlen(response)); + write_socket_delayed(csp->cfd, response, strlen(response), + get_write_delay(csp)); return TRUE; } @@ -478,8 +506,10 @@ static int client_has_unsupported_expectations(const struct client_state *csp) csp->ip_addr_str); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 417 0", csp->ip_addr_str, csp->http->cmd); - write_socket(csp->cfd, UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE, - strlen(UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE)); + write_socket_delayed(csp->cfd, + UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE, + strlen(UNSUPPORTED_CLIENT_EXPECTATION_ERROR_RESPONSE), + get_write_delay(csp)); return TRUE; } @@ -529,7 +559,8 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, csp->http->cmd); - write_socket(csp->cfd, CHEADER, strlen(CHEADER)); + write_socket_delayed(csp->cfd, CHEADER, strlen(CHEADER), + get_write_delay(csp)); destroy_list(headers); return JB_ERR_PARSE; @@ -557,7 +588,8 @@ static jb_err get_request_destination_elsewhere(struct client_state *csp, struct csp->ip_addr_str, csp->http->cmd, req); freez(req); - write_socket(csp->cfd, MISSING_DESTINATION_RESPONSE, strlen(MISSING_DESTINATION_RESPONSE)); + write_socket_delayed(csp->cfd, MISSING_DESTINATION_RESPONSE, + strlen(MISSING_DESTINATION_RESPONSE), get_write_delay(csp)); destroy_list(headers); return JB_ERR_PARSE; @@ -762,7 +794,7 @@ static void log_applied_actions(const struct current_action_spec *actions) * * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) - * 1 : rsp = Fully prepared response. Will be freed on exit. + * 2 : rsp = Fully prepared response. Will be freed on exit. * * Returns : Nothing. * @@ -802,13 +834,13 @@ static void send_crunch_response(const struct client_state *csp, struct http_res csp->ip_addr_str, http->ocmd, status_code, rsp->content_length); /* Write the answer to the client */ - if (write_socket(csp->cfd, rsp->head, rsp->head_length) - || write_socket(csp->cfd, rsp->body, rsp->content_length)) + if (write_socket_delayed(csp->cfd, rsp->head, rsp->head_length, get_write_delay(csp)) + || write_socket_delayed(csp->cfd, rsp->body, rsp->content_length, get_write_delay(csp))) { /* There is nothing we can do about it. */ - log_error(LOG_LEVEL_ERROR, - "Couldn't deliver the error message through client socket %d: %E", - csp->cfd); + log_error(LOG_LEVEL_CONNECT, + "Couldn't deliver the error message for %s through client socket %d: %E", + http->url, csp->cfd); } /* Clean up and return */ @@ -1069,7 +1101,7 @@ static void wait_for_alive_connections(void) * 1 : sfd = Open socket to remember. * 2 : http = The destination for the connection. * 3 : fwd = The forwarder settings used. - * 3 : server_connection = storage. + * 4 : server_connection = storage. * * Returns : void * @@ -1304,8 +1336,9 @@ static char *get_request_line(struct client_state *csp) log_error(LOG_LEVEL_CONNECT, "No request line on socket %d received in time. Timeout: %d.", csp->cfd, csp->config->socket_timeout); - write_socket(csp->cfd, CLIENT_CONNECTION_TIMEOUT_RESPONSE, - strlen(CLIENT_CONNECTION_TIMEOUT_RESPONSE)); + write_socket_delayed(csp->cfd, CLIENT_CONNECTION_TIMEOUT_RESPONSE, + strlen(CLIENT_CONNECTION_TIMEOUT_RESPONSE), + get_write_delay(csp)); } else { @@ -1467,8 +1500,8 @@ static jb_err receive_chunked_client_request_body(struct client_state *csp) } if (status != CHUNK_STATUS_BODY_COMPLETE) { - write_socket(csp->cfd, CLIENT_BODY_PARSE_ERROR_RESPONSE, - strlen(CLIENT_BODY_PARSE_ERROR_RESPONSE)); + write_socket_delayed(csp->cfd, CLIENT_BODY_PARSE_ERROR_RESPONSE, + strlen(CLIENT_BODY_PARSE_ERROR_RESPONSE), get_write_delay(csp)); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Failed reading chunked client body\" 400 0", csp->ip_addr_str); return JB_ERR_PARSE; @@ -1676,7 +1709,8 @@ static jb_err receive_client_request(struct client_state *csp) freez(req); if (JB_ERR_OK != err) { - write_socket(csp->cfd, CHEADER, strlen(CHEADER)); + write_socket_delayed(csp->cfd, CHEADER, strlen(CHEADER), + get_write_delay(csp)); /* XXX: Use correct size */ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request\" 400 0", csp->ip_addr_str); log_error(LOG_LEVEL_ERROR, @@ -1866,7 +1900,7 @@ static jb_err parse_client_request(struct client_state *csp) csp->ip_addr_str); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, csp->http->cmd); - write_socket(csp->cfd, CHEADER, strlen(CHEADER)); + write_socket_delayed(csp->cfd, CHEADER, strlen(CHEADER), get_write_delay(csp)); return JB_ERR_PARSE; } csp->flags |= CSP_FLAG_CLIENT_HEADER_PARSING_DONE; @@ -1879,7 +1913,8 @@ static jb_err parse_client_request(struct client_state *csp) /* * A header filter broke the request line - bail out. */ - write_socket(csp->cfd, MESSED_UP_REQUEST_RESPONSE, strlen(MESSED_UP_REQUEST_RESPONSE)); + write_socket_delayed(csp->cfd, MESSED_UP_REQUEST_RESPONSE, + strlen(MESSED_UP_REQUEST_RESPONSE), get_write_delay(csp)); /* XXX: Use correct size */ log_error(LOG_LEVEL_CLF, "%s - - [%T] \"Invalid request generated\" 500 0", csp->ip_addr_str); @@ -1910,7 +1945,7 @@ static jb_err parse_client_request(struct client_state *csp) * Parameters : * 1 : csp = Current client state (buffers, headers, etc...) * - * Returns : 0 on success, anything else is na error. + * Returns : 0 on success, anything else is an error. * *********************************************************************/ static int send_http_request(struct client_state *csp) @@ -1939,7 +1974,7 @@ static int send_http_request(struct client_state *csp) csp->http->hostport); } else if (((csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING) == 0) - && (flush_socket(csp->server_connection.sfd, csp->client_iob) < 0)) + && (flush_iob(csp->server_connection.sfd, csp->client_iob, 0) < 0)) { write_failure = 1; log_error(LOG_LEVEL_CONNECT, "Failed sending request body to: %s: %E", @@ -1964,10 +1999,8 @@ static int send_http_request(struct client_state *csp) * Returns : Nothing. * *********************************************************************/ -static void handle_established_connection(struct client_state *csp, - const struct forward_spec *fwd) +static void handle_established_connection(struct client_state *csp) { - char *receive_buffer; char *hdr; char *p; int n; @@ -1984,16 +2017,17 @@ static void handle_established_connection(struct client_state *csp, struct http_request *http; long len = 0; /* for buffer sizes (and negative error codes) */ int buffer_and_filter_content = 0; + unsigned int write_delay; /* Skeleton for HTTP response, if we should intercept the request */ struct http_response *rsp; #ifdef FEATURE_CONNECTION_KEEP_ALIVE int watch_client_socket; #endif - const size_t receive_buffer_size = csp->config->receive_buffer_size; - receive_buffer = zalloc(receive_buffer_size + 1); - if (receive_buffer == NULL) + csp->receive_buffer_size = csp->config->receive_buffer_size; + csp->receive_buffer = zalloc(csp->receive_buffer_size + 1); + if (csp->receive_buffer == NULL) { log_error(LOG_LEVEL_ERROR, "Out of memory. Failed to allocate the receive buffer."); @@ -2018,6 +2052,7 @@ static void handle_established_connection(struct client_state *csp, #ifdef FEATURE_CONNECTION_KEEP_ALIVE watch_client_socket = 0 == (csp->flags & CSP_FLAG_PIPELINED_REQUEST_WAITING); #endif + write_delay = get_write_delay(csp); for (;;) { @@ -2124,7 +2159,6 @@ static void handle_established_connection(struct client_state *csp, send_crunch_response(csp, error_response(csp, "connection-timeout")); } mark_server_socket_tainted(csp); - freez(receive_buffer); return; } else if (n < 0) @@ -2135,7 +2169,6 @@ static void handle_established_connection(struct client_state *csp, log_error(LOG_LEVEL_ERROR, "select() failed!: %E"); #endif mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2162,7 +2195,7 @@ static void handle_established_connection(struct client_state *csp, if (FD_ISSET(csp->cfd, &rfds)) #endif /* def HAVE_POLL*/ { - int max_bytes_to_read = (int)receive_buffer_size; + int max_bytes_to_read = (int)csp->receive_buffer_size; #ifdef FEATURE_CONNECTION_KEEP_ALIVE if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ)) @@ -2177,7 +2210,7 @@ static void handle_established_connection(struct client_state *csp, */ watch_client_socket = 0; log_error(LOG_LEVEL_CONNECT, - "Stopping to watch the client socket %d. " + "Stop watching client socket %d. " "There's already another request waiting.", csp->cfd); continue; @@ -2196,7 +2229,7 @@ static void handle_established_connection(struct client_state *csp, } if (csp->expected_client_content_length != 0) { - if (csp->expected_client_content_length < receive_buffer_size) + if (csp->expected_client_content_length < csp->receive_buffer_size) { max_bytes_to_read = (int)csp->expected_client_content_length; } @@ -2204,10 +2237,10 @@ static void handle_established_connection(struct client_state *csp, "Waiting for up to %d bytes from the client.", max_bytes_to_read); } - assert(max_bytes_to_read <= receive_buffer_size); + assert(max_bytes_to_read <= csp->receive_buffer_size); #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ - len = read_socket(csp->cfd, receive_buffer, max_bytes_to_read); + len = read_socket(csp->cfd, csp->receive_buffer, max_bytes_to_read); if (len <= 0) { @@ -2234,11 +2267,10 @@ static void handle_established_connection(struct client_state *csp, } #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ - if (write_socket(csp->server_connection.sfd, receive_buffer, (size_t)len)) + if (write_socket(csp->server_connection.sfd, csp->receive_buffer, (size_t)len)) { log_error(LOG_LEVEL_ERROR, "write to: %s failed: %E", http->host); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } continue; @@ -2272,19 +2304,18 @@ static void handle_established_connection(struct client_state *csp, log_error(LOG_LEVEL_CONNECT, "The server still wants to talk, but the client hung up on us."); mark_server_socket_tainted(csp); - freez(receive_buffer); return; #endif /* def _WIN32 */ } #endif /* def FEATURE_CONNECTION_KEEP_ALIVE */ - len = read_socket(csp->server_connection.sfd, receive_buffer, (int)receive_buffer_size); + len = read_socket(csp->server_connection.sfd, csp->receive_buffer, (int)csp->receive_buffer_size); if (len < 0) { log_error(LOG_LEVEL_ERROR, "read from: %s failed: %E", http->host); - if (http->ssl && (fwd->forward_host == NULL)) + if (http->ssl && (csp->fwd == NULL)) { /* * Just hang up. We already confirmed the client's CONNECT @@ -2293,7 +2324,6 @@ static void handle_established_connection(struct client_state *csp, */ log_error(LOG_LEVEL_ERROR, "CONNECT already confirmed. Unable to tell the client about the problem."); - freez(receive_buffer); return; } else if (byte_count) @@ -2308,7 +2338,6 @@ static void handle_established_connection(struct client_state *csp, log_error(LOG_LEVEL_ERROR, "Already forwarded the original headers. " "Unable to tell the client about the problem."); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } /* @@ -2321,7 +2350,7 @@ static void handle_established_connection(struct client_state *csp, #ifdef FEATURE_CONNECTION_KEEP_ALIVE if (csp->flags & CSP_FLAG_CHUNKED) { - if ((len >= 5) && !memcmp(receive_buffer+len-5, "0\r\n\r\n", 5)) + if ((len >= 5) && !memcmp(csp->receive_buffer+len-5, "0\r\n\r\n", 5)) { /* XXX: this is a temporary hack */ log_error(LOG_LEVEL_CONNECT, @@ -2338,19 +2367,19 @@ static void handle_established_connection(struct client_state *csp, * This is guaranteed by allocating with zalloc_or_die() * and never (intentionally) writing to the last byte. * - * receive_buffer_size is the size of the part of the + * csp->receive_buffer_size is the size of the part of the * buffer we intentionally write to, but we actually - * allocated receive_buffer_size+1 bytes so the assertion + * allocated csp->receive_buffer_size+1 bytes so the assertion * stays within the allocated range. */ - assert(receive_buffer[receive_buffer_size] == '\0'); + assert(csp->receive_buffer[csp->receive_buffer_size] == '\0'); /* * Add a trailing zero to let be able to use string operations. * XXX: do we still need this with filter_popups gone? */ - assert(len <= receive_buffer_size); - receive_buffer[len] = '\0'; + assert(len <= csp->receive_buffer_size); + csp->receive_buffer[len] = '\0'; /* * Normally, this would indicate that we've read @@ -2421,15 +2450,15 @@ static void handle_established_connection(struct client_state *csp, log_error(LOG_LEVEL_FATAL, "Out of memory parsing server header"); } - if (write_socket(csp->cfd, hdr, strlen(hdr)) - || write_socket(csp->cfd, - ((p != NULL) ? p : csp->iob->cur), (size_t)csp->content_length)) + if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay) + || write_socket_delayed(csp->cfd, + ((p != NULL) ? p : csp->iob->cur), + (size_t)csp->content_length, write_delay)) { log_error(LOG_LEVEL_ERROR, "write modified content to client failed: %E"); freez(hdr); freez(p); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2444,8 +2473,8 @@ static void handle_established_connection(struct client_state *csp, * This is NOT the body, so * Let's pretend the server just sent us a blank line. */ - snprintf(receive_buffer, receive_buffer_size, "\r\n"); - len = (int)strlen(receive_buffer); + snprintf(csp->receive_buffer, csp->receive_buffer_size, "\r\n"); + len = (int)strlen(csp->receive_buffer); /* * Now, let the normal header parsing algorithm below do its @@ -2469,7 +2498,7 @@ static void handle_established_connection(struct client_state *csp, * has been reached, switch to non-filtering mode, i.e. make & write the * header, flush the iob and buf, and get out of the way. */ - if (add_to_iob(csp->iob, csp->config->buffer_limit, receive_buffer, len)) + if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len)) { size_t hdrlen; long flushed; @@ -2488,20 +2517,19 @@ static void handle_established_connection(struct client_state *csp, rsp = cgi_error_memory(); send_crunch_response(csp, rsp); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } hdrlen = strlen(hdr); - if (write_socket(csp->cfd, hdr, hdrlen) - || ((flushed = flush_socket(csp->cfd, csp->iob)) < 0) - || (write_socket(csp->cfd, receive_buffer, (size_t)len))) + if (write_socket_delayed(csp->cfd, hdr, hdrlen, write_delay) + || ((flushed = flush_iob(csp->cfd, csp->iob, write_delay)) < 0) + || write_socket_delayed(csp->cfd, csp->receive_buffer, + (size_t)len, write_delay)) { log_error(LOG_LEVEL_CONNECT, "Flush header and buffers to client failed: %E"); freez(hdr); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2518,11 +2546,11 @@ static void handle_established_connection(struct client_state *csp, } else { - if (write_socket(csp->cfd, receive_buffer, (size_t)len)) + if (write_socket_delayed(csp->cfd, csp->receive_buffer, + (size_t)len, write_delay)) { log_error(LOG_LEVEL_ERROR, "write to client failed: %E"); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } } @@ -2536,13 +2564,12 @@ static void handle_established_connection(struct client_state *csp, * Buffer up the data we just read. If that fails, there's * little we can do but send our static out-of-memory page. */ - if (add_to_iob(csp->iob, csp->config->buffer_limit, receive_buffer, len)) + if (add_to_iob(csp->iob, csp->config->buffer_limit, csp->receive_buffer, len)) { log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers."); rsp = cgi_error_memory(); send_crunch_response(csp, rsp); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2560,10 +2587,10 @@ static void handle_established_connection(struct client_state *csp, "Applying the MS IIS5 hack didn't help."); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); - write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + write_socket_delayed(csp->cfd, + INVALID_SERVER_HEADERS_RESPONSE, + strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } else @@ -2609,7 +2636,6 @@ static void handle_established_connection(struct client_state *csp, } free_http_request(http); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } @@ -2631,8 +2657,8 @@ static void handle_established_connection(struct client_state *csp, csp->headers->first->str); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); - write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, + strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay); free_http_request(http); mark_server_socket_tainted(csp); return; @@ -2646,11 +2672,10 @@ static void handle_established_connection(struct client_state *csp, { log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); - write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, + strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay); free_http_request(http); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } hdr = list_to_text(csp->headers); @@ -2685,7 +2710,6 @@ static void handle_established_connection(struct client_state *csp, */ freez(hdr); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } /* Buffer and pcrs filter this if appropriate. */ @@ -2705,8 +2729,8 @@ static void handle_established_connection(struct client_state *csp, * may be in the buffer) */ - if (write_socket(csp->cfd, hdr, strlen(hdr)) - || ((len = flush_socket(csp->cfd, csp->iob)) < 0)) + if (write_socket_delayed(csp->cfd, hdr, strlen(hdr), write_delay) + || ((len = flush_iob(csp->cfd, csp->iob, write_delay)) < 0)) { log_error(LOG_LEVEL_CONNECT, "write header to client failed: %E"); @@ -2716,7 +2740,6 @@ static void handle_established_connection(struct client_state *csp, */ freez(hdr); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } } @@ -2738,20 +2761,17 @@ static void handle_established_connection(struct client_state *csp, "Applying the MS IIS5 hack didn't help."); log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd); - write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, - strlen(INVALID_SERVER_HEADERS_RESPONSE)); + write_socket_delayed(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE, + strlen(INVALID_SERVER_HEADERS_RESPONSE), write_delay); mark_server_socket_tainted(csp); - freez(receive_buffer); return; } } continue; } mark_server_socket_tainted(csp); - freez(receive_buffer); return; /* huh? we should never get here */ } - freez(receive_buffer); if (csp->content_length == 0) { @@ -3020,7 +3040,8 @@ static void chat(struct client_state *csp) * message to the client, flush the rest, and get out of the way. */ list_remove_all(csp->headers); - if (write_socket(csp->cfd, CSUCCEED, strlen(CSUCCEED))) + if (write_socket_delayed(csp->cfd, CSUCCEED, + strlen(CSUCCEED), get_write_delay(csp))) { return; } @@ -3032,7 +3053,8 @@ static void chat(struct client_state *csp) /* XXX: should the time start earlier for optimistically sent data? */ csp->server_connection.request_sent = time(NULL); - handle_established_connection(csp, fwd); + handle_established_connection(csp); + freez(csp->receive_buffer); } @@ -3069,6 +3091,7 @@ extern int fuzz_server_response(struct client_state *csp, char *fuzz_input_file) fuzz_input_file); } } + csp->fwd = &fwd; csp->content_type |= CT_GIF; csp->action->flags |= ACTION_DEANIMATE; csp->action->string[ACTION_STRING_DEANIMATE] = "last"; @@ -3089,7 +3112,8 @@ extern int fuzz_server_response(struct client_state *csp, char *fuzz_input_file) cgi_init_error_messages(); - handle_established_connection(csp, &fwd); + handle_established_connection(csp); + freez(csp->receive_buffer); return 0; } @@ -3188,11 +3212,7 @@ static void prepare_csp_for_next_request(struct client_state *csp) * Returns : N/A * *********************************************************************/ -#ifdef AMIGA -void serve(struct client_state *csp) -#else /* ifndef AMIGA */ static void serve(struct client_state *csp) -#endif /* def AMIGA */ { int config_file_change_detected = 0; /* Only used for debugging */ #ifdef FEATURE_CONNECTION_KEEP_ALIVE @@ -3837,9 +3857,7 @@ int main(int argc, char **argv) clients->next = NULL; /* XXX: factor out initialising after the next stable release. */ -#ifdef AMIGA - InitAmiga(); -#elif defined(_WIN32) +#ifdef _WIN32 InitWin32(); #endif @@ -3862,7 +3880,7 @@ int main(int argc, char **argv) * are handled when and where they occur without relying * on a signal. */ -#if !defined(_WIN32) && !defined(__OS2__) && !defined(AMIGA) +#if !defined(_WIN32) && !defined(__OS2__) { int idx; const int catched_signals[] = { SIGTERM, SIGINT, SIGHUP }; @@ -4003,8 +4021,10 @@ int main(int argc, char **argv) * As soon as we have written the PID file, we can switch * to the user and group ID indicated by the --user option */ - write_pid_file(); - + if (pidfile != NULL) + { + write_pid_file(pidfile); + } if (NULL != pw) { if (setgid((NULL != grp) ? grp->gr_gid : pw->pw_gid)) @@ -4322,12 +4342,12 @@ static void listen_loop(void) for (;;) #endif { -#if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) && !defined(__OS2__) +#if !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(__OS2__) while (waitpid(-1, NULL, WNOHANG) > 0) { /* zombie children */ } -#endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) && !defined(AMIGA) */ +#endif /* !defined(FEATURE_PTHREAD) && !defined(_WIN32) && !defined(__BEOS__) */ /* * Free data that was used by died threads @@ -4364,13 +4384,6 @@ static void listen_loop(void) if (!accept_connection(csp, bfds)) { log_error(LOG_LEVEL_CONNECT, "accept failed: %E"); - -#ifdef AMIGA - if (!childs) - { - exit(1); - } -#endif freez(csp_list); continue; } @@ -4433,8 +4446,8 @@ static void listen_loop(void) log_error(LOG_LEVEL_CONNECT, "Rejecting connection from %s. Maximum number of connections reached.", csp->ip_addr_str); - write_socket(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE, - strlen(TOO_MANY_CONNECTIONS_RESPONSE)); + write_socket_delayed(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE, + strlen(TOO_MANY_CONNECTIONS_RESPONSE), get_write_delay(csp)); close_socket(csp->cfd); freez(csp->ip_addr_str); freez(csp->listen_addr_str); @@ -4499,34 +4512,6 @@ static void listen_loop(void) } #endif -#if defined(AMIGA) && !defined(SELECTED_ONE_OPTION) -#define SELECTED_ONE_OPTION - csp->cfd = ReleaseSocket(csp->cfd, -1); - -#ifdef __amigaos4__ - child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread, - NP_Output, Output(), - NP_CloseOutput, FALSE, - NP_Name, (ULONG)"privoxy child", - NP_Child, TRUE, - TAG_DONE); -#else - child_id = (int)CreateNewProcTags(NP_Entry, (ULONG)server_thread, - NP_Output, Output(), - NP_CloseOutput, FALSE, - NP_Name, (ULONG)"privoxy child", - NP_StackSize, 200*1024, - TAG_DONE); -#endif - if (0 != child_id) - { - childs++; - ((struct Task *)child_id)->tc_UserData = csp; - Signal((struct Task *)child_id, SIGF_SINGLE); - Wait(SIGF_SINGLE); - } -#endif - #if !defined(SELECTED_ONE_OPTION) child_id = fork(); @@ -4614,8 +4599,8 @@ static void listen_loop(void) log_error(LOG_LEVEL_ERROR, "Unable to take any additional connections: %E. Active threads: %d", active_threads); - write_socket(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE, - strlen(TOO_MANY_CONNECTIONS_RESPONSE)); + write_socket_delayed(csp->cfd, TOO_MANY_CONNECTIONS_RESPONSE, + strlen(TOO_MANY_CONNECTIONS_RESPONSE), get_write_delay(csp)); close_socket(csp->cfd); csp->flags &= ~CSP_FLAG_ACTIVE; }