HttpAddFragmentToCache и ошибка ОС 50 - PullRequest
3 голосов
/ 26 апреля 2011

Я пытаюсь создать встроенный веб-сервер в приложении.Для этого я использую HTTP-сервер HTTP.sys из Windows.Все хорошо работает, когда я не пытаюсь использовать 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, является действительным subURL по сравнению со строкой, переданной в 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 (байты) 4096 (4 КБ) - 16777216 (16 МБ) байтов Любой ответ, которыйбольше, чем это значение, не кэшируется в кеше ответов ядра.

Это оставляет две возможности: 1. сохранить несколько фрагментов для больших файлов.или 2. увеличить этот лимит в реестре.

Ответы [ 2 ]

1 голос
/ 27 апреля 2011

Решена проблема: существует ограничение в размере, который кеш фрагментов может кэшировать на фрагмент;по умолчанию 256 КБ.Подробности смотрите в обновлении вопроса.

0 голосов
/ 26 апреля 2011

Это немного сложно без всего исходного кода вашей реализации.

Когда вы звоните HttpAddFragmentToCache? Это должно быть перед любым вызовом HttpReceiveHttpRequest () в клиентских экземплярах TThread.

Например, ваш вызов HttpReceiveHttpRequest () звучит немного странно для меня. Вы должны использовать

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

Взгляните на класс THttpApiServer в нашем модуле SynCrtSock, чтобы увидеть рабочий пример сервера http.sys. Он пока не поддерживает кэш, но, по крайней мере, основная инициализация и пул потоков работают как положено.

...