-const char jcc_rcs[] = "$Id: jcc.c,v 1.257 2009/06/12 13:39:02 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.258 2009/06/27 11:22:52 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/jcc.c,v $
{
log_error(LOG_LEVEL_CONNECT, "Unsetting keep-alive flag.");
csp->flags &= ~CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE;
+ csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
}
}
return JB_ERR_PARSE;
}
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE))
+ {
+ if (csp->iob->cur[0] != '\0')
+ {
+ csp->flags |= CSP_FLAG_SERVER_SOCKET_TAINTED;
+ if (!strcmpic(csp->http->gpc, "POST"))
+ {
+ /* XXX: this is an incomplete hack */
+ csp->flags &= ~CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
+ log_error(LOG_LEVEL_CONNECT,
+ "POST request detected. The connection will not be kept alive.");
+ }
+ else
+ {
+ /* XXX: and so is this */
+ csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
+ log_error(LOG_LEVEL_CONNECT,
+ "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;
+ }
+ }
+ else
+ {
+ csp->flags |= CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ;
+ log_error(LOG_LEVEL_CONNECT, "Complete client request received.");
+ }
+ }
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+
return JB_ERR_OK;
}
#else
FD_ZERO(&rfds);
#endif
- FD_SET(csp->cfd, &rfds);
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ if ((csp->flags & CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ))
+ {
+ maxfd = csp->sfd;
+ }
+ else
+#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+ {
+ FD_SET(csp->cfd, &rfds);
+ }
+
FD_SET(csp->sfd, &rfds);
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
continue_chatting = (csp->config->feature_flags
& RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
&& (csp->flags & CSP_FLAG_SERVER_CONNECTION_KEEP_ALIVE)
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
&& (csp->cfd != JB_INVALID_SOCKET)
&& (csp->sfd != JB_INVALID_SOCKET)
&& socket_is_still_usable(csp->sfd);
-const char parsers_rcs[] = "$Id: parsers.c,v 1.184 2009/06/18 17:10:16 fabiankeil Exp $";
+const char parsers_rcs[] = "$Id: parsers.c,v 1.185 2009/06/27 11:25:33 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/parsers.c,v $
*********************************************************************/
static jb_err server_connection(struct client_state *csp, char **header)
{
- if (!strcmpic(*header, "Connection: keep-alive"))
+ if (!strcmpic(*header, "Connection: keep-alive")
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
+#endif
+ )
{
#ifdef FEATURE_CONNECTION_KEEP_ALIVE
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE))
if ((csp->config->feature_flags &
RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
&& (NULL != response_status_line)
- && !strncmpic(response_status_line, "HTTP/1.1", 8))
+ && !strncmpic(response_status_line, "HTTP/1.1", 8)
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
+#endif
+ )
{
log_error(LOG_LEVEL_HEADER, "A HTTP/1.1 response "
"without Connection header implies keep-alive.");
static const char proxy_connection_header[] = "Proxy-Connection: keep-alive";
jb_err err = JB_ERR_OK;
- if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE))
+ if ((csp->flags & CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE)
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED))
{
log_error(LOG_LEVEL_HEADER, "Adding: %s", proxy_connection_header);
err = enlist(csp->headers, proxy_connection_header);
static const char connection_close[] = "Connection: close";
if ((csp->config->feature_flags & RUNTIME_FEATURE_CONNECTION_KEEP_ALIVE)
+#ifdef FEATURE_CONNECTION_KEEP_ALIVE
+ && !(csp->flags & CSP_FLAG_SERVER_SOCKET_TAINTED)
+#endif
&& (csp->http->ssl == 0))
{
return connection_keep_alive;
#ifndef PROJECT_H_INCLUDED
#define PROJECT_H_INCLUDED
/** Version string. */
-#define PROJECT_H_VERSION "$Id: project.h,v 1.141 2009/06/11 11:46:22 fabiankeil Exp $"
+#define PROJECT_H_VERSION "$Id: project.h,v 1.142 2009/06/11 11:49:11 fabiankeil Exp $"
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/project.h,v $
* the connection alive.
*/
#define CSP_FLAG_CLIENT_CONNECTION_KEEP_ALIVE 0x00008000U
+
+/**
+ * Flag for csp->flags: Set if we think we got the whole
+ * client request and shouldn't read any additional data
+ * coming from the client until the current request has
+ * been dealt with.
+ */
+#define CSP_FLAG_CLIENT_REQUEST_COMPLETELY_READ 0x00010000U
+
#endif /* def FEATURE_CONNECTION_KEEP_ALIVE */
+/**
+ * Flag for csp->flags: Set if we think we can't reuse
+ * the server socket.
+ */
+#define CSP_FLAG_SERVER_SOCKET_TAINTED 0x00020000U
+
/*
* Flags for use in return codes of child processes
*/