-const char jcc_rcs[] = "$Id: jcc.c,v 1.171 2008/03/27 18:27:25 fabiankeil Exp $";
+const char jcc_rcs[] = "$Id: jcc.c,v 1.177 2008/05/10 11:51:12 fabiankeil Exp $";
/*********************************************************************
*
* File : $Source: /cvsroot/ijbswa/current/jcc.c,v $
*
* Revisions :
* $Log: jcc.c,v $
+ * Revision 1.177 2008/05/10 11:51:12 fabiankeil
+ * Make the "read the rest of the headers" loop a bit more readable.
+ *
+ * Revision 1.176 2008/05/10 11:37:57 fabiankeil
+ * - Instead of logging when the IIS5 hack is enabled, log when it fails.
+ * - Remove useless comment.
+ *
+ * Revision 1.175 2008/05/09 18:53:59 fabiankeil
+ * Fix comment grammar.
+ *
+ * Revision 1.174 2008/05/07 18:05:53 fabiankeil
+ * Remove the pointless buffer in client_protocol_is_unsupported().
+ *
+ * Revision 1.173 2008/05/06 15:09:00 fabiankeil
+ * Least-effort fix for bug #1821930 (reported by Lee):
+ * If the response doesn't look like HTTP,
+ * tell the client and log the problem.
+ *
+ * Revision 1.172 2008/04/16 16:38:21 fabiankeil
+ * Don't pass the whole csp structure to flush_socket()
+ * when it only needs a file descriptor and a buffer.
+ *
* Revision 1.171 2008/03/27 18:27:25 fabiankeil
* Remove kill-popups action.
*
"Empty server or forwarder response.\r\n"
"The connection has been closed but Privoxy didn't receive any data.\r\n";
+/* XXX: should be a template */
+static const char INVALID_SERVER_HEADERS_RESPONSE[] =
+ "HTTP/1.0 502 Server or forwarder response invalid\r\n"
+ "Proxy-Agent: Privoxy " VERSION "\r\n"
+ "Content-Type: text/plain\r\n"
+ "Connection: close\r\n\r\n"
+ "Bad response. The server or forwarder response doesn't look like HTTP.\r\n";
+
#if 0
/* XXX: should be a template */
static const char NULL_BYTE_RESPONSE[] =
*********************************************************************/
static int client_protocol_is_unsupported(const struct client_state *csp, char *req)
{
- char buf[BUFFER_SIZE];
-
/*
* If it's a FTP or gopher request, we don't support it.
*
*/
if (!strncmpic(req, "GET ftp://", 10) || !strncmpic(req, "GET gopher://", 13))
{
+ const char *response = NULL;
+ const char *protocol = NULL;
+
if (!strncmpic(req, "GET ftp://", 10))
{
- strlcpy(buf, FTP_RESPONSE, sizeof(buf));
- log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as FTP proxy: %s",
- csp->ip_addr_str, req);
+ response = FTP_RESPONSE;
+ protocol = "FTP";
}
else
{
- strlcpy(buf, GOPHER_RESPONSE, sizeof(buf));
- log_error(LOG_LEVEL_ERROR, "%s tried to use Privoxy as gopher proxy: %s",
- csp->ip_addr_str, req);
+ response = GOPHER_RESPONSE;
+ protocol = "GOPHER";
}
- log_error(LOG_LEVEL_CLF, "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
+ log_error(LOG_LEVEL_ERROR,
+ "%s tried to use Privoxy as %s proxy: %s",
+ csp->ip_addr_str, protocol, req);
+ log_error(LOG_LEVEL_CLF,
+ "%s - - [%T] \"%s\" 400 0", csp->ip_addr_str, req);
freez(req);
- write_socket(csp->cfd, buf, strlen(buf));
+ write_socket(csp->cfd, response, strlen(response));
return TRUE;
}
int continue_hack_in_da_house = 0;
char * header;
- while (((header = get_header(csp)) != NULL) || continue_hack_in_da_house)
+ while (((header = get_header(csp->iob)) != NULL) || continue_hack_in_da_house)
{
if (header == NULL)
{
return JB_ERR_PARSE;
}
- /* Enlist header */
if (JB_ERR_MEMORY == enlist(csp->headers, header))
{
/*
return;
}
- req = get_header(csp);
+ req = get_header(csp->iob);
} while ((NULL != req) && ('\0' == *req));
init_list(headers);
for (;;)
{
- if ( ( ( p = get_header(csp) ) != NULL) && ( *p == '\0' ) )
+ p = get_header(csp->iob);
+
+ if (p == NULL)
{
+ /* There are no additional headers to read. */
+ break;
+ }
+
+ if (*p == '\0')
+ {
+ /*
+ * We didn't receive a complete header
+ * line yet, get the rest of it.
+ */
len = read_socket(csp->cfd, buf, sizeof(buf) - 1);
if (len <= 0)
{
return;
}
- /*
- * 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 there is no memory left for buffering the
+ * request, there is nothing we can do but hang up
+ */
destroy_list(headers);
return;
}
- continue;
}
-
- if (p == NULL) break;
-
- enlist(headers, p);
- freez(p);
-
+ else
+ {
+ /*
+ * We were able to read a complete
+ * header and can finaly enlist it.
+ */
+ enlist(headers, p);
+ freez(p);
+ }
}
if (http->host == NULL)
* This is NOT the body, so
* Let's pretend the server just sent us a blank line.
*/
- log_error(LOG_LEVEL_INFO,
- "Malformerd HTTP headers detected and MS IIS5 hack enabled. "
- "Expect an invalid response or even no response at all.");
snprintf(buf, sizeof(buf), "\r\n");
len = (int)strlen(buf);
* and there isn't anything
* we can do about it.
*/
+ log_error(LOG_LEVEL_INFO,
+ "MS IIS5 hack didn't produce valid headers.");
break;
}
else
return;
}
+ assert(csp->headers->first->str);
+ assert(!http->ssl);
+ if (strncmpic(csp->headers->first->str, "HTTP", 4))
+ {
+ /*
+ * It doesn't look like a HTTP response:
+ * tell the client and log the problem.
+ */
+ if (strlen(csp->headers->first->str) > 30)
+ {
+ csp->headers->first->str[30] = '\0';
+ }
+ log_error(LOG_LEVEL_ERROR,
+ "Invalid server or forwarder response. Starts with: %s",
+ csp->headers->first->str);
+ log_error(LOG_LEVEL_CLF,
+ "%s - - [%T] \"%s\" 502 0", csp->ip_addr_str, http->cmd);
+ write_socket(csp->cfd, INVALID_SERVER_HEADERS_RESPONSE,
+ strlen(INVALID_SERVER_HEADERS_RESPONSE));
+ free_http_request(http);
+ return;
+ }
+
/* we have now received the entire header.
* filter it and send the result to the client
*/
*/
if (ms_iis5_hack)
{
+ log_error(LOG_LEVEL_INFO,
+ "Closed server connection detected with MS IIS5 hack enabled.");
break;
}
}
* Parse the command line arguments
*
* XXX: simply printing usage information in case of
- * invalid arguments isn't particular user friendly.
+ * invalid arguments isn't particularly user friendly.
*/
while (++argc_pos < argc)
{