for both requests and responses.
/*
- * $Id: HttpHeader.cc,v 1.98 2004/09/26 16:38:01 hno Exp $
+ * $Id: HttpHeader.cc,v 1.99 2004/11/16 23:11:46 wessels Exp $
*
* DEBUG: section 55 HTTP Header
* AUTHOR: Alex Rousskov
e = httpHeaderEntryParseCreate(field_start, field_end);
- if (e != NULL)
- httpHeaderAddEntry(hdr, e);
- else
- debug(55, 2) ("warning: ignoring unparseable http header field near '%s'\n",
+ if (NULL == e) {
+ debug(55, 1) ("WARNING: ignoring unparseable HTTP header field near '%s'\n",
getStringPrefix(field_start, field_end));
+ } else if (e->id == HDR_CONTENT_LENGTH && httpHeaderHas(hdr, HDR_CONTENT_LENGTH)) {
+ debug(55, 1) ("WARNING: found double content-length header\n");
+ httpHeaderEntryDestroy(e);
+ return httpHeaderReset(hdr);
+ } else if (e->id == HDR_OTHER && stringHasWhitespace(e->name.buf())) {
+ debug(55, 1) ("WARNING: found whitespace in HTTP header {%s}\n", e->name.buf());
+ httpHeaderEntryDestroy(e);
+ return httpHeaderReset(hdr);
+ } else {
+ httpHeaderAddEntry(hdr, e);
+ }
field_start = field_end;
/* skip CRLF */
+
if (*field_start == '\r')
field_start++;
/*
- * $Id: HttpVersion.h,v 1.1 2003/09/01 03:49:37 robertc Exp $
+ * $Id: HttpVersion.h,v 1.2 2004/11/16 23:11:46 wessels Exp $
*
*
* SQUID Web Proxy Cache http://www.squid-cache.org/
unsigned int major;
unsigned int minor;
+
+ bool operator==(const HttpVersion& that) const
+ {
+ if (this->major != that.major)
+ return false;
+
+ if (this->minor != that.minor)
+ return false;
+
+ return true;
+ }
+
};
#endif /* SQUID_HTTPVERSION_H */
/*
- * $Id: client_side.cc,v 1.673 2004/10/18 12:16:22 hno Exp $
+ * $Id: client_side.cc,v 1.674 2004/11/16 23:11:46 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
debug(33, 3) ("parseHttpRequest: end = {%s}\n", end);
+ if (strstr(req_hdr, "\r\r\n")) {
+ debug(33, 1) ("WARNING: suspicious HTTP request contains double CR\n");
+ xfree(inbuf);
+ return parseHttpRequestAbort(conn, "error:double-CR");
+ }
+
prefix_sz = end - inbuf;
debug(33, 3) ("parseHttpRequest: prefix_sz = %d, req_line_sz = %d\n",
/* compile headers */
/* we should skip request line! */
- if (!httpRequestParseHeader(request, prefix + req_line_sz))
- if (http->http_ver.major >= 1)
- debug(33, 1) ("Failed to parse request headers: %s\n%s\n",
- http->uri, prefix);
-
- /* continue anyway? */
+ if (!httpRequestParseHeader(request, prefix + req_line_sz)) {
+ clientStreamNode *node = context->getClientReplyContext();
+ debug(33, 5) ("Failed to parse request headers:\n%s\n", prefix);
+ clientReplyContext *repContext = dynamic_cast<clientReplyContext *>(node->data.getRaw());
+ assert (repContext);
+ repContext->setReplyToError(
+ ERR_INVALID_URL, HTTP_BAD_REQUEST, method, http->uri,
+ &conn->peer.sin_addr, NULL, NULL, NULL);
+ assert(context->http->out.offset == 0);
+ context->pullData();
+ conn->flags.readMoreRequests = 0;
+ return;
+ }
request->flags.accelerated = http->flags.accel;
/*
- * $Id: http.cc,v 1.434 2004/11/06 22:20:47 hno Exp $
+ * $Id: http.cc,v 1.435 2004/11/16 23:11:46 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
if (hdr_len > 4 && strncmp(reply_hdr, "HTTP/", 5)) {
debug(11, 3) ("httpProcessReplyHeader: Non-HTTP-compliant header: '%s'\n", reply_hdr);
reply_hdr_state += 2;
+ reply->sline.version = HttpVersion(1, 0);
reply->sline.status = HTTP_INVALID_HEADER;
storeEntryReplaceObject (entry, reply);
/* Parse headers into reply structure */
/* what happens if we fail to parse here? */
httpReplyParse(reply, reply_hdr, hdr_len);
+
+ if (reply->sline.status >= HTTP_INVALID_HEADER) {
+ debug(11, 3) ("httpProcessReplyHeader: Non-HTTP-compliant header: '%s'\n", reply_hdr);
+ reply->sline.version = HttpVersion(1, 0);
+ reply->sline.status = HTTP_INVALID_HEADER;
+ storeEntryReplaceObject (entry, reply);
+
+ if (eof == 1) {
+ fwdComplete(fwd);
+ comm_close(fd);
+ }
+
+ return;
+ }
+
processSurrogateControl (reply);
/* TODO: we need our own reply * in the httpState, as we probably don't want to replace
* the storeEntry with interim headers
*/
/* doesn't return */
processReplyHeader(buf, len);
- else {
+ else if (entry->getReply()->sline.status == HTTP_INVALID_HEADER && HttpVersion(0,9) != entry->getReply()->sline.version) {
+ ErrorState *err;
+ err = errorCon(ERR_INVALID_REQ, HTTP_BAD_GATEWAY);
+ err->request = requestLink((HttpRequest *) request);
+ fwdFail(fwd, err);
+ do_next_read = 0;
+ } else {
fwdComplete(fwd);
do_next_read = 0;
comm_close(fd);
if (reply_hdr_state == 2) {
http_status s = entry->getReply()->sline.status;
+ HttpVersion httpver = entry->getReply()->sline.version;
+
+ if (s == HTTP_INVALID_HEADER && httpver != HttpVersion(0,9)) {
+ ErrorState *err;
+ storeEntryReset(entry);
+ err = errorCon(ERR_INVALID_REQ, HTTP_BAD_GATEWAY);
+ err->request = requestLink((HttpRequest *) request);
+ fwdFail(fwd, err);
+ comm_close(fd);
+ return;
+ }
+
#if WIP_FWD_LOG
fwdStatus(fwd, s);
+
#endif
/*
* If its not a reply that we will re-forward, then