direct client address in delay pools.
</verb>
+ <tag>client_request_buffer_max_size</tag>
+ <p>New directive added with squid-3.1.10 to set limits on the amount of buffer space allocated
+ for receiving upload and request data from clients.
+
<tag>dns_v4_fallback</tag>
<p>New option to prevent Squid from always looking up IPv4 regardless of whether IPv6 addresses are found.
Squid will follow a policy of prefering IPv6 links, keeping the IPv4 only as a safety net behind IPv6.
}
#endif
+
+ // prevent infinite fetch loops in the request parser
+ // due to buffer full but not enough data recived to finish parse
+ if (Config.maxRequestBufferSize <= Config.maxRequestHeaderSize) {
+ fatalf("Client request buffer of %u bytes cannot hold a request with %u bytes of headers." \
+ " Change client_request_buffer_max or request_header_max_size limits.",
+ (uint32_t)Config.maxRequestBufferSize, (uint32_t)Config.maxRequestHeaderSize);
+ }
}
/* Parse a time specification from the config file. Store the
be no limit imposed.
DOC_END
+NAME: client_request_buffer_max_size
+COMMENT: (bytes)
+TYPE: b_size_t
+DEFAULT: 512 KB
+LOC: Config.maxRequestBufferSize
+DOC_START
+ This specifies the maximum buffer size of a client request.
+ It prevents squid eating too much memory when somebody uploads
+ a large file.
+DOC_END
+
NAME: chunked_request_body_max_size
COMMENT: (bytes)
TYPE: b_int64_t
debugs(33, 4, "clientReadSomeData: FD " << fd << ": reading request...");
- makeSpaceAvailable();
+ if (!maybeMakeSpaceAvailable())
+ return;
typedef CommCbMemFunT<ConnStateData, CommIoCbParams> Dialer;
reader = JobCallback(33, 5,
return result;
}
-void
-ConnStateData::makeSpaceAvailable()
+bool
+ConnStateData::maybeMakeSpaceAvailable()
{
if (getAvailableBufferLength() < 2) {
- in.buf = (char *)memReallocBuf(in.buf, in.allocatedSize * 2, &in.allocatedSize);
+ size_t newSize;
+ if (in.allocatedSize >= Config.maxRequestBufferSize) {
+ debugs(33, 4, "request buffer full: client_request_buffer_max_size=" << Config.maxRequestBufferSize);
+ return false;
+ }
+ if ((newSize=in.allocatedSize * 2) > Config.maxRequestBufferSize) {
+ newSize=Config.maxRequestBufferSize;
+ }
+ in.buf = (char *)memReallocBuf(in.buf, newSize, &in.allocatedSize);
debugs(33, 2, "growing request buffer: notYetUsed=" << in.notYetUsed << " size=" << in.allocatedSize);
}
+ return true;
}
void
void
ConnStateData::noteMoreBodySpaceAvailable(BodyPipe::Pointer )
{
- handleRequestBodyData();
+ if (!handleRequestBodyData())
+ return;
+
+ readSomeData();
}
void
bool areAllContextsForThisConnection() const;
void freeAllContexts();
void readNextRequest();
- void makeSpaceAvailable();
+ bool maybeMakeSpaceAvailable();
ClientSocketContext::Pointer getCurrentContext() const;
void addContextToQueue(ClientSocketContext * context);
int getConcurrentRequestCount() const;
size_t maxRequestHeaderSize;
int64_t maxRequestBodySize;
int64_t maxChunkedRequestBodySize;
+ size_t maxRequestBufferSize;
size_t maxReplyHeaderSize;
acl_size_t *ReplyBodySize;