#
-# $Id: cf.data.pre,v 1.152 1999/05/04 21:58:18 wessels Exp $
+# $Id: cf.data.pre,v 1.153 1999/05/10 19:33:20 wessels Exp $
#
#
# SQUID Internet Object Cache http://squid.nlanr.net/Squid/
DOC_END
-NAME: request_size
+NAME: request_header_max_size
+COMMENT: (KB)
+TYPE: b_size_t
+DEFAULT: 10 KB
+LOC: Config.maxRequestHeaderSize
+DOC_START
+ This specifies the maximum size for HTTP headers in a request.
+ Request headers are usually relatively small (about 512 bytes).
+ Placing a limit on the request header size will catch certain
+ bugs (for example with persistent connections) and possibly
+ buffer-overflow or denial-of-service attacks.
+request_header_max_size 10 KB
+DOC_END
+
+NAME: request_body_max_size
COMMENT: (KB)
TYPE: b_size_t
DEFAULT: 100 KB
-LOC: Config.maxRequestSize
+LOC: Config.maxRequestBodySize
DOC_START
- Maximum allowed request size in kilobytes. If people are using
- POST to upload files, then set this to the largest acceptable
- filesize plus a few extra kbytes.
+ This specifies the maximum size for an HTTP request body.
+ In other words, the maximum size of a PUT/POST request.
+ A user who attempts to send a request with a body larger
+ than this limit receives an "Invalid Request" error message.
+ If you set this parameter to a zero, there will be no limit
+ imposed.
+request_body_max_size 100 KB
+DOC_END
-request_size 100 KB
+NAME: reply_body_max_size
+COMMENT: (KB)
+TYPE: b_size_t
+DEFAULT: 0
+LOC: Config.maxReplyBodySize
+DOC_START
+ This specifies the maximum size for an HTTP reply body.
+ This can be used to restrict users from downloading very
+ large files. If the reply headers include a content-length
+ value, then we can recognize large reply bodies early and
+ avoid downloading any of it. If not, we will download as
+ much data up to this limit and then ungraciously terminate
+ the transfer. If you set this parameter to zero, there
+ will be no limit imposed.
+reply_body_max_size 0
DOC_END
/*
- * $Id: client_side.cc,v 1.451 1999/05/04 21:08:40 wessels Exp $
+ * $Id: client_side.cc,v 1.452 1999/05/10 19:33:22 wessels Exp $
*
* DEBUG: section 33 Client-side Routines
* AUTHOR: Duane Wessels
static int clientCheckContentLength(request_t * r);
static int httpAcceptDefer(void);
static log_type clientProcessRequest2(clientHttpRequest * http);
+static int clientReplyBodyTooLarge(int clen);
static int
checkAccelOnly(clientHttpRequest * http)
return i->debt_size > 0;
}
+static int
+clientReplyBodyTooLarge(int clen)
+{
+ if (0 == Config.maxReplyBodySize)
+ return 0; /* disabled */
+ if (clen < 0)
+ return 0; /* unknown */
+ if (clen > Config.maxReplyBodySize)
+ return 1; /* too large */
+ return 0;
+}
+
/*
* accepts chunk of a http message in buf, parses prefix, filters headers and
* such, writes processed message to the client's socket
}
}
rep = clientBuildReply(http, buf, size);
- if (rep) {
+ if (clientReplyBodyTooLarge(rep->content_length)) {
+ ErrorState *err = errorCon(ERR_TOO_BIG, HTTP_FORBIDDEN);
+ err->request = requestLink(http->request);
+ storeUnregister(http->entry, http);
+ storeUnlockObject(http->entry);
+ http->entry = clientCreateStoreEntry(http, http->request->method,
+ null_request_flags);
+ errorAppendEntry(http->entry, err);
+ return;
+ } else if (rep) {
body_size = size - rep->hdr_sz;
assert(body_size >= 0);
body_buf = buf + rep->hdr_sz;
} else {
comm_close(fd);
}
+ } else if (clientReplyBodyTooLarge((int) http->out.offset)) {
+ comm_close(fd);
} else {
/* More data will be coming from primary server; register with
* storage manager. */
break;
}
if (0 == clientCheckContentLength(request)) {
- err = errorCon(ERR_INVALID_REQ, HTTP_LENGTH_REQUIRED);
+ err = errorCon(ERR_TOO_BIG, HTTP_LENGTH_REQUIRED);
err->src_addr = conn->peer.sin_addr;
err->request = requestLink(request);
http->al.http.code = err->http_status;
*/
if (request->body_sz < cont_len)
commSetSelect(fd, COMM_SELECT_READ, NULL, NULL, 0);
+ if (cont_len > Config.maxRequestBodySize) {
+ err = errorCon(ERR_INVALID_REQ,
+ HTTP_REQUEST_ENTITY_TOO_LARGE);
+ err->request = requestLink(request);
+ http->entry = clientCreateStoreEntry(http,
+ METHOD_NONE, null_request_flags);
+ errorAppendEntry(http->entry, err);
+ break;
+ }
}
clientAccessCheck(http);
continue; /* while offset > 0 */
*/
k = conn->in.size - 1 - conn->in.offset;
if (k == 0) {
- if (conn->in.offset >= Config.maxRequestSize) {
+ if (conn->in.offset >= Config.maxRequestHeaderSize) {
/* The request is too large to handle */
debug(33, 0) ("Request won't fit in buffer.\n");
- debug(33, 0) ("Config 'request_size'= %d bytes.\n",
- Config.maxRequestSize);
+ debug(33, 0) ("Config 'request_header_max_size'= %d bytes.\n",
+ Config.maxRequestHeaderSize);
debug(33, 0) ("This request = %d bytes.\n",
(int) conn->in.offset);
err = errorCon(ERR_INVALID_REQ, HTTP_REQUEST_ENTITY_TOO_LARGE);