我正在尝试在应用程序中创建嵌入式web服务器。为此,我使用http。sys来自Windows的HTTP服务器组件。当我不尝试使用HttpAddFragmentToCache
时,一切都很好。
我所做的到目前为止(删除任何错误检查,但没有片段缓存它工作正常):
HttpInitialize( HTTPAPI_VERSION_1, HTTP_INITIALIZE_SERVER );
HttpCreateHttpHandle( FQueueHandle )
HttpAddUrl( FQueueHandle, PWideChar( W ) );
...
HttpRemoveUrl( FQueueHandle, PWideChar( W ) );
HttpTerminate( HTTP_INITIALIZE_SERVER );
现在当一个请求来自于一个帮助线程:
HttpReceiveHttpRequest( FQueueHandle, FRequestID, 0, FRequest^, FRequestBufferSize, @Bytes );
// if needed:
HttpReceiveRequestEntityBody( FQueueHandle, FRequestId, 0, @FRequestContent[ 0 ], Longword( N ), @BytesRead )
// Fill in chunks...
// Respond
HttpSendHttpResponse( FQueueHandle, FRequestId, 0, FResponse, nil, N );
我想改变的是添加一些静态文档到片段缓存(在上面的省略号处):
Chunk.DataChunkType := hctFromMemory;
Chunk.FromMemory.pBuffer := @Content[ 0 ];
Chunk.FromMemory.BufferLength := Length( Content );
Policy.Policy := hcpUserInvalidates;
Policy.SecondsToLive := 0;
Result := HttpAddFragmentToCache( FQueueHandle, PWideChar( W ), Chunk, Policy );
注意:在我的代码中,所有重叠的参数都是可选的nil/NULL,这解释了为什么你可能会错过这个参数。
这将产生结果50(不支持该请求)。我试着从内存和文件句柄中添加片段,所有不同的策略。检查在反汇编中传递的值是否正确,检查传递给HttpAddFragmentToCache
的字符串是否确实是传递给HttpAddUrl
的字符串的有效子url(如果不是,您会得到操作系统错误2,因此也不是它)。
我的问题是:这可能是什么?我尝试以最直接的方式使用这个API调用,我可以看到(这是API的设计目的),但显然我做错了…
更新:
看起来用HttpAddFragmentToCache
函数添加的片段有一个最大大小:
当上面的代码被替换为:
Chunk.FromMemory.BufferLength := Min( 256*1024, Length( Content ) );
无错误;当被
取代时Chunk.FromMemory.BufferLength := Min( 256*1024 + 1, Length( Content ) );
它失败。显然有尺寸限制,而且……我找到它了:
http://support.microsoft.com/kb/820129UriMaxUriBytes 262144 (bytes)4096(4k) - 16777216(16MB)字节任意比这更大的响应值不在内核中缓存响应缓存。
这留下两个选项:1。为较大的文件保留多个片段。或2。
解决了这个问题:每个片段缓存的大小是有限制的;默认为256KB。
如果没有实现的所有源代码,这有点困难。
什么时候调用HttpAddFragmentToCache
?它应该在客户端TThread实例中调用HttpReceiveHttpRequest
()之前。
例如,你的HttpReceiveHttpRequest
()调用听起来有点奇怪。你应该使用
HttpReceiveRequestEntityBody( FQueueHandle, FRequest^.RequestID, ... )
看看我们的SynCrtSock
单元中的THttpApiServer
类,这是http。系统服务器。它还不支持缓存,但至少主初始化和线程池可以正常工作。