diff --git a/http/server/FileCache.h b/http/server/FileCache.h index 363c41d88..2e0d51aff 100644 --- a/http/server/FileCache.h +++ b/http/server/FileCache.h @@ -10,7 +10,7 @@ #include "hstring.h" #include "LRUCache.h" -#define HTTP_HEADER_MAX_LENGTH 1024 // 1K +#define HTTP_HEADER_MAX_LENGTH 4096 // 4K #define FILE_CACHE_MAX_NUM 100 #define FILE_CACHE_MAX_SIZE (1 << 22) // 4M @@ -48,11 +48,16 @@ typedef struct file_cache_s { filebuf.len = filesize; } - void prepend_header(const char* header, int len) { - if (len > HTTP_HEADER_MAX_LENGTH) return; + // Prepend the response header into the space reserved before filebuf so the + // header + file content can be sent as one buffer (httpbuf). Returns false + // if the header does not fit the reserved space; the caller must then send + // the header and filebuf separately (filebuf stays intact either way). + bool prepend_header(const char* header, int len) { + if (len > HTTP_HEADER_MAX_LENGTH) return false; httpbuf.base = filebuf.base - len; httpbuf.len = len + filebuf.len; memcpy(httpbuf.base, header, len); + return true; } } file_cache_t; diff --git a/http/server/HttpHandler.cpp b/http/server/HttpHandler.cpp index 4345a05bc..fa2013b32 100644 --- a/http/server/HttpHandler.cpp +++ b/http/server/HttpHandler.cpp @@ -856,11 +856,18 @@ int HttpHandler::GetSendData(char** data, size_t* len) { // FileCache // NOTE: no copy filebuf, more efficient header = pResp->Dump(true, false); - fc->prepend_header(header.c_str(), header.size()); - *data = fc->httpbuf.base; - *len = fc->httpbuf.len; - state = SEND_DONE; - return *len; + if (fc->prepend_header(header.c_str(), header.size())) { + // header fit the reserved space: send header + file content + // as one buffer. + *data = fc->httpbuf.base; + *len = fc->httpbuf.len; + state = SEND_DONE; + return *len; + } + // header too large for the reserved space: send the header now, + // then the file content (pResp->content points at fc->filebuf). + state = SEND_BODY; + goto return_header; } // API service content_length = pResp->ContentLength();