Получение заголовков HTTP
В этом руководстве описывается, как получить сведения о заголовках из HTTP-запросов.
Шаги реализации
Существует два способа получения сведений о заголовке:
- Используйте одну из констант флага сведений о запросе, связанных с заголовком HTTP, который требуется вашему приложению.
- Используйте флаг атрибута HTTP_QUERY_CUSTOM и передайте имя заголовка HTTP.
Использование константы, связанной с заголовком HTTP, который требуется вашему приложению, быстрее для внутренней обработки, однако могут быть заголовки HTTP, для которых не существует соответствующей константы. В таких случаях метод с помощью флага атрибута HTTP_QUERY_CUSTOM доступен.
Оба метода используют функцию HttpQueryInfo. HttpQueryInfo принимает дескрипторHINTERNET, на котором был выполнен HTTP-запрос, один атрибут, буфер, значение DWORD, содержащее размер буфера и значение индекса. Модификатор также можно добавить в атрибут, переданный в HttpQueryInfo, чтобы указать, в каком формате должны быть возвращены данные.
Получение заголовков с помощью константы
Чтобы использовать функцию HttpQueryInfo для получения заголовка HTTP с помощью константы, выполните следующие действия.
- Вызовите HttpQueryInfo с константой из списка Attributes, с буфером NULL и переменной, содержащей размер буфера, установленной в ноль. Кроме того, если приложению нужны данные в определенном формате, можно добавить константу из списка модификаторов.
- Если запрошенный заголовок HTTP существует, вызов HttpQueryInfo должен завершиться ошибкой, GetLastError должен возвращать ERROR_INSUFFICIENT_BUFFER, а переменная, передаваемая для параметра lpdwBufferLength, должна быть установлена в количество требуемых байтов.
- Выделите буфер с необходимым количеством байтов.
- Повторите вызов HttpQueryInfo.
В следующем примере показано вызов HttpQueryInfo с помощью константы HTTP_QUERY_RAW_HEADERS_CRLF, которая представляет собой специальное значение, которое запрашивает все возвращаемые заголовки HTTP.
// Retrieving Headers Using a Constant
BOOL SampleCodeOne(HINTERNET hHttp)
{
LPVOID lpOutBuffer=NULL;
DWORD dwSize = 0;
retry:
// This call will fail on the first pass, because
// no buffer is allocated.
if(!HttpQueryInfo(hHttp,HTTP_QUERY_RAW_HEADERS_CRLF,
(LPVOID)lpOutBuffer,&dwSize,NULL))
{
if (GetLastError()==ERROR_HTTP_HEADER_NOT_FOUND)
{
// Code to handle the case where the header isn't available.
return TRUE;
}
else
{
// Check for an insufficient buffer.
if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
// Allocate the necessary buffer.
lpOutBuffer = new char[dwSize];
// Retry the call.
goto retry;
}
else
{
// Error handling code.
if (lpOutBuffer)
{
delete [] lpOutBuffer;
}
return FALSE;
}
}
}
if (lpOutBuffer)
{
delete [] lpOutBuffer;
}
return TRUE;
}
Получение заголовков с помощью HTTP_QUERY_CUSTOM
Чтобы использовать функцию HttpQueryInfo для получения заголовка HTTP с помощью HTTP_QUERY_CUSTOM, выполните следующие действия.
- Выделите буфер, достаточно большой для хранения имени строки заголовка HTTP.
- Запишите строковое имя заголовка HTTP в буфер.
- Вызовите HttpQueryInfo с параметрами: HTTP_QUERY_CUSTOM, буфером, содержащим строковое имя заголовка HTTP, и переменной, содержащей размер этого буфера. Кроме того, если приложению нужны данные в определенном формате, можно добавить константу из списка модификаторов.
- Если вызов HttpQueryInfo завершается ошибкой, и GetLastError возвращает ERROR_INSUFFICIENT_BUFFER, перенаследуйте буфер с необходимым количеством байтов.
- Снова запишите имя строки заголовка HTTP в буфер.
- Повторно выполните вызов HttpQueryInfo.
В следующем примере показан вызов HttpQueryInfo, используя константу HTTP_QUERY_CUSTOM для запроса заголовка HTTP Content-Type.
// Retrieving Headers Using HTTP_QUERY_CUSTOM
BOOL SampleCodeTwo(HINTERNET hHttp)
{
DWORD dwSize = 20;
LPVOID lpOutBuffer = new char[dwSize];
StringCchPrintfA((LPSTR)lpOutBuffer,dwSize,"Content-Type");
retry:
if(!HttpQueryInfo(hHttp,HTTP_QUERY_CUSTOM,
(LPVOID)lpOutBuffer,&dwSize,NULL))
{
if (GetLastError()==ERROR_HTTP_HEADER_NOT_FOUND)
{
// Code to handle the case where the header isn't available.
delete [] lpOutBuffer;
return TRUE;
}
else
{
// Check for an insufficient buffer.
if (GetLastError()==ERROR_INSUFFICIENT_BUFFER)
{
// Allocate the necessary buffer.
delete [] lpOutBuffer;
lpOutBuffer = new char[dwSize];
// Rewrite the header name in the buffer.
StringCchPrintfA((LPSTR)lpOutBuffer,
dwSize,"Content-Type");
// Retry the call.
goto retry;
}
else
{
// Error handling code.
delete [] lpOutBuffer;
return FALSE;
}
}
}
return TRUE;
}
Заметка
WinINet не поддерживает серверные реализации. Кроме того, его не следует использовать в рамках службы. Для реализации или служб сервера microsoft Windows HTTP Services (WinHTTP).