Use a dedicated iob for the data read from the client
authorFabian Keil <fk@fabiankeil.de>
Sun, 21 Oct 2012 12:39:27 +0000 (12:39 +0000)
committerFabian Keil <fk@fabiankeil.de>
Sun, 21 Oct 2012 12:39:27 +0000 (12:39 +0000)
This is necessary to support client-side pipelining.

cgisimple.c
jcc.c
parsers.c
parsers.h
project.h

index 95cb7ad..fd48858 100644 (file)
@@ -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 $
 /*********************************************************************
  *
  * 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()
     */
    /*
     * 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';
    }
    {
       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
     */
 
     * 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;
    {
       free_map(exports);
       return JB_ERR_MEMORY;
diff --git a/jcc.c b/jcc.c
index 4a9125f..5946ca4 100644 (file)
--- 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 $
 /*********************************************************************
  *
  * 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 =
 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))
 
    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
       {
       }
       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);
          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)
    }
 
    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")
    {
       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. */
             "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
       }
    }
    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 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;
       }
 
       {
          return NULL;
       }
 
-      request_line = get_header(csp->iob);
+      request_line = get_header(csp->client_iob);
 
    } while ((NULL != request_line) && ('\0' == *request_line));
 
 
    } 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 (;;)
    {
    init_list(headers);
    for (;;)
    {
-      p = get_header(csp->iob);
+      p = get_header(csp->client_iob);
 
       if (p == NULL)
       {
 
       if (p == NULL)
       {
@@ -1352,7 +1352,7 @@ static jb_err receive_client_request(struct client_state *csp)
             return JB_ERR_PARSE;
          }
 
             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
          {
             /*
              * 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))
        * (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);
       {
          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;
       }
       {
          return;
       }
-      IOB_RESET(csp->iob);
+      IOB_RESET(csp->client_iob);
    }
 
    log_error(LOG_LEVEL_CONNECT, "to %s successful", http->hostport);
    }
 
    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.
                 */
                 * 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;
                {
                   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.
              */
              * 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();
             {
                log_error(LOG_LEVEL_ERROR, "Out of memory while looking for end of server headers.");
                rsp = cgi_error_memory();
index 5489288..2ea779a 100644 (file)
--- 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 $
 /*********************************************************************
  *
  * 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
  *
  *
  * 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  :
  *                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.
  *
  *********************************************************************/
  *
  * 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;
 
    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 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",
    {
       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)
    {
       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;
       }
 
 
       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;
       }
       {
          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 */
    }
 
    /* 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;
 
    /* point to the end of the data */
    iob->eod += n;
index 44dbcc7..c801068 100644 (file)
--- a/parsers.h
+++ b/parsers.h
@@ -1,6 +1,6 @@
 #ifndef PARSERS_H_INCLUDED
 #define PARSERS_H_INCLUDED
 #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 $
 /*********************************************************************
  *
  * 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);
 #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);
 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);
index 447d513..f0d7260 100644 (file)
--- a/project.h
+++ b/project.h
@@ -1,7 +1,7 @@
 #ifndef PROJECT_H_INCLUDED
 #define PROJECT_H_INCLUDED
 /** Version string. */
 #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 $
 /*********************************************************************
  *
  * File        :  $Source: /cvsroot/ijbswa/current/project.h,v $
@@ -902,9 +902,13 @@ struct client_state
     */
    struct forward_spec * fwd;
 
     */
    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];
 
    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];
 
    /** List of all headers for this request */
    struct list headers[1];