Here is a patch that replaces persistent_client_posts all together.
Instead it uses a (fast) ACL to determine if this extra CRLF should be
appended to the body of the request or not.
#
-# $Id: cf.data.pre,v 1.132 1999/01/21 23:15:36 wessels Exp $
+# $Id: cf.data.pre,v 1.133 1999/01/21 23:58:41 wessels Exp $
#
#
# SQUID Internet Object Cache http://squid.nlanr.net/Squid/
uri_whitespace deny
DOC_END
-NAME: persistent_client_posts
-TYPE: onoff
-LOC: Config.onoff.persistent_client_posts
-DEFAULT: on
+NAME: broken_posts
+TYPE: acl_access
+DEFAULT: none
+LOC: Config.accessList.brokenPosts
DOC_START
- Turn this 'off' to disable persistent connections for POST
- requests. When you disable this, Squid reads all bytes
- from the client request and sends them to the server. This
- makes Squid work with broken HTTP servers which expect the
- additional CRLF pair from broken web clients.
-persistent_client_posts on
+ A list of ACL elements which, if matched, causes Squid to send
+ a extra CRLF pair after the body of a PUT/POST request.
+
+ Some HTTP servers has broken implementations of PUT/POST,
+ and rely on a extra CRLF pair sent by some WWW clients.
+
+ Quote from RFC 2068 section 4.1 on this matter:
+
+ Note: certain buggy HTTP/1.0 client implementations generate an
+ extra CRLF's after a POST request. To restate what is explicitly
+ forbidden by the BNF, an HTTP/1.1 client must not preface or follow
+ a request with an extra CRLF.
+
+acl buggy_server url_regex ^http://....
+broken_posts allow buggy_server
DOC_END
NAME: mcast_miss_addr
/*
- * $Id: client_side.cc,v 1.433 1999/01/19 20:26:35 wessels Exp $
+ * $Id: client_side.cc,v 1.434 1999/01/21 23:58:43 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
RequestMethodStr[request->method]);
if (httpMsgIsPersistent(request->http_ver, req_hdr))
request->flags.proxy_keepalive = 1;
- if (request->method == METHOD_POST || request->method == METHOD_PUT)
- if (!Config.onoff.persistent_client_posts)
- request->flags.proxy_keepalive = 0;
}
static int
*/
if (request->method != METHOD_GET) {
int cont_len = httpHeaderGetInt(&request->header, HDR_CONTENT_LENGTH);
- int copy_len = conn->in.offset;
- if (cont_len < copy_len && request->flags.proxy_keepalive)
- copy_len = cont_len;
+ int copy_len = XMIN(conn->in.offset, cont_len);
if (copy_len > 0) {
assert(conn->in.offset >= copy_len);
request->body_sz = copy_len;
/*
- * $Id: http.cc,v 1.344 1999/01/20 19:27:10 wessels Exp $
+ * $Id: http.cc,v 1.345 1999/01/21 23:58:45 wessels Exp $
*
* DEBUG: section 11 Hypertext Transfer Protocol (HTTP)
* AUTHOR: Harvest Derived
static CNCB httpConnectDone;
static CWCB httpSendComplete;
static CWCB httpSendRequestEntry;
+static CWCB httpSendRequestEntryDone;
static PF httpReadReply;
static PF httpSendRequest;
comm_close(fd);
return;
}
- pumpStart(fd, httpState->fwd, httpSendComplete, httpState);
+ pumpStart(fd, httpState->fwd, httpSendRequestEntryDone, httpState);
+}
+
+static void
+httpSendRequestEntryDone(int fd, char *bufnotused, size_t size, int errflag, void *data)
+{
+ HttpStateData *httpState = data;
+ StoreEntry *entry = httpState->entry;
+ ErrorState *err;
+ aclCheck_t ch;
+ debug(11, 5) ("httpSendRequestEntryDone: FD %d: size %d: errflag %d.\n",
+ fd, size, errflag);
+ if (size > 0) {
+ fd_bytes(fd, size, FD_WRITE);
+ kb_incr(&Counter.server.all.kbytes_out, size);
+ kb_incr(&Counter.server.http.kbytes_out, size);
+ }
+ if (errflag == COMM_ERR_CLOSING)
+ return;
+ if (errflag) {
+ err = errorCon(ERR_WRITE_ERROR, HTTP_INTERNAL_SERVER_ERROR);
+ err->xerrno = errno;
+ err->request = requestLink(httpState->orig_request);
+ errorAppendEntry(entry, err);
+ comm_close(fd);
+ return;
+ }
+ memset(&ch, '\0', sizeof(ch));
+ ch.request = httpState->request;
+ if (!Config.accessList.brokenPosts) {
+ debug(11, 5) ("httpSendRequestEntryDone: No brokenPosts list\n");
+ httpSendComplete(fd, NULL, 0, 0, data);
+ } else if (!aclCheckFast(Config.accessList.brokenPosts, &ch)) {
+ debug(11, 5) ("httpSendRequestEntryDone: didn't match brokenPosts\n");
+ httpSendComplete(fd, NULL, 0, 0, data);
+ } else {
+ debug(11, 2) ("httpSendRequestEntryDone: matched brokenPosts\n");
+ comm_write(fd, "\r\n", 2, httpSendComplete, data, NULL);
+ }
}
/*
- * $Id: structs.h,v 1.266 1999/01/21 23:15:41 wessels Exp $
+ * $Id: structs.h,v 1.267 1999/01/21 23:58:47 wessels Exp $
*
*
* SQUID Internet Object Cache http://squid.nlanr.net/Squid/
#if SQUID_SNMP
acl_access *snmp;
#endif
+ acl_access *brokenPosts;
} accessList;
acl_deny_info_list *denyInfoList;
char *proxyAuthRealm;