+ struct http_response *rsp = NULL;
+
+ if (
+ /* We may not forward the request by rfc2616 sect 14.31 */
+ (NULL != (rsp = direct_response(csp)))
+
+ /* or we are enabled and... */
+ || (IS_ENABLED_AND (
+
+ /* ..the request was blocked */
+ ( NULL != (rsp = block_url(csp)))
+
+ /* ..or untrusted */
+#ifdef FEATURE_TRUST
+ || ( NULL != (rsp = trust_url(csp)))
+#endif /* def FEATURE_TRUST */
+
+ /* ..or a redirect kicked in */
+ || ( NULL != (rsp = redirect_url(csp)))
+ ))
+ /*
+ * .. or a CGI call was detected and answered.
+ *
+ * This check comes last to give the user the power
+ * to deny acces to some (or all) of the cgi pages.
+ */
+ || (NULL != (rsp = dispatch_cgi(csp)))
+
+ )
+ {
+ /* Deliver, log and free the interception response. */
+ send_crunch_response(csp, rsp);
+#ifdef FEATURE_STATISTICS
+ csp->flags |= CSP_FLAG_REJECTED;
+#endif /* def FEATURE_STATISTICS */
+
+ return TRUE;
+ }
+
+ return FALSE;
+}
+
+
+/*********************************************************************
+ *
+ * Function : build_request_line
+ *
+ * Description : Builds the HTTP request line.
+ *
+ * If a HTTP forwarder is used it expects the whole URL,
+ * web servers only get the path.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ * 2 : fwd = The forwarding spec used for the request
+ *
+ * Returns : Nothing. Terminates in case of memory problems.
+ *
+ *********************************************************************/
+void build_request_line(struct client_state *csp, const struct forward_spec *fwd)
+{
+ struct http_request *http = csp->http;
+
+ assert(http->ssl == 0);
+
+ /*
+ * Downgrade http version from 1.1 to 1.0
+ * if +downgrade action applies.
+ */
+ if ( (csp->action->flags & ACTION_DOWNGRADE)
+ && (!strcmpic(http->ver, "HTTP/1.1")))
+ {
+ freez(http->ver);
+ http->ver = strdup("HTTP/1.0");
+
+ if (http->ver == NULL)
+ {
+ log_error(LOG_LEVEL_FATAL, "Out of memory downgrading HTTP version");
+ }
+ }
+
+ /*
+ * Rebuild the request line.
+ * XXX: If a http forwarder is used and the HTTP version
+ * wasn't downgraded, we don't have to rebuild anything.
+ */
+ freez(http->cmd);
+
+ http->cmd = strdup(http->gpc);
+ string_append(&http->cmd, " ");
+
+ if (fwd->forward_host)
+ {
+ string_append(&http->cmd, http->url);
+ }
+ else
+ {
+ string_append(&http->cmd, http->path);
+ }
+ string_append(&http->cmd, " ");
+ string_append(&http->cmd, http->ver);
+
+ if (http->cmd == NULL)
+ {
+ log_error(LOG_LEVEL_FATAL, "Out of memory writing HTTP command");
+ }
+ log_error(LOG_LEVEL_HEADER, "New HTTP Request-Line: %s", http->cmd);
+}
+
+
+/*********************************************************************
+ *
+ * Function : chat
+ *
+ * Description : Once a connection to the client has been accepted,
+ * this function is called (via serve()) to handle the
+ * main business of the communication. When this
+ * function returns, the caller must close the client
+ * socket handle.
+ *
+ * FIXME: chat is nearly thousand lines long.
+ * Ridiculous.
+ *
+ * Parameters :
+ * 1 : csp = Current client state (buffers, headers, etc...)
+ *
+ * Returns : Nothing.
+ *
+ *********************************************************************/
+static void chat(struct client_state *csp)
+{