-const char parsers_rcs[] = "$Id: parsers.c,v 1.247 2012/07/27 17:36:06 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.261 2012/11/09 10:46:06 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/parsers.c,v $
*
* 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;
* 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;
}
}
/* 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;
}
+/*********************************************************************
+ *
+ * Function : clear_iob
+ *
+ * Description : Frees the memory allocated for an I/O buffer and
+ * resets the structure.
+ *
+ * Parameters :
+ * 1 : iob = I/O buffer to clear.
+ *
+ * Returns : JB_ERR_OK on success, JB_ERR_MEMORY if out-of-memory
+ * or buffer limit reached.
+ *
+ *********************************************************************/
+void clear_iob(struct iob *iob)
+{
+ free(iob->buf);
+ memset(iob, '\0', sizeof(*iob));;
+}
+
+
#ifdef FEATURE_ZLIB
/*********************************************************************
*
}
else if (csp->content_type & CT_DEFLATE)
{
- /*
- * XXX: The debug level should be lowered
- * before the next stable release.
- */
- log_error(LOG_LEVEL_INFO, "Decompressing deflated iob: %d", *cur);
/*
* In theory (that is, according to RFC 1950), deflate-compressed
* data should begin with a two-byte zlib header and have an
if (!strcmpic(*header, connection_close))
{
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
- if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING))
+ if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_SHARING)
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
{
if (!strcmpic(csp->http->ver, "HTTP/1.1"))
{
csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
}
}
- else if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE))
+ else if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
{
log_error(LOG_LEVEL_HEADER,
"Keeping the client header '%s' around. "
freez(old_header);
}
- /* Signal client_connection_adder() to return early. */
+ /* Signal client_connection_header_adder() to return early. */
csp->flags |= CSP_FLAG_CLIENT_CONNECTION_HEADER_SET;
return JB_ERR_OK;
*********************************************************************/
static jb_err client_send_cookie(struct client_state *csp, char **header)
{
- if (csp->action->flags & ACTION_NO_COOKIE_READ)
+ if (csp->action->flags & ACTION_CRUNCH_OUTGOING_COOKIES)
{
log_error(LOG_LEVEL_HEADER, "Crunched outgoing cookie: %s", *header);
freez(*header);
* Function : server_proxy_connection_adder
*
* Description : Adds a "Proxy-Connection: keep-alive" header to
- * csp->headers if the client asked for keep-alive.
- * XXX: We should reuse existent ones.
+ * csp->headers when appropriate.
*
* Parameters :
* 1 : csp = Current client state (buffers, headers, etc...)
if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
&& !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
- && !(csp->flags & CSP_FLAG_SERVER_PROXY_CONNECTION_HEADER_SET))
+ && !(csp->flags & CSP_FLAG_SERVER_PROXY_CONNECTION_HEADER_SET)
+ && ((csp->flags & CSP_FLAG_SERVER_CONTENT_LENGTH_SET)
+ || (csp->flags & CSP_FLAG_CHUNKED)))
{
log_error(LOG_LEVEL_HEADER, "Adding: %s", proxy_connection_header);
err = enlist(csp->headers, proxy_connection_header);
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
&& (csp->http->ssl == 0)
&& !strcmpic(csp->http->ver, "HTTP/1.1"))
{
time_t now;
time_t cookie_time;
- time(&now);
-
- if ((csp->action->flags & ACTION_NO_COOKIE_SET) != 0)
+ if ((csp->action->flags & ACTION_CRUNCH_INCOMING_COOKIES) != 0)
{
log_error(LOG_LEVEL_HEADER, "Crunching incoming cookie: %s", *header);
freez(*header);
}
- else if ((csp->action->flags & ACTION_NO_COOKIE_KEEP) != 0)
+ else if ((csp->action->flags & ACTION_SESSION_COOKIES_ONLY) != 0)
{
/* Flag whether or not to log a message */
int changed = 0;
cur_tag++;
}
+ time(&now);
+
/* Loop through each tag in the cookie */
while (*cur_tag)
{
}
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+/*********************************************************************
+ *
+ * Function : get_expected_content_length
+ *
+ * Description : Figures out the content length from a list of headers.
+ *
+ * Parameters :
+ * 1 : headers = List of headers
+ *
+ * Returns : Number of bytes to expect
+ *
+ *********************************************************************/
+unsigned long long get_expected_content_length(struct list *headers)
+{
+ const char *content_length_header;
+ unsigned long long content_length = 0;
+
+ content_length_header = get_header_value(headers, "Content-Length:");
+ if (content_length_header != NULL)
+ {
+ if (JB_ERR_OK != get_content_length(content_length_header, &content_length))
+ {
+ log_error(LOG_LEVEL_ERROR,
+ "Failed to get the Content-Length in %s", content_length_header);
+ /* XXX: The header will be removed later on */
+ return 0;
+ }
+ }
+
+ return content_length;
+}
+#endif
+
/*
Local Variables:
tab-width: 3