Skip to content

Commit 1c2fc1d

Browse files
committed
fix(http): handle oversized response header in FileCache send path
FileCache reserves a fixed block before the file content so header+body can be sent as one buffer. prepend_header() previously returned void and silently did nothing when the header exceeded the reserve (1K): the file was then served with a missing/garbage header and the caller had no way to know. - Bump the reserve from 1K to 4K (covers normal responses incl. long cookies / CORS / CSP headers), so the fast single-buffer path is taken in practice. - prepend_header() now returns bool. When the header still doesn't fit, HttpHandler falls back to sending the header first, then the file content (pResp->content already points at fc->filebuf) via the existing SEND_BODY state -- correct instead of silently broken. Verified: normal static file serve unchanged; a response with a >4K header still delivers both the full header and the intact file body. Minimal alternative to #823 (avoids its LRU/concurrency/config rework).
1 parent 2bd2061 commit 1c2fc1d

2 files changed

Lines changed: 20 additions & 8 deletions

File tree

http/server/FileCache.h

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
#include "hstring.h"
1111
#include "LRUCache.h"
1212

13-
#define HTTP_HEADER_MAX_LENGTH 1024 // 1K
13+
#define HTTP_HEADER_MAX_LENGTH 4096 // 4K
1414
#define FILE_CACHE_MAX_NUM 100
1515
#define FILE_CACHE_MAX_SIZE (1 << 22) // 4M
1616

@@ -48,11 +48,16 @@ typedef struct file_cache_s {
4848
filebuf.len = filesize;
4949
}
5050

51-
void prepend_header(const char* header, int len) {
52-
if (len > HTTP_HEADER_MAX_LENGTH) return;
51+
// Prepend the response header into the space reserved before filebuf so the
52+
// header + file content can be sent as one buffer (httpbuf). Returns false
53+
// if the header does not fit the reserved space; the caller must then send
54+
// the header and filebuf separately (filebuf stays intact either way).
55+
bool prepend_header(const char* header, int len) {
56+
if (len > HTTP_HEADER_MAX_LENGTH) return false;
5357
httpbuf.base = filebuf.base - len;
5458
httpbuf.len = len + filebuf.len;
5559
memcpy(httpbuf.base, header, len);
60+
return true;
5661
}
5762
} file_cache_t;
5863

http/server/HttpHandler.cpp

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -856,11 +856,18 @@ int HttpHandler::GetSendData(char** data, size_t* len) {
856856
// FileCache
857857
// NOTE: no copy filebuf, more efficient
858858
header = pResp->Dump(true, false);
859-
fc->prepend_header(header.c_str(), header.size());
860-
*data = fc->httpbuf.base;
861-
*len = fc->httpbuf.len;
862-
state = SEND_DONE;
863-
return *len;
859+
if (fc->prepend_header(header.c_str(), header.size())) {
860+
// header fit the reserved space: send header + file content
861+
// as one buffer.
862+
*data = fc->httpbuf.base;
863+
*len = fc->httpbuf.len;
864+
state = SEND_DONE;
865+
return *len;
866+
}
867+
// header too large for the reserved space: send the header now,
868+
// then the file content (pResp->content points at fc->filebuf).
869+
state = SEND_BODY;
870+
goto return_header;
864871
}
865872
// API service
866873
content_length = pResp->ContentLength();

0 commit comments

Comments
 (0)