3

我正在尝试在应用程序中创建嵌入式 Web 服务器。为此,我使用 Windows 中的 http.sys 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是否确实是传递给的字符串的有效子URL HttpAddUrl(如果不是,您会收到操作系统错误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/820129

UriMaxUriBytes 262144 (bytes) 4096(4k) – 16777216(16MB) bytes 任何大于此值的响应都不会缓存在内核响应缓存中。

这留下了两个选择: 1. 为较大的文件保留多个片段。或 2. 在注册表中增加此限制。

4

2 回答 2

1

解决问题:分片缓存每个分片可以缓存的大小有限制;默认为 256KB。有关详细信息,请参阅问题的更新。

于 2011-04-26T20:33:10.407 回答
0

如果没有您的实现的所有源代码,这有点困难。

你什么时候打电话HttpAddFragmentToCache?它应该HttpReceiveHttpRequest在客户端 TThread 实例中对 () 的任何调用之前。

例如,您的HttpReceiveHttpRequest() 调用对我来说听起来有点奇怪。你应该使用

HttpReceiveRequestEntityBody( FQueueHandle, FRequest^.RequestID, ... ) 

看看THttpApiServer我们SynCrtSock单元中的课程,以 http.sys 服务器的工作示例。它还不支持缓存,但至少主初始化和线程池按预期工作。

于 2011-04-26T12:23:16.487 回答