-const char parsers_rcs[] = "$Id: parsers.c,v 1.193 2009/07/11 11:15:53 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.200 2009/07/19 09:24:17 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/parsers.c,v $
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
static jb_err server_save_content_length(struct client_state *csp, char **header);
static jb_err server_keep_alive(struct client_state *csp, char **header);
+static jb_err server_proxy_connection(struct client_state *csp, char **header);
static jb_err client_keep_alive(struct client_state *csp, char **header);
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
{ "Content-Length:", 15, server_save_content_length },
{ "Keep-Alive:", 11, server_keep_alive },
+ { "Proxy-Connection:", 17, server_proxy_connection },
#else
{ "Keep-Alive:", 11, crumble },
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
"Server keep-alive timeout is %u. Sticking with %u.",
keep_alive_timeout, csp->server_connection.keep_alive_timeout);
}
+ csp->flags |= CSP_FLAG_SERVER_KEEP_ALIVE_TIMEOUT_SET;
}
return JB_ERR_OK;
}
+/*********************************************************************
+ *
+ * Function : server_proxy_connection
+ *
+ * Description : Figures out whether or not we should add a
+ * Proxy-Connection header.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : header = On input, pointer to header to modify.
+ * On output, pointer to the modified header, or NULL
+ * to remove the header. This function frees the
+ * original string if necessary.
+ *
+ * Returns : JB_ERR_OK.
+ *
+ *********************************************************************/
+static jb_err server_proxy_connection(struct client_state *csp, char **header)
+{
+ csp->flags |= CSP_FLAG_SERVER_PROXY_CONNECTION_HEADER_SET;
+ return JB_ERR_OK;
+}
+
+
/*********************************************************************
*
* Function : client_keep_alive
unsigned int keep_alive_timeout;
const char *timeout_position = strstr(*header, ": ");
+ if (!(csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE))
+ {
+ log_error(LOG_LEVEL_HEADER,
+ "keep-alive support is disabled. Crunching: %s.", *header);
+ freez(*header);
+ return JB_ERR_OK;
+ }
+
if ((NULL == timeout_position)
|| (1 != sscanf(timeout_position, ": %u", &keep_alive_timeout)))
{
*********************************************************************/
static jb_err client_connection(struct client_state *csp, char **header)
{
- const char *wanted_header = get_appropiate_connection_header(csp);
+ static const char connection_close[] = "Connection: close";
- if (strcmpic(*header, wanted_header))
+ 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))
+ {
+ if (!strcmpic(csp->http->ver, "HTTP/1.1"))
+ {
+ log_error(LOG_LEVEL_HEADER,
+ "Removing \'%s\' to imply keep-alive.", *header);
+ freez(*header);
+ }
+ else
+ {
+ char *old_header = *header;
+
+ *header = strdup("Connection: keep-alive");
+ if (header == NULL)
+ {
+ return JB_ERR_MEMORY;
+ }
+ log_error(LOG_LEVEL_HEADER,
+ "Replaced: \'%s\' with \'%s\'", old_header, *header);
+ freez(old_header);
+ }
+ }
+ else
{
log_error(LOG_LEVEL_HEADER,
"Keeping the client header '%s' around. "
"The connection will not be kept alive.",
*header);
+ csp->flags &= ~CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
}
- else
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
- {
- char *old_header = *header;
-
- *header = strdup(wanted_header);
- if (header == NULL)
- {
- return JB_ERR_MEMORY;
- }
- log_error(LOG_LEVEL_HEADER,
- "Replaced: \'%s\' with \'%s\'", old_header, *header);
- freez(old_header);
- }
}
-#ifdef FEATURE_CONNECTION_KEEP_ALIVE
else
{
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
log_error(LOG_LEVEL_HEADER,
"Keeping the client header '%s' around. "
"The server connection will be kept alive if possible.",
*header);
csp->flags |= CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE;
- }
+#else
+ char *old_header = *header;
+
+ *header = strdup(connection_close);
+ if (header == NULL)
+ {
+ return JB_ERR_MEMORY;
+ }
+ log_error(LOG_LEVEL_HEADER,
+ "Replaced: \'%s\' with \'%s\'", old_header, *header);
+ freez(old_header);
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+ }
/* Signal client_connection_adder() to return early. */
csp->flags |= CSP_FLAG_CLIENT_CONNECTION_HEADER_SET;
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
&& !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
#endif
- && (csp->http->status == 200)
)
{
- /*
- * XXX: not doing this for status codes other than 200 works
- * around problems with broken servers that will keep the
- * connection open, but terminate the connection when the
- * next request arrives. Once we are able to figure out which
- * requests are safe to send again, this will probably no
- * longer be necessary.
- */
log_error(LOG_LEVEL_HEADER, "A HTTP/1.1 response "
"without Connection header implies keep-alive.");
csp->flags |= CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE;
jb_err err = JB_ERR_OK;
if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
- && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
+ && !(csp->flags & CSP_FLAG_SERVER_PROXY_CONNECTION_HEADER_SET))
{
log_error(LOG_LEVEL_HEADER, "Adding: %s", proxy_connection_header);
err = enlist(csp->headers, proxy_connection_header);