Поделиться через


Получение заголовков HTTP

В этом руководстве описывается, как получить сведения о заголовках из HTTP-запросов.

Шаги реализации

Существует два способа получения сведений о заголовке:

  • Используйте одну из констант флага сведений о запросе, связанных с заголовком HTTP, который требуется вашему приложению.
  • Используйте флаг атрибута HTTP_QUERY_CUSTOM и передайте имя заголовка HTTP.

Использование константы, связанной с заголовком HTTP, который требуется вашему приложению, быстрее для внутренней обработки, однако могут быть заголовки HTTP, для которых не существует соответствующей константы. В таких случаях метод с помощью флага атрибута HTTP_QUERY_CUSTOM доступен.

Оба метода используют функцию HttpQueryInfo. HttpQueryInfo принимает дескрипторHINTERNET, на котором был выполнен HTTP-запрос, один атрибут, буфер, значение DWORD, содержащее размер буфера и значение индекса. Модификатор также можно добавить в атрибут, переданный в HttpQueryInfo, чтобы указать, в каком формате должны быть возвращены данные.

Получение заголовков с помощью константы

Чтобы использовать функцию HttpQueryInfo для получения заголовка HTTP с помощью константы, выполните следующие действия.

  1. Вызовите HttpQueryInfo с константой из списка Attributes, с буфером NULL и переменной, содержащей размер буфера, установленной в ноль. Кроме того, если приложению нужны данные в определенном формате, можно добавить константу из списка модификаторов.
  2. Если запрошенный заголовок HTTP существует, вызов HttpQueryInfo должен завершиться ошибкой, GetLastError должен возвращать ERROR_INSUFFICIENT_BUFFER, а переменная, передаваемая для параметра lpdwBufferLength, должна быть установлена в количество требуемых байтов.
  3. Выделите буфер с необходимым количеством байтов.
  4. Повторите вызов 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, выполните следующие действия.

  1. Выделите буфер, достаточно большой для хранения имени строки заголовка HTTP.
  2. Запишите строковое имя заголовка HTTP в буфер.
  3. Вызовите HttpQueryInfo с параметрами: HTTP_QUERY_CUSTOM, буфером, содержащим строковое имя заголовка HTTP, и переменной, содержащей размер этого буфера. Кроме того, если приложению нужны данные в определенном формате, можно добавить константу из списка модификаторов.
  4. Если вызов HttpQueryInfo завершается ошибкой, и GetLastError возвращает ERROR_INSUFFICIENT_BUFFER, перенаследуйте буфер с необходимым количеством байтов.
  5. Снова запишите имя строки заголовка HTTP в буфер.
  6. Повторно выполните вызов 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).