Функция WinHttpSendRequest (winhttp.h)
Функция WinHttpSendRequest отправляет указанный запрос на HTTP-сервер.
Синтаксис
WINHTTPAPI BOOL WinHttpSendRequest(
[in] HINTERNET hRequest,
[in, optional] LPCWSTR lpszHeaders,
[in] DWORD dwHeadersLength,
[in, optional] LPVOID lpOptional,
[in] DWORD dwOptionalLength,
[in] DWORD dwTotalLength,
[in] DWORD_PTR dwContext
);
Параметры
[in] hRequest
Дескриптор HINTERNET, возвращаемый WinHttpOpenRequest.
[in, optional] lpszHeaders
Указатель на строку, содержащую дополнительные заголовки для добавления в запрос. Этот параметр можно WINHTTP_NO_ADDITIONAL_HEADERS , если нет дополнительных заголовков для добавления.
[in] dwHeadersLength
Длинное целое число без знака, содержащее длину дополнительных заголовков в символах. Если этот параметр имеет значение -1L , а pwszHeaders не равен NULL, эта функция предполагает, что pwszHeaders завершается null и вычисляется длина.
[in, optional] lpOptional
Указатель на буфер, содержащий любые необязательные данные для отправки сразу после заголовков запроса. Этот параметр обычно используется для операций POST и PUT. Необязательными данными могут быть ресурсы или данные, опубликованные на сервере. Этот параметр можно WINHTTP_NO_REQUEST_DATA , если нет необязательных данных для отправки.
Если параметр dwOptionalLength имеет значение 0, этот параметр игнорируется и имеет значение NULL.
Этот буфер должен оставаться доступным до тех пор, пока не будет закрыт дескриптор запроса или до завершения вызова WinHttpReceiveResponse .
[in] dwOptionalLength
Целое число без знака, содержащее длину необязательных данных в байтах. Этот параметр может быть равен нулю, если нет необязательных данных для отправки.
Этот параметр должен содержать допустимую длину, если параметр lpOptional не равен NULL. В противном случае lpOptional игнорируется и имеет значение NULL.
[in] dwTotalLength
Длинное целое число без знака, содержащее длину в байтах общего объема отправленных данных. Этот параметр указывает заголовок Content-Length запроса. Если значение этого параметра больше длины, указанной в dwOptionalLength, то для отправки дополнительных данных можно использовать WinHttpWriteData .
Параметр dwTotalLength не должен меняться между вызовами WinHttpSendRequest для одного и того же запроса. Если необходимо изменить dwTotalLength , вызывающий объект должен создать новый запрос.
[in] dwContext
Указатель на переменную размера с указателем, содержащую определяемое приложением значение, которое передается с помощью дескриптора запроса в любые функции обратного вызова.
Возвращаемое значение
Возвращает значение TRUE в случае успешного выполнения или FALSE в противном случае. Для получения дополнительных сведений об ошибке вызовите Метод GetLastError. Коды ошибок перечислены в следующей таблице.
Код ошибки | Описание |
---|---|
|
Возвращается при сбое подключения к серверу. |
|
Для безопасного HTTP-сервера требуется сертификат клиента. Приложение получает список издателей сертификатов, вызывая WinHttpQueryOption с параметром WINHTTP_OPTION_CLIENT_CERT_ISSUER_LIST .
Если сервер запрашивает сертификат клиента, но не требует его, приложение может также вызвать WinHttpSetOption с параметром WINHTTP_OPTION_CLIENT_CERT_CONTEXT . В этом случае приложение указывает макрос WINHTTP_NO_CLIENT_CERT_CONTEXT в параметре lpBufferобъекта WinHttpSetOption. Дополнительные сведения см. в разделе параметр WINHTTP_OPTION_CLIENT_CERT_CONTEXT . Windows Server 2003 с пакетом обновления 1 (SP1), Windows XP с пакетом обновления 2 (SP2) и Windows 2000: Эта ошибка не поддерживается. |
|
Соединение с сервером было сброшено или прервано, или обнаружен несовместимый протокол SSL. Например, WinHTTP версии 5.1 не поддерживает SSL2, если только клиент не включает его. |
|
Не удается выполнить запрошенную операцию, так как предоставленный дескриптор находится в неправильном состоянии. |
|
Для этой операции указан неправильный тип дескриптора. |
|
Произошла внутренняя ошибка. |
|
Недопустимый URL-адрес. |
|
Попытка входа завершилась сбоем. При обнаружении этой ошибки дескриптор запроса должен быть закрыт с помощью WinHttpCloseHandle. Перед повтором функции, которая изначально вызвала эту ошибку, необходимо создать новый дескриптор запроса. |
|
Не удается разрешить имя сервера. |
|
Операция была отменена, как правило, из-за того, что дескриптор, с которым выполнялся запрос, был закрыт до завершения операции. |
|
Возвращается, когда входящий ответ превышает внутренний размер WinHTTP. |
|
В SSL-сертификате, отправленном сервером, обнаружена одна или несколько ошибок. Чтобы определить тип ошибки, проверьте с помощью уведомления WINHTTP_CALLBACK_STATUS_SECURE_FAILURE в функции обратного вызова состояния. Дополнительные сведения см. в разделе WINHTTP_STATUS_CALLBACK. |
|
Поддержка функции WinHTTP завершается или выгружается. |
|
Истек срок действия запроса. |
|
URL-адрес указывает схему, отличаемую от "http:" или "https:". |
|
Недостаточно памяти для выполнения запрошенной операции. (Код ошибки Windows) Windows Server 2003, Windows XP и Windows 2000: Диапазон резервирования TCP, заданный с параметром WINHTTP_OPTION_PORT_RESERVATION , недостаточно велик для отправки этого запроса. |
|
Длина содержимого, указанная в параметре dwTotalLength , не соответствует длине, указанной в заголовке Content-Length.
Параметр lpOptional должен иметь значение NULL , а параметр dwOptionalLength должен быть равен нулю при наличии заголовка Transfer-Encoding. Заголовок Content-Length не может присутствовать при наличии Transfer-Encoding заголовка. |
|
Приложение должно снова вызвать WinHttpSendRequest из-за проблемы с перенаправлением или проверкой подлинности.
Windows Server 2003 с пакетом обновления 1 (SP1), Windows XP с пакетом обновления 2 (SP2) и Windows 2000: Эта ошибка не поддерживается. |
Комментарии
Даже если WinHTTP используется в асинхронном режиме, то есть если WINHTTP_FLAG_ASYNC задано в WinHttpOpen, эта функция может работать синхронно или асинхронно. В любом случае, если запрос успешно отправлен, приложение вызывается с состоянием завершения, равным WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE. Завершение WINHTTP_CALLBACK_STATUS_REQUEST_ERROR указывает, что операция завершилась асинхронно, но завершилась сбоем. После получения обратного вызова состояния WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE приложение может начать получать ответ от сервера с помощью WinHttpReceiveResponse. До этого нельзя было вызывать другие асинхронные функции, в противном случае возвращается ERROR_WINHTTP_INCORRECT_HANDLE_STATE .
Приложение не должно удалять или изменять буфер, на который указывает lpOptional , пока не будет закрыт дескриптор запроса или вызов WinHttpReceiveResponse не будет завершен, так как запрос проверки подлинности или перенаправление, для которого требуются необязательные данные, могут быть обнаружены в процессе получения ответа. Если операция должна быть прервана с помощью WinHttpCloseHandle, приложение должно поддерживать буфер, пока не получит WINHTTP_CALLBACK_STATUS_REQUEST_ERROR обратного вызова с кодом ошибки ERROR_WINHTTP_OPERATION_CANCELLED .
Если WinHTTP используется синхронно, то есть если WINHTP_FLAG_ASYNC не задано в WinHttpOpen, приложение не вызывается с состоянием завершения, даже если зарегистрирована функция обратного вызова. В этом режиме приложение может вызывать WinHttpReceiveResponse при возврате WinHttpSendRequest .
Функция WinHttpSendRequest отправляет указанный запрос на HTTP-сервер и позволяет клиенту указать дополнительные заголовки для отправки вместе с запросом.
Эта функция также позволяет клиенту указать необязательные данные для отправки на HTTP-сервер сразу после заголовков запроса. Эта функция обычно используется для операций записи, таких как PUT и POST.
Приложение может использовать один и тот же дескриптор HTTP-запроса в нескольких вызовах WinHttpSendRequest для повторной отправки одного и того же запроса, но перед повторным вызовом этой функции приложение должно прочитать все данные, возвращенные из предыдущего вызова.
Имя и значение заголовков запросов, добавленных с помощью этой функции, проверяются. Заголовки должны быть правильно сформированы. Дополнительные сведения о допустимых заголовках HTTP см. в статье RFC 2616. Если используется недопустимый заголовок, эта функция завершается сбоем и GetLastError возвращает ERROR_INVALID_PARAMETER. Недопустимый заголовок не добавлен.
Windows 2000: При отправке запросов из нескольких потоков может произойти значительное снижение производительности сети и ЦП.
Windows XP и Windows 2000: См. раздел Требования к времени выполнения.
WinHttpSetStatusCallback
Если функция обратного вызова состояния была установлена с winHttpSetStatusCallback, то следующие уведомления, заданные в параметре dwNotificationFlagswinHttpSetStatusCallback , указывают на ход отправки запроса:- WINHTTP_CALLBACK_STATUS_DETECTING_PROXY (не реализовано)
- WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE (только в асинхронном режиме)
- WINHTTP_CALLBACK_STATUS_REDIRECT
- WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
- WINHTTP_CALLBACK_STATUS_INTERMEDIATE_RESPONSE
- WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
- WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
- WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
- WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
- WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
- WINHTTP_CALLBACK_STATUS_REQUEST_SENT
- WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
- WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
- WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
- WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
Поддержка отправки размером более 4 ГБ
Начиная с Windows Vista и Windows Server 2008, WinHttp поддерживает отправку файлов размером до LARGE_INTEGER (2^64 байта) с помощью заголовка Content-Length. Длина полезных данных, указанная в вызове WinHttpSendRequest , ограничена размером DWORD (2^32 байта). Чтобы отправить данные на URL-адрес, превышающий DWORD, приложение должно указать длину в заголовке Content-Length запроса. В этом случае клиентское приложение WinHttp вызывает WinHttpSendRequest с параметром dwTotalLength , равным WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH.Если заголовок Content-Length указывает длину меньше 2^32, приложение также должно указать длину содержимого в вызове WinHttpSendRequest. Если параметр dwTotalLength не соответствует длине, указанной в заголовке Content-Length, вызов завершается ошибкой и возвращает ERROR_INVALID_PARAMETER.
Заголовок Content-Length можно добавить в вызове WinHttpAddRequestHeaders или указать в параметре lpszHeaderwinHttpSendRequest , как показано в следующем примере кода.
BOOL fRet = WinHttpSendRequest(
hReq,
L"Content-Length: 68719476735\r\n",
-1L,
WINHTTP_NO_REQUEST_DATA,
0,
WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH,
pMyContent);
Заголовок кодирования передачи
Начиная с Windows Vista и Windows Server 2008, WinHttp позволяет приложениям выполнять кодирование фрагментов передачи данных, отправляемых на сервер. Если заголовок Transfer-Encoding присутствует в запросе WinHttp, параметру dwTotalLength в вызове WinHttpSendRequest присваивается значение WINHTTP_IGNORE_REQUEST_TOTAL_LENGTH и приложение отправляет тело сущности в одном или нескольких вызовах WinHttpWriteData. Параметр lpOptionalwinHttpSendRequest должен иметь значение NULL , а параметр dwOptionLength должен быть равен нулю, в противном случае возвращается ошибка ERROR_WINHTTP_INVALID_PARAMETER . Чтобы завершить передачу фрагментированных данных, приложение создает блок нулевой длины и отправляет его в последнем вызове WinHttpWriteData.Примеры
В следующем примере кода показано, как получить дескриптор HINTERNET , открыть сеанс HTTP, создать заголовок запроса и отправить этот заголовок на сервер.
BOOL bResults = FALSE;
HINTERNET hSession = NULL,
hConnect = NULL,
hRequest = NULL;
// Use WinHttpOpen to obtain a session handle.
hSession = WinHttpOpen( L"A WinHTTP Example Program/1.0",
WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
WINHTTP_NO_PROXY_NAME,
WINHTTP_NO_PROXY_BYPASS, 0);
// Specify an HTTP server.
if (hSession)
hConnect = WinHttpConnect( hSession, L"www.wingtiptoys.com",
INTERNET_DEFAULT_HTTP_PORT, 0);
// Create an HTTP Request handle.
if (hConnect)
hRequest = WinHttpOpenRequest( hConnect, L"PUT",
L"/writetst.txt",
NULL, WINHTTP_NO_REFERER,
WINHTTP_DEFAULT_ACCEPT_TYPES,
0);
// Send a Request.
if (hRequest)
bResults = WinHttpSendRequest( hRequest,
WINHTTP_NO_ADDITIONAL_HEADERS,
0, WINHTTP_NO_REQUEST_DATA, 0,
0, 0);
// Place additional code here.
// Report errors.
if (!bResults)
printf("Error %d has occurred.\n",GetLastError());
// Close open handles.
if (hRequest) WinHttpCloseHandle(hRequest);
if (hConnect) WinHttpCloseHandle(hConnect);
if (hSession) WinHttpCloseHandle(hSession);
Требования
Требование | Значение |
---|---|
Минимальная версия клиента | Windows XP, Windows 2000 Профессиональная с пакетом обновления 3 (SP3) [только классические приложения] |
Минимальная версия сервера | Windows Server 2003, Windows 2000 Server с пакетом обновления 3 (SP3) [только классические приложения] |
Целевая платформа | Windows |
Header | winhttp.h |
Библиотека | Winhttp.lib |
DLL | Winhttp.dll |
Распространяемые компоненты | WinHTTP 5.0 и Internet Обозреватель 5.01 или более поздней версии в Windows XP и Windows 2000. |
См. также раздел
Сведения о службах MICROSOFT Windows HTTP (WinHTTP)
WINHTTP_STATUS_CALLBACK