Получение заголовков HTTP
В этом руководстве описывается, как получить сведения о заголовке из HTTP-запросов.
Этапы реализации
Получить сведения о заголовке можно двумя способами:
- Используйте одну из констант флага сведений о запросе , связанную с заголовком HTTP, который требуется приложению.
- Используйте флаг атрибута HTTP_QUERY_CUSTOM и передайте имя заголовка HTTP.
Использование константы, связанной с заголовком HTTP, который требуется приложению, выполняется быстрее, но с ними могут быть заголовки HTTP, которые не связаны с ними. В таких случаях доступен метод, использующий флаг атрибута HTTP_QUERY_CUSTOM.
Оба метода используют функцию HttpQueryInfo . HttpQueryInfo принимает дескриптор HINTERNET , на котором был сделан HTTP-запрос, один атрибут, буфер, значение DWORD, содержащее размер буфера и значение индекса. Модификатор также можно добавить в атрибут, передаваемый в HttpQueryInfo , чтобы указать, в каком формате должны возвращаться данные.
Получение заголовков с помощью константы
Чтобы использовать функцию HttpQueryInfo для получения заголовка HTTP с помощью константы, выполните следующие действия.
- Вызов HttpQueryInfo с константой из списка атрибутов , буфера 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 типа контента.
// 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).