From 5908e5c4c1a5f4a19602dfa42b7a9af5c2c2dfe2 Mon Sep 17 00:00:00 2001 From: Fabian Keil Date: Sun, 21 Oct 2012 12:39:27 +0000 Subject: [PATCH] Use a dedicated iob for the data read from the client This is necessary to support client-side pipelining. --- cgisimple.c | 6 +++--- jcc.c | 30 +++++++++++++++--------------- parsers.c | 24 ++++++++++++------------ parsers.h | 4 ++-- project.h | 8 ++++++-- 5 files changed, 38 insertions(+), 34 deletions(-) diff --git a/cgisimple.c b/cgisimple.c index 95cb7ad6..fd488586 100644 --- a/cgisimple.c +++ b/cgisimple.c @@ -1,4 +1,4 @@ -const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.114 2012/03/09 16:24:36 fabiankeil Exp $"; +const char cgisimple_rcs[] = "$Id: cgisimple.c,v 1.115 2012/03/09 17:55:49 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/cgisimple.c,v $ @@ -255,7 +255,7 @@ jb_err cgi_show_request(struct client_state *csp, /* * Repair the damage done to the IOB by get_header() */ - for (p = csp->iob->buf; p < csp->iob->eod; p++) + for (p = csp->client_iob->buf; p < csp->client_iob->eod; p++) { if (*p == '\0') *p = '\n'; } @@ -265,7 +265,7 @@ jb_err cgi_show_request(struct client_state *csp, * be sending to the server if this wasn't a CGI call */ - if (map(exports, "client-request", 1, html_encode(csp->iob->buf), 0)) + if (map(exports, "client-request", 1, html_encode(csp->client_iob->buf), 0)) { free_map(exports); return JB_ERR_MEMORY; diff --git a/jcc.c b/jcc.c index 4a9125fc..5946ca43 100644 --- a/jcc.c +++ b/jcc.c @@ -1,4 +1,4 @@ -const char jcc_rcs[] = "$Id: jcc.c,v 1.391 2012/10/21 12:35:15 fabiankeil Exp $"; +const char jcc_rcs[] = "$Id: jcc.c,v 1.392 2012/10/21 12:36:25 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/jcc.c,v $ @@ -1079,7 +1079,7 @@ void save_connection_destination(jb_socket sfd, static void verify_request_length(struct client_state *csp) { unsigned long long buffered_request_bytes = - (unsigned long long)(csp->iob->eod - csp->iob->cur); + (unsigned long long)(csp->client_iob->eod - csp->client_iob->cur); if ((csp->expected_client_content_length != 0) && (buffered_request_bytes != 0)) @@ -1093,8 +1093,8 @@ static void verify_request_length(struct client_state *csp) } else { - assert(csp->iob->eod > csp->iob->cur + csp->expected_client_content_length); - csp->iob->eod = csp->iob->cur + csp->expected_client_content_length; + assert(csp->client_iob->eod > csp->client_iob->cur + csp->expected_client_content_length); + csp->client_iob->eod = csp->client_iob->cur + csp->expected_client_content_length; log_error(LOG_LEVEL_CONNECT, "Reducing expected bytes to 0. " "Marking the server socket tainted after throwing %llu bytes away.", buffered_request_bytes - csp->expected_client_content_length); @@ -1109,7 +1109,7 @@ static void verify_request_length(struct client_state *csp) } if (!(csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ) - && ((csp->iob->cur[0] != '\0') || (csp->expected_client_content_length != 0))) + && ((csp->client_iob->cur[0] != '\0') || (csp->expected_client_content_length != 0))) { csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED; if (strcmpic(csp->http->gpc, "GET") @@ -1131,8 +1131,8 @@ static void verify_request_length(struct client_state *csp) "Possible pipeline attempt detected. The connection will not " "be kept alive and we will only serve the first request."); /* Nuke the pipelined requests from orbit, just to be sure. */ - csp->iob->buf[0] = '\0'; - csp->iob->eod = csp->iob->cur = csp->iob->buf; + csp->client_iob->buf[0] = '\0'; + csp->client_iob->eod = csp->client_iob->cur = csp->client_iob->buf; } } else @@ -1225,12 +1225,12 @@ static char *get_request_line(struct client_state *csp) * If there is no memory left for buffering the * request, there is nothing we can do but hang up */ - if (add_to_iob(csp, buf, len)) + if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len)) { return NULL; } - request_line = get_header(csp->iob); + request_line = get_header(csp->client_iob); } while ((NULL != request_line) && ('\0' == *request_line)); @@ -1322,7 +1322,7 @@ static jb_err receive_client_request(struct client_state *csp) init_list(headers); for (;;) { - p = get_header(csp->iob); + p = get_header(csp->client_iob); if (p == NULL) { @@ -1352,7 +1352,7 @@ static jb_err receive_client_request(struct client_state *csp) return JB_ERR_PARSE; } - if (add_to_iob(csp, buf, len)) + if (add_to_iob(csp->client_iob, csp->config->buffer_limit, buf, len)) { /* * If there is no memory left for buffering the @@ -1715,7 +1715,7 @@ static void chat(struct client_state *csp) * (along with anything else that may be in the buffer) */ if (write_socket(csp->server_connection.sfd, hdr, strlen(hdr)) - || (flush_socket(csp->server_connection.sfd, csp->iob) < 0)) + || (flush_socket(csp->server_connection.sfd, csp->client_iob) < 0)) { log_error(LOG_LEVEL_CONNECT, "write header to: %s failed: %E", http->hostport); @@ -1743,7 +1743,7 @@ static void chat(struct client_state *csp) { return; } - IOB_RESET(csp->iob); + IOB_RESET(csp->client_iob); } log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport); @@ -2144,7 +2144,7 @@ static void chat(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, buf, len)) + if (add_to_iob(csp->iob, csp->config->buffer_limit, buf, len)) { size_t hdrlen; long flushed; @@ -2208,7 +2208,7 @@ static void chat(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, buf, len)) + if (add_to_iob(csp->iob, csp->config->buffer_limit, buf, len)) { log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers."); rsp = cgi_error_memory(); diff --git a/parsers.c b/parsers.c index 5489288e..2ea779a5 100644 --- a/parsers.c +++ b/parsers.c @@ -1,4 +1,4 @@ -const char parsers_rcs[] = "$Id: parsers.c,v 1.255 2012/10/17 18:19:29 fabiankeil Exp $"; +const char parsers_rcs[] = "$Id: parsers.c,v 1.256 2012/10/17 18:19:59 fabiankeil Exp $"; /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.c,v $ @@ -280,21 +280,21 @@ long flush_socket(jb_socket fd, struct iob *iob) * * Function : add_to_iob * - * Description : Add content to the buffered page, expanding the + * Description : Add content to the buffer, expanding the * buffer if necessary. * * Parameters : - * 1 : csp = Current client state (buffers, headers, etc...) - * 2 : buf = holds the content to be added to the page - * 3 : n = number of bytes to be added + * 1 : iob = Destination buffer. + * 2 : buffer_limit = Limit to which the destination may grow + * 3 : src = holds the content to be added + * 4 : n = number of bytes to be added * * Returns : JB_ERR_OK on success, JB_ERR_MEMORY if out-of-memory * or buffer limit reached. * *********************************************************************/ -jb_err add_to_iob(struct client_state *csp, char *buf, long n) +jb_err add_to_iob(struct iob *iob, const size_t buffer_limit, char *src, long n) { - struct iob *iob = csp->iob; size_t used, offset, need; char *p; @@ -308,24 +308,24 @@ jb_err add_to_iob(struct client_state *csp, char *buf, long n) * If the buffer can't hold the new data, extend it first. * Use the next power of two if possible, else use the actual need. */ - if (need > csp->config->buffer_limit) + if (need > buffer_limit) { log_error(LOG_LEVEL_INFO, "Buffer limit reached while extending the buffer (iob). Needed: %d. Limit: %d", - need, csp->config->buffer_limit); + need, buffer_limit); return JB_ERR_MEMORY; } if (need > iob->size) { - size_t want = csp->iob->size ? csp->iob->size : 512; + size_t want = iob->size ? iob->size : 512; while (want <= need) { want *= 2; } - if (want <= csp->config->buffer_limit && NULL != (p = (char *)realloc(iob->buf, want))) + if (want <= buffer_limit && NULL != (p = (char *)realloc(iob->buf, want))) { iob->size = want; } @@ -346,7 +346,7 @@ jb_err add_to_iob(struct client_state *csp, char *buf, long n) } /* copy the new data into the iob buffer */ - memcpy(iob->eod, buf, (size_t)n); + memcpy(iob->eod, src, (size_t)n); /* point to the end of the data */ iob->eod += n; diff --git a/parsers.h b/parsers.h index 44dbcc76..c8010688 100644 --- a/parsers.h +++ b/parsers.h @@ -1,6 +1,6 @@ #ifndef PARSERS_H_INCLUDED #define PARSERS_H_INCLUDED -#define PARSERS_H_VERSION "$Id: parsers.h,v 1.51 2011/09/04 11:10:56 fabiankeil Exp $" +#define PARSERS_H_VERSION "$Id: parsers.h,v 1.52 2012/09/04 08:33:31 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/parsers.h,v $ @@ -55,7 +55,7 @@ extern "C" { #define FILTER_SERVER_HEADERS 1 extern long flush_socket(jb_socket fd, struct iob *iob); -extern jb_err add_to_iob(struct client_state *csp, char *buf, long n); +extern jb_err add_to_iob(struct iob *iob, const size_t buffer_limit, char *src, long n); extern jb_err decompress_iob(struct client_state *csp); extern char *get_header(struct iob *iob); extern char *get_header_value(const struct list *header_list, const char *header_name); diff --git a/project.h b/project.h index 447d5138..f0d72603 100644 --- a/project.h +++ b/project.h @@ -1,7 +1,7 @@ #ifndef PROJECT_H_INCLUDED #define PROJECT_H_INCLUDED /** Version string. */ -#define PROJECT_H_VERSION "$Id: project.h,v 1.183 2012/10/21 12:31:21 fabiankeil Exp $" +#define PROJECT_H_VERSION "$Id: project.h,v 1.184 2012/10/21 12:35:15 fabiankeil Exp $" /********************************************************************* * * File : $Source: /cvsroot/ijbswa/current/project.h,v $ @@ -902,9 +902,13 @@ struct client_state */ struct forward_spec * fwd; - /** An I/O buffer used for buffering data read from the network */ + /** An I/O buffer used for buffering data read from the server */ + /* XXX: should be renamed to server_iob */ struct iob iob[1]; + /** An I/O buffer used for buffering data read from the client */ + struct iob client_iob[1]; + /** List of all headers for this request */ struct list headers[1]; -- 2.39.2