Получение заголовков 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-заголовка 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 (WinHTTP).