ReactOS 0.4.16-dev-329-g9223134
http.c File Reference
#include <stdlib.h>
#include "winsock2.h"
#include "ws2ipdef.h"
#include <stdarg.h>
#include <stdio.h>
#include <time.h>
#include <assert.h>
#include <errno.h>
#include <limits.h>
#include "windef.h"
#include "winbase.h"
#include "wininet.h"
#include "winerror.h"
#include "winternl.h"
#include "shlwapi.h"
#include "sspi.h"
#include "wincrypt.h"
#include "winuser.h"
#include "internet.h"
#include "zlib.h"
#include "resource.h"
#include "wine/debug.h"
#include "wine/exception.h"
Include dependency graph for http.c:

Go to the source code of this file.

Classes

struct  HttpAuthInfo
 
struct  _basicAuthorizationData
 
struct  _authorizationData
 
struct  data_stream_vtbl_t
 
struct  chunked_stream_t
 
struct  gzip_stream_t
 
struct  read_file_task_t
 
struct  send_request_task_t
 
struct  end_request_task_t
 

Macros

#define NO_SHLWAPI_STREAM
 
#define NO_SHLWAPI_REG
 
#define NO_SHLWAPI_GDI
 
#define HTTP_ADDHDR_FLAG_ADD   0x20000000
 
#define HTTP_ADDHDR_FLAG_ADD_IF_NEW   0x10000000
 
#define HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA   0x40000000
 
#define HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON   0x01000000
 
#define HTTP_ADDHDR_FLAG_REPLACE   0x80000000
 
#define HTTP_ADDHDR_FLAG_REQ   0x02000000
 
#define COLLECT_TIME   60000
 
#define FE(x)   { x, #x }
 
#define COALESCEFLAGS   (HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA|HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON)
 

Typedefs

typedef struct _basicAuthorizationData basicAuthorizationData
 
typedef struct _authorizationData authorizationData
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (wininet)
 
static DWORD HTTP_GetResponseHeaders (http_request_t *req, INT *len)
 
static DWORD HTTP_ProcessHeader (http_request_t *req, LPCWSTR field, LPCWSTR value, DWORD dwModifier)
 
static LPWSTRHTTP_InterpretHttpHeader (LPCWSTR buffer)
 
static DWORD HTTP_InsertCustomHeader (http_request_t *req, LPHTTPHEADERW lpHdr)
 
static INT HTTP_GetCustomHeaderIndex (http_request_t *req, LPCWSTR lpszField, INT index, BOOL Request)
 
static BOOL HTTP_DeleteCustomHeader (http_request_t *req, DWORD index)
 
static LPWSTR HTTP_build_req (LPCWSTR *list, int len)
 
static DWORD HTTP_HttpQueryInfoW (http_request_t *, DWORD, LPVOID, LPDWORD, LPDWORD)
 
static UINT HTTP_DecodeBase64 (LPCWSTR base64, LPSTR bin)
 
static DWORD drain_content (http_request_t *, BOOL)
 
void server_addref (server_t *server)
 
void server_release (server_t *server)
 
static BOOL process_host_port (server_t *server)
 
server_tget_server (substr_t name, INTERNET_PORT port, BOOL is_https, BOOL do_create)
 
BOOL collect_connections (collect_type_t collect_type)
 
static DWORD WINAPI collect_connections_proc (void *arg)
 
static LPHTTPHEADERW HTTP_GetHeader (http_request_t *req, LPCWSTR head)
 
static WCHARget_host_header (http_request_t *req)
 
static void destroy_data_stream (data_stream_t *stream)
 
static void reset_data_stream (http_request_t *req)
 
static void remove_header (http_request_t *request, const WCHAR *str, BOOL from_request)
 
static BOOL gzip_end_of_data (data_stream_t *stream, http_request_t *req)
 
static DWORD gzip_read (data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size, DWORD *read, BOOL allow_blocking)
 
static DWORD gzip_drain_content (data_stream_t *stream, http_request_t *req, BOOL allow_blocking)
 
static void gzip_destroy (data_stream_t *stream)
 
static voidpf wininet_zalloc (voidpf opaque, uInt items, uInt size)
 
static void wininet_zfree (voidpf opaque, voidpf address)
 
static DWORD init_gzip_stream (http_request_t *req, BOOL is_gzip)
 
static void HTTP_FreeTokens (LPWSTR *token_array)
 
static void HTTP_FixURL (http_request_t *request)
 
static WCHARbuild_request_header (http_request_t *request, const WCHAR *verb, const WCHAR *path, const WCHAR *version, BOOL use_cr)
 
static WCHARbuild_response_header (http_request_t *request, BOOL use_cr)
 
static void HTTP_ProcessCookies (http_request_t *request)
 
static void strip_spaces (LPWSTR start)
 
static BOOL is_basic_auth_value (LPCWSTR pszAuthValue, LPWSTR *pszRealm)
 
static void destroy_authinfo (struct HttpAuthInfo *authinfo)
 
static UINT retrieve_cached_basic_authorization (http_request_t *req, const WCHAR *host, const WCHAR *realm, char **auth_data)
 
static void cache_basic_authorization (LPWSTR host, LPWSTR realm, LPSTR auth_data, UINT auth_data_len)
 
static BOOL retrieve_cached_authorization (LPWSTR host, LPWSTR scheme, SEC_WINNT_AUTH_IDENTITY_W *nt_auth_identity)
 
static void cache_authorization (LPWSTR host, LPWSTR scheme, SEC_WINNT_AUTH_IDENTITY_W *nt_auth_identity)
 
void free_authorization_cache (void)
 
static BOOL HTTP_DoAuthorization (http_request_t *request, LPCWSTR pszAuthValue, struct HttpAuthInfo **ppAuthInfo, LPWSTR domain_and_username, LPWSTR password, LPWSTR host)
 
static DWORD HTTP_HttpAddRequestHeadersW (http_request_t *request, LPCWSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier)
 
BOOL WINAPI HttpAddRequestHeadersW (HINTERNET hHttpRequest, LPCWSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier)
 
BOOL WINAPI HttpAddRequestHeadersA (HINTERNET hHttpRequest, LPCSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier)
 
static void free_accept_types (WCHAR **accept_types)
 
static WCHAR ** convert_accept_types (const char **accept_types)
 
HINTERNET WINAPI HttpOpenRequestA (HINTERNET hHttpSession, LPCSTR lpszVerb, LPCSTR lpszObjectName, LPCSTR lpszVersion, LPCSTR lpszReferrer, LPCSTR *lpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext)
 
static UINT HTTP_EncodeBase64 (LPCSTR bin, unsigned int len, LPWSTR base64)
 
static WCHARencode_auth_data (const WCHAR *scheme, const char *data, UINT data_len)
 
static BOOL HTTP_InsertAuthorization (http_request_t *request, struct HttpAuthInfo *pAuthInfo, LPCWSTR header)
 
static WCHARbuild_proxy_path_url (http_request_t *req)
 
static BOOL HTTP_DomainMatches (LPCWSTR server, substr_t domain)
 
static BOOL HTTP_ShouldBypassProxy (appinfo_t *lpwai, LPCWSTR server)
 
static BOOL HTTP_DealWithProxy (appinfo_t *hIC, http_session_t *session, http_request_t *request)
 
static DWORD HTTP_ResolveName (http_request_t *request)
 
static WCHARcompose_request_url (http_request_t *req)
 
static void HTTPREQ_Destroy (object_header_t *hdr)
 
static void http_release_netconn (http_request_t *req, BOOL reuse)
 
static BOOL HTTP_KeepAlive (http_request_t *request)
 
static void HTTPREQ_CloseConnection (object_header_t *hdr)
 
static DWORD str_to_buffer (const WCHAR *str, void *buffer, DWORD *size, BOOL unicode)
 
static DWORD get_security_cert_struct (http_request_t *req, INTERNET_CERTIFICATE_INFOA *info)
 
static DWORD HTTPREQ_QueryOption (object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
 
static DWORD HTTPREQ_SetOption (object_header_t *hdr, DWORD option, void *buffer, DWORD size)
 
static void commit_cache_entry (http_request_t *req)
 
static void create_cache_entry (http_request_t *req)
 
static DWORD read_more_data (http_request_t *req, int maxlen)
 
static void remove_data (http_request_t *req, int count)
 
static DWORD read_line (http_request_t *req, LPSTR buffer, DWORD *len)
 
static BOOL end_of_read_data (http_request_t *req)
 
static DWORD read_http_stream (http_request_t *req, BYTE *buf, DWORD size, DWORD *read, BOOL allow_blocking)
 
static DWORD refill_read_buffer (http_request_t *req, BOOL allow_blocking, DWORD *read_bytes)
 
static BOOL netconn_end_of_data (data_stream_t *stream, http_request_t *req)
 
static DWORD netconn_read (data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size, DWORD *read, BOOL allow_blocking)
 
static DWORD netconn_drain_content (data_stream_t *stream, http_request_t *req, BOOL allow_blocking)
 
static void netconn_destroy (data_stream_t *stream)
 
static char next_chunked_data_char (chunked_stream_t *stream)
 
static BOOL chunked_end_of_data (data_stream_t *stream, http_request_t *req)
 
static DWORD chunked_read (data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size, DWORD *read, BOOL allow_blocking)
 
static DWORD chunked_drain_content (data_stream_t *stream, http_request_t *req, BOOL allow_blocking)
 
static void chunked_destroy (data_stream_t *stream)
 
static DWORD set_content_length (http_request_t *request)
 
static void send_request_complete (http_request_t *req, DWORD_PTR result, DWORD error)
 
static void HTTP_ReceiveRequestData (http_request_t *req)
 
static DWORD HTTPREQ_Read (http_request_t *req, void *buffer, DWORD size, DWORD *read, BOOL allow_blocking)
 
static void async_read_file_proc (task_header_t *hdr)
 
static DWORD async_read (http_request_t *req, void *buf, DWORD size, DWORD read_pos, DWORD *ret_read)
 
static DWORD HTTPREQ_ReadFile (object_header_t *hdr, void *buf, DWORD size, DWORD *ret_read, DWORD flags, DWORD_PTR context)
 
static DWORD HTTPREQ_WriteFile (object_header_t *hdr, const void *buffer, DWORD size, DWORD *written)
 
static DWORD HTTPREQ_QueryDataAvailable (object_header_t *hdr, DWORD *available, DWORD flags, DWORD_PTR ctx)
 
static DWORD HTTPREQ_LockRequestFile (object_header_t *hdr, req_file_t **ret)
 
static DWORD HTTP_HttpOpenRequestW (http_session_t *session, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszReferrer, LPCWSTR *lpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext, HINTERNET *ret)
 
HINTERNET WINAPI HttpOpenRequestW (HINTERNET hHttpSession, LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, LPCWSTR lpszReferrer, LPCWSTR *lpszAcceptTypes, DWORD dwFlags, DWORD_PTR dwContext)
 
BOOL WINAPI HttpQueryInfoW (HINTERNET hHttpRequest, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex)
 
BOOL WINAPI HttpQueryInfoA (HINTERNET hHttpRequest, DWORD dwInfoLevel, LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex)
 
static WCHARget_redirect_url (http_request_t *request)
 
static DWORD HTTP_HandleRedirect (http_request_t *request, WCHAR *url)
 
static void HTTP_InsertCookies (http_request_t *request)
 
static WORD HTTP_ParseWkday (LPCWSTR day)
 
static WORD HTTP_ParseMonth (LPCWSTR month)
 
static BOOL HTTP_ParseTime (SYSTEMTIME *st, LPCWSTR *str)
 
static BOOL HTTP_ParseDateAsAsctime (LPCWSTR value, FILETIME *ft)
 
static BOOL HTTP_ParseRfc1123Date (LPCWSTR value, FILETIME *ft)
 
static WORD HTTP_ParseWeekday (LPCWSTR day)
 
static BOOL HTTP_ParseRfc850Date (LPCWSTR value, FILETIME *ft)
 
static BOOL HTTP_ParseDate (LPCWSTR value, FILETIME *ft)
 
static void HTTP_ProcessExpires (http_request_t *request)
 
static void HTTP_ProcessLastModified (http_request_t *request)
 
static void http_process_keep_alive (http_request_t *req)
 
static DWORD open_http_connection (http_request_t *request, BOOL *reusing)
 
static charbuild_ascii_request (const WCHAR *str, void *data, DWORD data_len, DWORD *out_len)
 
static void set_content_length_header (http_request_t *request, DWORD len, DWORD flags)
 
static DWORD HTTP_HttpSendRequestW (http_request_t *request, LPCWSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwContentLength, BOOL bEndRequest)
 
static void AsyncHttpSendRequestProc (task_header_t *hdr)
 
static DWORD HTTP_HttpEndRequestW (http_request_t *request, DWORD dwFlags, DWORD_PTR dwContext)
 
BOOL WINAPI HttpEndRequestA (HINTERNET hRequest, LPINTERNET_BUFFERSA lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext)
 
static void AsyncHttpEndRequestProc (task_header_t *hdr)
 
BOOL WINAPI HttpEndRequestW (HINTERNET hRequest, LPINTERNET_BUFFERSW lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext)
 
BOOL WINAPI HttpSendRequestExA (HINTERNET hRequest, LPINTERNET_BUFFERSA lpBuffersIn, LPINTERNET_BUFFERSA lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext)
 
BOOL WINAPI HttpSendRequestExW (HINTERNET hRequest, LPINTERNET_BUFFERSW lpBuffersIn, LPINTERNET_BUFFERSW lpBuffersOut, DWORD dwFlags, DWORD_PTR dwContext)
 
BOOL WINAPI HttpSendRequestW (HINTERNET hHttpRequest, LPCWSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength)
 
BOOL WINAPI HttpSendRequestA (HINTERNET hHttpRequest, LPCSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength)
 
static void HTTPSESSION_Destroy (object_header_t *hdr)
 
static DWORD HTTPSESSION_QueryOption (object_header_t *hdr, DWORD option, void *buffer, DWORD *size, BOOL unicode)
 
static DWORD HTTPSESSION_SetOption (object_header_t *hdr, DWORD option, void *buffer, DWORD size)
 
DWORD HTTP_Connect (appinfo_t *hIC, LPCWSTR lpszServerName, INTERNET_PORT serverPort, LPCWSTR lpszUserName, LPCWSTR lpszPassword, DWORD dwFlags, DWORD_PTR dwContext, DWORD dwInternalFlags, HINTERNET *ret)
 
static void HTTP_clear_response_headers (http_request_t *request)
 
static INT HTTP_GetCustomHeaderIndex (http_request_t *request, LPCWSTR lpszField, int requested_index, BOOL request_only)
 
BOOL WINAPI IsHostInProxyBypassList (DWORD flags, LPCSTR szHost, DWORD length)
 

Variables

static struct list basicAuthorizationCache = LIST_INIT(basicAuthorizationCache)
 
static struct list authorizationCache = LIST_INIT(authorizationCache)
 
static CRITICAL_SECTION authcache_cs = { &critsect_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG critsect_debug
 
static CRITICAL_SECTION connection_pool_cs = { &connection_pool_debug, -1, 0, 0, 0, 0 }
 
static CRITICAL_SECTION_DEBUG connection_pool_debug
 
static struct list connection_pool = LIST_INIT(connection_pool)
 
static BOOL collector_running
 
static const data_stream_vtbl_t gzip_stream_vtbl
 
static const signed char HTTP_Base64Dec []
 
static const data_stream_vtbl_t netconn_stream_vtbl
 
static const data_stream_vtbl_t chunked_stream_vtbl
 
static const object_vtbl_t HTTPREQVtbl
 
static const LPCWSTR header_lookup []
 
static const object_vtbl_t HTTPSESSIONVtbl
 

Macro Definition Documentation

◆ COALESCEFLAGS

◆ COLLECT_TIME

#define COLLECT_TIME   60000

Definition at line 74 of file http.c.

◆ FE

#define FE (   x)    { x, #x }

◆ HTTP_ADDHDR_FLAG_ADD

#define HTTP_ADDHDR_FLAG_ADD   0x20000000

Definition at line 67 of file http.c.

◆ HTTP_ADDHDR_FLAG_ADD_IF_NEW

#define HTTP_ADDHDR_FLAG_ADD_IF_NEW   0x10000000

Definition at line 68 of file http.c.

◆ HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA

#define HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA   0x40000000

Definition at line 69 of file http.c.

◆ HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON

#define HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON   0x01000000

Definition at line 70 of file http.c.

◆ HTTP_ADDHDR_FLAG_REPLACE

#define HTTP_ADDHDR_FLAG_REPLACE   0x80000000

Definition at line 71 of file http.c.

◆ HTTP_ADDHDR_FLAG_REQ

#define HTTP_ADDHDR_FLAG_REQ   0x02000000

Definition at line 72 of file http.c.

◆ NO_SHLWAPI_GDI

#define NO_SHLWAPI_GDI

Definition at line 52 of file http.c.

◆ NO_SHLWAPI_REG

#define NO_SHLWAPI_REG

Definition at line 51 of file http.c.

◆ NO_SHLWAPI_STREAM

#define NO_SHLWAPI_STREAM

Definition at line 50 of file http.c.

Typedef Documentation

◆ authorizationData

◆ basicAuthorizationData

Function Documentation

◆ async_read()

static DWORD async_read ( http_request_t req,
void buf,
DWORD  size,
DWORD  read_pos,
DWORD ret_read 
)
static

Definition at line 3157 of file http.c.

3158{
3159 read_file_task_t *task;
3160
3161 task = alloc_async_task(&req->hdr, async_read_file_proc, sizeof(*task));
3162 if(!task)
3163 return ERROR_OUTOFMEMORY;
3164
3165 task->buf = buf;
3166 task->size = size;
3167 task->read_pos = read_pos;
3168 task->ret_read = ret_read;
3169
3170 INTERNET_AsyncCall(&task->hdr);
3171 return ERROR_IO_PENDING;
3172}
#define ERROR_IO_PENDING
Definition: dderror.h:15
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
static void async_read_file_proc(task_header_t *hdr)
Definition: http.c:3117
DWORD INTERNET_AsyncCall(task_header_t *task)
Definition: internet.c:3915
void * alloc_async_task(object_header_t *hdr, async_task_proc_t proc, size_t size)
Definition: internet.c:3894
GLsizeiptr size
Definition: glext.h:5919
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
object_header_t hdr
Definition: internet.h:345
DWORD * ret_read
Definition: http.c:3114
DWORD size
Definition: http.c:3112
task_header_t hdr
Definition: http.c:3110
void * buf
Definition: http.c:3111
DWORD read_pos
Definition: http.c:3113

Referenced by HTTPREQ_QueryDataAvailable(), and HTTPREQ_ReadFile().

◆ async_read_file_proc()

static void async_read_file_proc ( task_header_t hdr)
static

Definition at line 3117 of file http.c.

3118{
3120 http_request_t *req = (http_request_t*)task->hdr.hdr;
3121 DWORD res = ERROR_SUCCESS, read = task->read_pos, complete_arg = 0;
3122
3123 TRACE("req %p buf %p size %u read_pos %u ret_read %p\n", req, task->buf, task->size, task->read_pos, task->ret_read);
3124
3125 if(task->buf) {
3127 while (read < task->size) {
3128 res = HTTPREQ_Read(req, (char*)task->buf + read, task->size - read, &read_bytes, TRUE);
3129 if (res != ERROR_SUCCESS || !read_bytes)
3130 break;
3131 read += read_bytes;
3132 }
3133 }else {
3135 res = refill_read_buffer(req, TRUE, &read);
3137
3138 if(task->ret_read)
3139 complete_arg = read; /* QueryDataAvailable reports read bytes in request complete notification */
3140 if(res != ERROR_SUCCESS || !read)
3142 }
3143
3144 TRACE("res %u read %u\n", res, read);
3145
3146 if(task->ret_read)
3147 *task->ret_read = read;
3148
3149 /* FIXME: We should report bytes transferred before decoding content. */
3151
3152 if(res != ERROR_SUCCESS)
3153 complete_arg = res;
3154 send_request_complete(req, res == ERROR_SUCCESS, complete_arg);
3155}
#define read
Definition: acwin.h:96
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static DWORD drain_content(http_request_t *, BOOL)
Definition: http.c:3091
static void http_release_netconn(http_request_t *req, BOOL reuse)
Definition: http.c:1895
static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *read, BOOL allow_blocking)
Definition: http.c:3053
static DWORD refill_read_buffer(http_request_t *req, BOOL allow_blocking, DWORD *read_bytes)
Definition: http.c:2657
static void send_request_complete(http_request_t *req, DWORD_PTR result, DWORD error)
Definition: http.c:3014
unsigned long DWORD
Definition: ntddk_ex.h:95
GLuint res
Definition: glext.h:9613
VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwInternetStatus, LPVOID lpvStatusInfo, DWORD dwStatusInfoLength) DECLSPEC_HIDDEN
char hdr[14]
Definition: iptest.cpp:33
static BOOL read_bytes(parse_buffer *buf, LPVOID data, DWORD size)
Definition: parsing.c:168
#define TRACE(s)
Definition: solgame.cpp:4
DWORD_PTR dwContext
Definition: internet.h:278
CRITICAL_SECTION read_section
Definition: internet.h:373
object_header_t * hdr
Definition: internet.h:390
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
#define INTERNET_STATUS_RESPONSE_RECEIVED
Definition: wininet.h:890

Referenced by async_read().

◆ AsyncHttpEndRequestProc()

static void AsyncHttpEndRequestProc ( task_header_t hdr)
static

Definition at line 5369 of file http.c.

5370{
5372 http_request_t *req = (http_request_t*)task->hdr.hdr;
5373
5374 TRACE("%p\n", req);
5375
5376 HTTP_HttpEndRequestW(req, task->flags, task->context);
5377}
static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_PTR dwContext)
Definition: http.c:5269
task_header_t hdr
Definition: http.c:5364

Referenced by HttpEndRequestW().

◆ AsyncHttpSendRequestProc()

static void AsyncHttpSendRequestProc ( task_header_t hdr)
static

Definition at line 5255 of file http.c.

5256{
5259
5260 TRACE("%p\n", request);
5261
5263 task->optional_len, task->content_len, task->end_request);
5264
5265 heap_free(task->headers);
5266}
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength, DWORD dwContentLength, BOOL bEndRequest)
Definition: http.c:4910
Definition: tftpd.h:86
DWORD content_len
Definition: http.c:5246
void * optional
Definition: http.c:5244
WCHAR * headers
Definition: http.c:5242
task_header_t hdr
Definition: http.c:5241
DWORD optional_len
Definition: http.c:5245
DWORD headers_len
Definition: http.c:5243

Referenced by HttpSendRequestExW(), and HttpSendRequestW().

◆ build_ascii_request()

static char * build_ascii_request ( const WCHAR str,
void data,
DWORD  data_len,
DWORD out_len 
)
static

Definition at line 4879 of file http.c.

4880{
4881 int len = WideCharToMultiByte( CP_ACP, 0, str, -1, NULL, 0, NULL, NULL );
4882 char *ret;
4883
4884 if (!(ret = heap_alloc( len + data_len ))) return NULL;
4885 WideCharToMultiByte( CP_ACP, 0, str, -1, ret, len, NULL, NULL );
4886 if (data_len) memcpy( ret + len - 1, data, data_len );
4887 *out_len = len + data_len - 1;
4888 ret[*out_len] = 0;
4889 return ret;
4890}
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
#define NULL
Definition: types.h:112
#define CP_ACP
Definition: compat.h:109
#define WideCharToMultiByte
Definition: compat.h:111
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLenum GLsizei len
Definition: glext.h:6722
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
const WCHAR * str
int ret

Referenced by HTTP_HttpSendRequestW().

◆ build_proxy_path_url()

static WCHAR * build_proxy_path_url ( http_request_t req)
static

Definition at line 1657 of file http.c.

1658{
1659 DWORD size, len;
1660 WCHAR *url;
1661
1663 size = len + lstrlenW(req->path) + 1;
1664 if(*req->path != '/')
1665 size++;
1666 url = heap_alloc(size * sizeof(WCHAR));
1667 if(!url)
1668 return NULL;
1669
1670 memcpy(url, req->server->scheme_host_port, len*sizeof(WCHAR));
1671 if(*req->path != '/')
1672 url[len++] = '/';
1673
1674 lstrcpyW(url+len, req->path);
1675
1676 TRACE("url=%s\n", debugstr_w(url));
1677 return url;
1678}
#define lstrcpyW
Definition: compat.h:749
#define lstrlenW
Definition: compat.h:750
#define debugstr_w
Definition: kernel32.h:32
static const WCHAR url[]
Definition: encode.c:1432
server_t * server
Definition: internet.h:347
LPWSTR path
Definition: internet.h:349
WCHAR * scheme_host_port
Definition: internet.h:43
__wchar_t WCHAR
Definition: xmlstorage.h:180

Referenced by HTTP_HttpSendRequestW().

◆ build_request_header()

static WCHAR * build_request_header ( http_request_t request,
const WCHAR verb,
const WCHAR path,
const WCHAR version,
BOOL  use_cr 
)
static

Definition at line 556 of file http.c.

558{
559 LPWSTR requestString;
560 DWORD len, n;
561 LPCWSTR *req;
562 UINT i;
563
564 EnterCriticalSection( &request->headers_section );
565
566 /* allocate space for an array of all the string pointers to be added */
567 len = request->nCustHeaders * 5 + 10;
568 if (!(req = heap_alloc( len * sizeof(const WCHAR *) )))
569 {
570 LeaveCriticalSection( &request->headers_section );
571 return NULL;
572 }
573
574 /* add the verb, path and HTTP version string */
575 n = 0;
576 req[n++] = verb;
577 req[n++] = L" ";
578 req[n++] = path;
579 req[n++] = L" ";
580 req[n++] = version;
581 if (use_cr)
582 req[n++] = L"\r";
583 req[n++] = L"\n";
584
585 /* Append custom request headers */
586 for (i = 0; i < request->nCustHeaders; i++)
587 {
588 if (request->custHeaders[i].wFlags & HDR_ISREQUEST)
589 {
590 req[n++] = request->custHeaders[i].lpszField;
591 req[n++] = L": ";
592 req[n++] = request->custHeaders[i].lpszValue;
593 if (use_cr)
594 req[n++] = L"\r";
595 req[n++] = L"\n";
596
597 TRACE("Adding custom header %s (%s)\n",
598 debugstr_w(request->custHeaders[i].lpszField),
599 debugstr_w(request->custHeaders[i].lpszValue));
600 }
601 }
602 if (use_cr)
603 req[n++] = L"\r";
604 req[n++] = L"\n";
605 req[n] = NULL;
606
607 requestString = HTTP_build_req( req, 4 );
608 heap_free( req );
609 LeaveCriticalSection( &request->headers_section );
610 return requestString;
611}
static const WCHAR version[]
Definition: asmname.c:66
static LPWSTR HTTP_build_req(LPCWSTR *list, int len)
Definition: http.c:4259
GLdouble n
Definition: glext.h:7729
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define HDR_ISREQUEST
Definition: internet.h:314
unsigned int UINT
Definition: ndis.h:50
#define L(x)
Definition: ntvdm.h:50
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by HTTP_HttpQueryInfoW(), and HTTP_HttpSendRequestW().

◆ build_response_header()

static WCHAR * build_response_header ( http_request_t request,
BOOL  use_cr 
)
static

Definition at line 613 of file http.c.

614{
615 const WCHAR **req;
616 WCHAR *ret, buf[14];
617 DWORD i, n = 0;
618
619 EnterCriticalSection( &request->headers_section );
620
621 if (!(req = heap_alloc( (request->nCustHeaders * 5 + 8) * sizeof(WCHAR *) )))
622 {
623 LeaveCriticalSection( &request->headers_section );
624 return NULL;
625 }
626
627 if (request->status_code)
628 {
629 req[n++] = request->version;
630 swprintf(buf, ARRAY_SIZE(buf), L" %u ", request->status_code);
631 req[n++] = buf;
632 req[n++] = request->statusText;
633 if (use_cr)
634 req[n++] = L"\r";
635 req[n++] = L"\n";
636 }
637
638 for(i = 0; i < request->nCustHeaders; i++)
639 {
640 if(!(request->custHeaders[i].wFlags & HDR_ISREQUEST)
641 && wcscmp(request->custHeaders[i].lpszField, L"Status"))
642 {
643 req[n++] = request->custHeaders[i].lpszField;
644 req[n++] = L": ";
645 req[n++] = request->custHeaders[i].lpszValue;
646 if(use_cr)
647 req[n++] = L"\r";
648 req[n++] = L"\n";
649
650 TRACE("Adding custom header %s (%s)\n",
651 debugstr_w(request->custHeaders[i].lpszField),
652 debugstr_w(request->custHeaders[i].lpszValue));
653 }
654 }
655 if(use_cr)
656 req[n++] = L"\r";
657 req[n++] = L"\n";
658 req[n] = NULL;
659
660 ret = HTTP_build_req(req, 0);
661 heap_free(req);
662 LeaveCriticalSection( &request->headers_section );
663 return ret;
664}
#define ARRAY_SIZE(A)
Definition: main.h:20
#define swprintf
Definition: precomp.h:40
_Check_return_ _CRTIMP int __cdecl wcscmp(_In_z_ const wchar_t *_Str1, _In_z_ const wchar_t *_Str2)
WCHAR * version

Referenced by commit_cache_entry(), and HTTP_HttpQueryInfoW().

◆ cache_authorization()

static void cache_authorization ( LPWSTR  host,
LPWSTR  scheme,
SEC_WINNT_AUTH_IDENTITY_W nt_auth_identity 
)
static

Definition at line 891 of file http.c.

893{
895 BOOL found = FALSE;
896
897 TRACE("Caching authorization for %s:%s\n", debugstr_w(host), debugstr_w(scheme));
898
901 if(!wcsicmp(host, ad->host) && !wcsicmp(scheme, ad->scheme)) {
902 found = TRUE;
903 break;
904 }
905
906 if(found) {
907 heap_free(ad->user);
908 heap_free(ad->password);
909 heap_free(ad->domain);
910 } else {
911 ad = heap_alloc(sizeof(authorizationData));
912 if(!ad) {
914 return;
915 }
916
917 ad->host = heap_strdupW(host);
920 }
921
922 ad->user = heap_strndupW(nt_auth_identity->User, nt_auth_identity->UserLength);
923 ad->password = heap_strndupW(nt_auth_identity->Password, nt_auth_identity->PasswordLength);
924 ad->domain = heap_strndupW(nt_auth_identity->Domain, nt_auth_identity->DomainLength);
925 ad->user_len = nt_auth_identity->UserLength;
926 ad->password_len = nt_auth_identity->PasswordLength;
927 ad->domain_len = nt_auth_identity->DomainLength;
928
929 if(!ad->host || !ad->scheme || !ad->user || !ad->password
930 || (nt_auth_identity->Domain && !ad->domain)) {
931 heap_free(ad->host);
932 heap_free(ad->scheme);
933 heap_free(ad->user);
934 heap_free(ad->password);
935 heap_free(ad->domain);
936 list_remove(&ad->entry);
937 heap_free(ad);
938 }
939
941}
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static WCHAR * heap_strndupW(const WCHAR *src, size_t length)
Definition: button.c:262
static WCHAR * heap_strdupW(const WCHAR *str)
Definition: edit.c:4312
#define wcsicmp
Definition: compat.h:15
static struct list authorizationCache
Definition: http.c:115
static CRITICAL_SECTION authcache_cs
Definition: http.c:117
unsigned int BOOL
Definition: ntddk_ex.h:94
uint32_t entry
Definition: isohybrid.c:63
DWORD scheme
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
unsigned short * Domain
Definition: rpcdce.h:225
unsigned short * User
Definition: rpcdce.h:223
unsigned short * Password
Definition: rpcdce.h:227
struct list entry
Definition: http.c:102
UINT domain_len
Definition: http.c:107
LPWSTR password
Definition: http.c:110
LPWSTR domain
Definition: http.c:106
LPWSTR host
Definition: http.c:104
LPWSTR scheme
Definition: http.c:105
LPWSTR user
Definition: http.c:108
UINT password_len
Definition: http.c:111
char * host
Definition: whois.c:55

Referenced by HTTP_DoAuthorization().

◆ cache_basic_authorization()

static void cache_basic_authorization ( LPWSTR  host,
LPWSTR  realm,
LPSTR  auth_data,
UINT  auth_data_len 
)
static

Definition at line 814 of file http.c.

815{
816 struct list *cursor;
818
819 TRACE("caching authorization for %s:%s = %s\n",debugstr_w(host),debugstr_w(realm),debugstr_an(auth_data,auth_data_len));
820
823 {
825 if (!wcsicmp(host,check->host) && !wcscmp(realm,check->realm))
826 {
827 ad = check;
828 break;
829 }
830 }
831
832 if (ad)
833 {
834 TRACE("Found match in cache, replacing\n");
836 ad->authorization = heap_alloc(auth_data_len);
837 memcpy(ad->authorization, auth_data, auth_data_len);
838 ad->authorizationLen = auth_data_len;
839 }
840 else
841 {
843 ad->host = heap_strdupW(host);
844 ad->realm = heap_strdupW(realm);
845 ad->authorization = heap_alloc(auth_data_len);
846 memcpy(ad->authorization, auth_data, auth_data_len);
847 ad->authorizationLen = auth_data_len;
849 TRACE("authorization cached\n");
850 }
852}
Definition: list.h:37
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
static struct list basicAuthorizationCache
Definition: http.c:114
#define check(expected, result)
Definition: dplayx.c:32
const char cursor[]
Definition: icontest.c:13
#define LIST_FOR_EACH(cursor, list)
Definition: list.h:188
struct list entry
Definition: http.c:92
#define LIST_ENTRY(type)
Definition: queue.h:175

Referenced by HTTP_DoAuthorization().

◆ chunked_destroy()

static void chunked_destroy ( data_stream_t stream)
static

Definition at line 2929 of file http.c.

2930{
2931 chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
2932 heap_free(chunked_stream);
2933}
Definition: parse.h:23

◆ chunked_drain_content()

static DWORD chunked_drain_content ( data_stream_t stream,
http_request_t req,
BOOL  allow_blocking 
)
static

Definition at line 2911 of file http.c.

2912{
2913 chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
2914 BYTE buf[1024];
2915 DWORD size, res;
2916
2917 while(chunked_stream->state != CHUNKED_STREAM_STATE_END_OF_STREAM
2918 && chunked_stream->state != CHUNKED_STREAM_STATE_ERROR) {
2919 res = chunked_read(stream, req, buf, sizeof(buf), &size, allow_blocking);
2920 if(res != ERROR_SUCCESS)
2921 return res;
2922 }
2923
2924 if(chunked_stream->state != CHUNKED_STREAM_STATE_END_OF_STREAM)
2925 return ERROR_NO_DATA;
2926 return ERROR_SUCCESS;
2927}
static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DWORD size, DWORD *read, BOOL allow_blocking)
Definition: http.c:2768
enum chunked_stream_t::@602 state
#define ERROR_NO_DATA
Definition: winerror.h:284
unsigned char BYTE
Definition: xxhash.c:193

◆ chunked_end_of_data()

static BOOL chunked_end_of_data ( data_stream_t stream,
http_request_t req 
)
static

Definition at line 2755 of file http.c.

2756{
2757 chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
2758 switch(chunked_stream->state) {
2759 case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
2760 case CHUNKED_STREAM_STATE_END_OF_STREAM:
2761 case CHUNKED_STREAM_STATE_ERROR:
2762 return TRUE;
2763 default:
2764 return FALSE;
2765 }
2766}

◆ chunked_read()

static DWORD chunked_read ( data_stream_t stream,
http_request_t req,
BYTE buf,
DWORD  size,
DWORD read,
BOOL  allow_blocking 
)
static

Definition at line 2768 of file http.c.

2770{
2771 chunked_stream_t *chunked_stream = (chunked_stream_t*)stream;
2772 DWORD ret_read = 0, res = ERROR_SUCCESS;
2773 BOOL continue_read = TRUE;
2774 int read_bytes;
2775 char ch;
2776
2777 do {
2778 TRACE("state %d\n", chunked_stream->state);
2779
2780 /* Ensure that we have data in the buffer for states that need it. */
2781 if(!chunked_stream->buf_size) {
2782 BOOL blocking_read = allow_blocking;
2783
2784 switch(chunked_stream->state) {
2785 case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
2786 case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE:
2787 /* never allow blocking after 0 chunk size */
2788 if(!chunked_stream->chunk_size)
2789 blocking_read = FALSE;
2790 /* fall through */
2791 case CHUNKED_STREAM_STATE_READING_CHUNK_SIZE:
2792 case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
2793 chunked_stream->buf_pos = 0;
2794 res = NETCON_recv(req->netconn, chunked_stream->buf, sizeof(chunked_stream->buf), blocking_read, &read_bytes);
2795 if(res == ERROR_SUCCESS && read_bytes) {
2796 chunked_stream->buf_size += read_bytes;
2797 }else if(res == WSAEWOULDBLOCK) {
2798 if(ret_read || allow_blocking)
2800 continue_read = FALSE;
2801 continue;
2802 }else {
2803 chunked_stream->state = CHUNKED_STREAM_STATE_ERROR;
2804 }
2805 break;
2806 default:
2807 break;
2808 }
2809 }
2810
2811 switch(chunked_stream->state) {
2812 case CHUNKED_STREAM_STATE_READING_CHUNK_SIZE:
2813 ch = next_chunked_data_char(chunked_stream);
2814
2815 if(ch >= '0' && ch <= '9') {
2816 chunked_stream->chunk_size = chunked_stream->chunk_size * 16 + ch - '0';
2817 }else if(ch >= 'a' && ch <= 'f') {
2818 chunked_stream->chunk_size = chunked_stream->chunk_size * 16 + ch - 'a' + 10;
2819 }else if (ch >= 'A' && ch <= 'F') {
2820 chunked_stream->chunk_size = chunked_stream->chunk_size * 16 + ch - 'A' + 10;
2821 }else if (ch == ';' || ch == '\r' || ch == '\n') {
2822 TRACE("reading %u byte chunk\n", chunked_stream->chunk_size);
2823 chunked_stream->buf_size++;
2824 chunked_stream->buf_pos--;
2825 if(req->contentLength == ~0) req->contentLength = chunked_stream->chunk_size;
2826 else req->contentLength += chunked_stream->chunk_size;
2827 chunked_stream->state = CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE;
2828 }
2829 break;
2830
2831 case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_SIZE:
2832 ch = next_chunked_data_char(chunked_stream);
2833 if(ch == '\n')
2834 chunked_stream->state = chunked_stream->chunk_size
2835 ? CHUNKED_STREAM_STATE_READING_CHUNK
2836 : CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END;
2837 else if(ch != '\r')
2838 WARN("unexpected char '%c'\n", ch);
2839 break;
2840
2841 case CHUNKED_STREAM_STATE_READING_CHUNK:
2842 assert(chunked_stream->chunk_size);
2843 if(!size) {
2844 continue_read = FALSE;
2845 break;
2846 }
2847 read_bytes = min(size, chunked_stream->chunk_size);
2848
2849 if(chunked_stream->buf_size) {
2850 if(read_bytes > chunked_stream->buf_size)
2851 read_bytes = chunked_stream->buf_size;
2852
2853 memcpy(buf+ret_read, chunked_stream->buf+chunked_stream->buf_pos, read_bytes);
2854 chunked_stream->buf_pos += read_bytes;
2855 chunked_stream->buf_size -= read_bytes;
2856 }else {
2857 res = NETCON_recv(req->netconn, (char*)buf+ret_read, read_bytes,
2858 allow_blocking, (int*)&read_bytes);
2859 if(res != ERROR_SUCCESS) {
2860 continue_read = FALSE;
2861 break;
2862 }
2863
2864 if(!read_bytes) {
2865 chunked_stream->state = CHUNKED_STREAM_STATE_ERROR;
2866 continue;
2867 }
2868 }
2869
2870 chunked_stream->chunk_size -= read_bytes;
2871 size -= read_bytes;
2872 ret_read += read_bytes;
2873 if(!chunked_stream->chunk_size)
2874 chunked_stream->state = CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA;
2875 allow_blocking = FALSE;
2876 break;
2877
2878 case CHUNKED_STREAM_STATE_DISCARD_EOL_AFTER_DATA:
2879 ch = next_chunked_data_char(chunked_stream);
2880 if(ch == '\n')
2881 chunked_stream->state = CHUNKED_STREAM_STATE_READING_CHUNK_SIZE;
2882 else if(ch != '\r')
2883 WARN("unexpected char '%c'\n", ch);
2884 break;
2885
2886 case CHUNKED_STREAM_STATE_DISCARD_EOL_AT_END:
2887 ch = next_chunked_data_char(chunked_stream);
2888 if(ch == '\n')
2889 chunked_stream->state = CHUNKED_STREAM_STATE_END_OF_STREAM;
2890 else if(ch != '\r')
2891 WARN("unexpected char '%c'\n", ch);
2892 break;
2893
2894 case CHUNKED_STREAM_STATE_END_OF_STREAM:
2895 case CHUNKED_STREAM_STATE_ERROR:
2896 continue_read = FALSE;
2897 break;
2898 }
2899 } while(continue_read);
2900
2901 if(ret_read)
2903 if(res != ERROR_SUCCESS)
2904 return res;
2905
2906 TRACE("read %d bytes\n", ret_read);
2907 *read = ret_read;
2908 return ERROR_SUCCESS;
2909}
#define WARN(fmt,...)
Definition: precomp.h:61
static char next_chunked_data_char(chunked_stream_t *stream)
Definition: http.c:2747
#define assert(x)
Definition: debug.h:53
DWORD NETCON_recv(netconn_t *, void *, size_t, BOOL, int *) DECLSPEC_HIDDEN
#define min(a, b)
Definition: monoChain.cc:55
DWORD buf_pos
Definition: http.c:328
DWORD buf_size
Definition: http.c:327
BYTE buf[READ_BUFFER_SIZE]
Definition: http.c:326
DWORD chunk_size
Definition: http.c:329
netconn_t * netconn
Definition: internet.h:351
ULONGLONG contentLength
Definition: internet.h:374
#define WSAEWOULDBLOCK
Definition: winerror.h:1948

Referenced by chunked_drain_content().

◆ collect_connections()

BOOL collect_connections ( collect_type_t  collect_type)

Definition at line 235 of file http.c.

236{
237 netconn_t *netconn, *netconn_safe;
238 server_t *server, *server_safe;
239 BOOL remaining = FALSE;
240 DWORD64 now;
241
242#ifdef __REACTOS__
243 now = GetTickCount();
244#else
246#endif
247
249 LIST_FOR_EACH_ENTRY_SAFE(netconn, netconn_safe, &server->conn_pool, netconn_t, pool_entry) {
250 if(collect_type > COLLECT_TIMEOUT || netconn->keep_until < now) {
251 TRACE("freeing %p\n", netconn);
252 list_remove(&netconn->pool_entry);
254 }else {
255 remaining = TRUE;
256 }
257 }
258
259 if(collect_type == COLLECT_CLEANUP) {
260 list_remove(&server->entry);
261 list_init(&server->entry);
263 }
264 }
265
266 return remaining;
267}
ULONGLONG WINAPI GetTickCount64(VOID)
Definition: GetTickCount64.c:9
static void list_init(struct list_entry *head)
Definition: list.h:51
DWORD WINAPI GetTickCount(VOID)
Definition: time.c:455
static struct list connection_pool
Definition: http.c:146
void server_release(server_t *server)
Definition: http.c:154
time_t now
Definition: finger.c:65
@ COLLECT_TIMEOUT
Definition: internet.h:60
@ COLLECT_CLEANUP
Definition: internet.h:62
void free_netconn(netconn_t *) DECLSPEC_HIDDEN
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
ULONGLONG keep_until
uint64_t DWORD64
Definition: typedefs.h:67
static rfbScreenInfoPtr server
Definition: vnc.c:74

Referenced by collect_connections_proc(), DllMain(), and INET_SetOption().

◆ collect_connections_proc()

static DWORD WINAPI collect_connections_proc ( void arg)
static

Definition at line 269 of file http.c.

270{
271 BOOL remaining_conns;
272
273 do {
274 /* FIXME: Use more sophisticated method */
275 Sleep(5000);
276
278
279 remaining_conns = collect_connections(COLLECT_TIMEOUT);
280 if(!remaining_conns)
282
284 }while(remaining_conns);
285
287}
VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
Definition: loader.c:507
BOOL collect_connections(collect_type_t collect_type)
Definition: http.c:235
static CRITICAL_SECTION connection_pool_cs
Definition: http.c:137
static BOOL collector_running
Definition: http.c:147
HMODULE WININET_hModule
Definition: internet.c:73
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790

Referenced by http_release_netconn().

◆ commit_cache_entry()

static void commit_cache_entry ( http_request_t req)
static

Definition at line 2426 of file http.c.

2427{
2428 WCHAR *header;
2429 DWORD header_len;
2430 BOOL res;
2431
2432 TRACE("%p\n", req);
2433
2434 CloseHandle(req->hCacheFile);
2435 req->hCacheFile = NULL;
2436
2438 header_len = (header ? lstrlenW(header) : 0);
2441 header, header_len, NULL, 0);
2442 if(res)
2443 req->req_file->is_committed = TRUE;
2444 else
2445 WARN("CommitUrlCacheEntry failed: %u\n", GetLastError());
2447}
#define CloseHandle
Definition: compat.h:739
static WCHAR * build_response_header(http_request_t *request, BOOL use_cr)
Definition: http.c:613
BOOL WINAPI CommitUrlCacheEntryW(LPCWSTR lpszUrlName, LPCWSTR lpszLocalFileName, FILETIME ExpireTime, FILETIME LastModifiedTime, DWORD CacheEntryType, LPWSTR lpHeaderInfo, DWORD dwHeaderSize, LPCWSTR lpszFileExtension, LPCWSTR lpszOriginalUrl)
Definition: urlcache.c:3085
FILETIME expires
Definition: internet.h:369
FILETIME last_modified
Definition: internet.h:366
HANDLE hCacheFile
Definition: internet.h:367
req_file_t * req_file
Definition: internet.h:368
WCHAR * file_name
Definition: internet.h:250
WCHAR * url
Definition: internet.h:251
BOOL is_committed
Definition: internet.h:252
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
#define NORMAL_CACHE_ENTRY
Definition: wininet.h:2087

Referenced by create_cache_entry(), and read_http_stream().

◆ compose_request_url()

static WCHAR * compose_request_url ( http_request_t req)
static

Definition at line 1815 of file http.c.

1816{
1817 const WCHAR *host, *scheme;
1818 WCHAR *buf, *ptr;
1819 size_t len;
1820
1821 host = req->server->canon_host_port;
1822
1823 if (req->server->is_https)
1824 scheme = L"https://";
1825 else
1826 scheme = L"http://";
1827
1828 len = lstrlenW(scheme) + lstrlenW(host) + (req->path[0] != '/' ? 1 : 0) + lstrlenW(req->path);
1829 ptr = buf = heap_alloc((len+1) * sizeof(WCHAR));
1830 if(buf) {
1832 ptr += lstrlenW(ptr);
1833
1834 lstrcpyW(ptr, host);
1835 ptr += lstrlenW(ptr);
1836
1837 if(req->path[0] != '/')
1838 *ptr++ = '/';
1839
1840 lstrcpyW(ptr, req->path);
1841 ptr += lstrlenW(ptr);
1842 *ptr = 0;
1843 }
1844
1845 return buf;
1846}
static PVOID ptr
Definition: dispmode.c:27
const WCHAR * canon_host_port
Definition: internet.h:45
BOOL is_https
Definition: internet.h:38

Referenced by create_cache_entry(), and HTTPREQ_QueryOption().

◆ convert_accept_types()

static WCHAR ** convert_accept_types ( const char **  accept_types)
static

Definition at line 1359 of file http.c.

1360{
1361 unsigned int count;
1362 const char **types = accept_types;
1363 WCHAR **typesW;
1364 BOOL invalid_pointer = FALSE;
1365
1366 if (!types) return NULL;
1367 count = 0;
1368 while (*types)
1369 {
1370 __TRY
1371 {
1372 /* find out how many there are */
1373 if (*types && **types)
1374 {
1375 TRACE("accept type: %s\n", debugstr_a(*types));
1376 count++;
1377 }
1378 }
1380 {
1381 WARN("invalid accept type pointer\n");
1382 invalid_pointer = TRUE;
1383 }
1384 __ENDTRY;
1385 types++;
1386 }
1387 if (invalid_pointer) return NULL;
1388 if (!(typesW = heap_alloc( sizeof(WCHAR *) * (count + 1) ))) return NULL;
1389 count = 0;
1390 types = accept_types;
1391 while (*types)
1392 {
1393 if (*types && **types) typesW[count++] = heap_strdupAtoW( *types );
1394 types++;
1395 }
1396 typesW[count] = NULL;
1397 return typesW;
1398}
static WCHAR * heap_strdupAtoW(const char *str)
Definition: appwiz.h:81
#define __TRY
Definition: compat.h:80
#define __ENDTRY
Definition: compat.h:82
#define __EXCEPT_PAGE_FAULT
Definition: compat.h:81
GLuint GLuint GLsizei count
Definition: gl.h:1545
#define debugstr_a
Definition: kernel32.h:31
Definition: cmds.c:130

Referenced by HttpOpenRequestA().

◆ create_cache_entry()

static void create_cache_entry ( http_request_t req)
static

Definition at line 2449 of file http.c.

2450{
2452 WCHAR *url;
2453 BOOL b = TRUE;
2454
2455 /* FIXME: We should free previous cache file earlier */
2456 if(req->req_file) {
2458 req->req_file = NULL;
2459 }
2460 if(req->hCacheFile) {
2461 CloseHandle(req->hCacheFile);
2462 req->hCacheFile = NULL;
2463 }
2464
2466 b = FALSE;
2467
2468 if(b) {
2469 int header_idx;
2470
2472
2473 header_idx = HTTP_GetCustomHeaderIndex(req, L"Cache-Control", 0, FALSE);
2474 if(header_idx != -1) {
2475 WCHAR *ptr;
2476
2477 for(ptr=req->custHeaders[header_idx].lpszValue; *ptr; ) {
2478 WCHAR *end;
2479
2480 while(*ptr==' ' || *ptr=='\t')
2481 ptr++;
2482
2483 end = wcschr(ptr, ',');
2484 if(!end)
2485 end = ptr + lstrlenW(ptr);
2486
2487 if(!wcsnicmp(ptr, L"no-cache", ARRAY_SIZE(L"no-cache")-1)
2488 || !wcsnicmp(ptr, L"no-store", ARRAY_SIZE(L"no-store")-1)) {
2489 b = FALSE;
2490 break;
2491 }
2492
2493 ptr = end;
2494 if(*ptr == ',')
2495 ptr++;
2496 }
2497 }
2498
2500 }
2501
2502 if(!b) {
2503 if(!(req->hdr.dwFlags & INTERNET_FLAG_NEED_FILE))
2504 return;
2505
2506 FIXME("INTERNET_FLAG_NEED_FILE is not supported correctly\n");
2507 }
2508
2509 url = compose_request_url(req);
2510 if(!url) {
2511 WARN("Could not get URL\n");
2512 return;
2513 }
2514
2515 b = CreateUrlCacheEntryW(url, req->contentLength == ~0 ? 0 : req->contentLength, NULL, file_name, 0);
2516 if(!b) {
2517 WARN("Could not create cache entry: %08x\n", GetLastError());
2518 return;
2519 }
2520
2522 req->req_file->url = url;
2523
2526 if(req->hCacheFile == INVALID_HANDLE_VALUE) {
2527 WARN("Could not create file: %u\n", GetLastError());
2528 req->hCacheFile = NULL;
2529 return;
2530 }
2531
2532 if(req->read_size) {
2533 DWORD written;
2534
2535 b = WriteFile(req->hCacheFile, req->read_buf+req->read_pos, req->read_size, &written, NULL);
2536 if(!b)
2537 FIXME("WriteFile failed: %u\n", GetLastError());
2538
2539 if(req->data_stream->vtbl->end_of_data(req->data_stream, req))
2540 commit_cache_entry(req);
2541 }
2542}
#define FIXME(fmt,...)
Definition: precomp.h:53
#define wcschr
Definition: compat.h:17
#define wcsnicmp
Definition: compat.h:14
#define INVALID_HANDLE_VALUE
Definition: compat.h:731
#define MAX_PATH
Definition: compat.h:34
#define CreateFileW
Definition: compat.h:741
#define FILE_ATTRIBUTE_NORMAL
Definition: compat.h:137
#define FILE_SHARE_READ
Definition: compat.h:136
BOOL WINAPI WriteFile(IN HANDLE hFile, IN LPCVOID lpBuffer, IN DWORD nNumberOfBytesToWrite OPTIONAL, OUT LPDWORD lpNumberOfBytesWritten, IN LPOVERLAPPED lpOverlapped OPTIONAL)
Definition: rw.c:24
static void commit_cache_entry(http_request_t *req)
Definition: http.c:2426
static INT HTTP_GetCustomHeaderIndex(http_request_t *req, LPCWSTR lpszField, INT index, BOOL Request)
static WCHAR * compose_request_url(http_request_t *req)
Definition: http.c:1815
DWORD create_req_file(const WCHAR *file_name, req_file_t **ret)
Definition: internet.c:3988
void req_file_release(req_file_t *req_file)
Definition: internet.c:4015
BOOL WINAPI CreateUrlCacheEntryW(LPCWSTR lpszUrlName, DWORD dwExpectedFileSize, LPCWSTR lpszFileExtension, LPWSTR lpszFileName, DWORD dwReserved)
Definition: urlcache.c:2815
GLuint GLuint end
Definition: gl.h:1545
GLboolean GLboolean GLboolean b
Definition: glext.h:6204
#define CREATE_ALWAYS
Definition: disk.h:72
static LPCWSTR file_name
Definition: protocol.c:147
#define FILE_SHARE_WRITE
Definition: nt_native.h:681
#define GENERIC_WRITE
Definition: nt_native.h:90
LPWSTR lpszValue
Definition: internet.h:321
const data_stream_vtbl_t * vtbl
Definition: internet.h:332
BOOL(* end_of_data)(data_stream_t *, http_request_t *)
Definition: http.c:317
data_stream_t * data_stream
Definition: internet.h:380
DWORD read_pos
Definition: internet.h:376
BYTE read_buf[READ_BUFFER_SIZE]
Definition: internet.h:378
CRITICAL_SECTION headers_section
Definition: internet.h:362
DWORD read_size
Definition: internet.h:377
HTTPHEADERW * custHeaders
Definition: internet.h:363
#define INTERNET_FLAG_NEED_FILE
Definition: wininet.h:88
#define INTERNET_FLAG_NO_CACHE_WRITE
Definition: wininet.h:66

Referenced by HTTP_HttpEndRequestW(), and HTTP_HttpSendRequestW().

◆ destroy_authinfo()

static void destroy_authinfo ( struct HttpAuthInfo authinfo)
static

Definition at line 763 of file http.c.

764{
765 if (!authinfo) return;
766
771
772 heap_free(authinfo->auth_data);
775}
#define SecIsValidHandle(x)
Definition: sspi.h:63
DWORD scheme
CredHandle cred
CtxtHandle ctx
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151

Referenced by HTTP_DoAuthorization(), HTTP_HttpSendRequestW(), and HTTPREQ_Destroy().

◆ destroy_data_stream()

static void destroy_data_stream ( data_stream_t stream)
inlinestatic

Definition at line 342 of file http.c.

343{
344 stream->vtbl->destroy(stream);
345}

Referenced by gzip_destroy(), HTTPREQ_Destroy(), and reset_data_stream().

◆ drain_content()

static DWORD drain_content ( http_request_t req,
BOOL  blocking 
)
static

Definition at line 3091 of file http.c.

3092{
3093 DWORD res;
3094
3095 TRACE("%p\n", req->netconn);
3096
3097 if(!is_valid_netconn(req->netconn))
3098 return ERROR_NO_DATA;
3099
3100 if(!wcscmp(req->verb, L"HEAD"))
3101 return ERROR_SUCCESS;
3102
3104 res = req->data_stream->vtbl->drain_content(req->data_stream, req, blocking);
3106 return res;
3107}
BOOL is_valid_netconn(netconn_t *) DECLSPEC_HIDDEN
DWORD(* drain_content)(data_stream_t *, http_request_t *, BOOL)
Definition: http.c:319
LPWSTR verb
Definition: internet.h:350

Referenced by async_read_file_proc(), HTTP_HttpEndRequestW(), HTTP_HttpSendRequestW(), HTTPREQ_CloseConnection(), HTTPREQ_Read(), and open_http_connection().

◆ encode_auth_data()

static WCHAR * encode_auth_data ( const WCHAR scheme,
const char data,
UINT  data_len 
)
static

Definition at line 1574 of file http.c.

1575{
1576 WCHAR *ret;
1577 UINT len, scheme_len = lstrlenW( scheme );
1578
1579 /* scheme + space + base64 encoded data (3/2/1 bytes data -> 4 bytes of characters) */
1580 len = scheme_len + 1 + ((data_len + 2) * 4) / 3;
1581 if (!(ret = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return NULL;
1582 memcpy( ret, scheme, scheme_len * sizeof(WCHAR) );
1583 ret[scheme_len] = ' ';
1584 HTTP_EncodeBase64( data, data_len, ret + scheme_len + 1 );
1585 return ret;
1586}
static UINT HTTP_EncodeBase64(LPCSTR bin, unsigned int len, LPWSTR base64)
Definition: http.c:1468

Referenced by HTTP_InsertAuthorization().

◆ end_of_read_data()

static BOOL end_of_read_data ( http_request_t req)
static

Definition at line 2625 of file http.c.

2626{
2627 return !req->read_size && req->data_stream->vtbl->end_of_data(req->data_stream, req);
2628}

Referenced by HTTPREQ_QueryDataAvailable(), and HTTPREQ_ReadFile().

◆ free_accept_types()

static void free_accept_types ( WCHAR **  accept_types)
static

Definition at line 1346 of file http.c.

1347{
1348 WCHAR *ptr, **types = accept_types;
1349
1350 if (!types) return;
1351 while ((ptr = *types))
1352 {
1353 heap_free( ptr );
1354 types++;
1355 }
1356 heap_free( accept_types );
1357}

Referenced by HttpOpenRequestA().

◆ free_authorization_cache()

void free_authorization_cache ( void  )

Definition at line 943 of file http.c.

944{
945 authorizationData *ad, *sa_safe;
946 basicAuthorizationData *basic, *basic_safe;
947
949
951 {
952 heap_free(basic->host);
953 heap_free(basic->realm);
954 heap_free(basic->authorization);
955
956 list_remove(&basic->entry);
957 heap_free(basic);
958 }
959
961 {
962 heap_free(ad->host);
963 heap_free(ad->scheme);
964 heap_free(ad->user);
965 heap_free(ad->password);
966 heap_free(ad->domain);
967 list_remove(&ad->entry);
968 heap_free(ad);
969 }
970
972}

Referenced by InternetSetOptionW().

◆ get_host_header()

static WCHAR * get_host_header ( http_request_t req)
static

Definition at line 304 of file http.c.

305{
307 WCHAR *ret = NULL;
308
310 if ((header = HTTP_GetHeader( req, L"Host" ))) ret = heap_strdupW( header->lpszValue );
311 else ret = heap_strdupW( req->server->canon_host_port );
313 return ret;
314}
static LPHTTPHEADERW HTTP_GetHeader(http_request_t *req, LPCWSTR head)
Definition: http.c:294

Referenced by HTTP_InsertAuthorization().

◆ get_redirect_url()

static WCHAR * get_redirect_url ( http_request_t request)
static

Definition at line 4076 of file http.c.

4077{
4078 static WCHAR szHttp[] = L"http";
4079 static WCHAR szHttps[] = L"https";
4080 http_session_t *session = request->session;
4081 URL_COMPONENTSW urlComponents = { sizeof(urlComponents) };
4082 WCHAR *orig_url = NULL, *redirect_url = NULL, *combined_url = NULL;
4083 DWORD url_length = 0, res;
4084 BOOL b;
4085
4086 url_length = 0;
4087 res = HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, redirect_url, &url_length, NULL);
4089 redirect_url = heap_alloc(url_length);
4090 res = HTTP_HttpQueryInfoW(request, HTTP_QUERY_LOCATION, redirect_url, &url_length, NULL);
4091 }
4092 if(res != ERROR_SUCCESS) {
4093 heap_free(redirect_url);
4094 return NULL;
4095 }
4096
4097 urlComponents.dwSchemeLength = 1;
4098 b = InternetCrackUrlW(redirect_url, url_length / sizeof(WCHAR), 0, &urlComponents);
4099 if(b && urlComponents.dwSchemeLength &&
4100 urlComponents.nScheme != INTERNET_SCHEME_HTTP && urlComponents.nScheme != INTERNET_SCHEME_HTTPS) {
4101 TRACE("redirect to non-http URL\n");
4102 return NULL;
4103 }
4104
4105 urlComponents.lpszScheme = (request->hdr.dwFlags & INTERNET_FLAG_SECURE) ? szHttps : szHttp;
4106 urlComponents.dwSchemeLength = 0;
4107 urlComponents.lpszHostName = request->server->name;
4108 urlComponents.nPort = request->server->port;
4109 urlComponents.lpszUserName = session->userName;
4110 urlComponents.lpszUrlPath = request->path;
4111
4112 b = InternetCreateUrlW(&urlComponents, 0, NULL, &url_length);
4114 orig_url = heap_alloc(url_length);
4115
4116 /* convert from bytes to characters */
4117 url_length = url_length / sizeof(WCHAR) - 1;
4118 b = InternetCreateUrlW(&urlComponents, 0, orig_url, &url_length);
4119 }
4120
4121 if(b) {
4122 url_length = 0;
4123 b = InternetCombineUrlW(orig_url, redirect_url, NULL, &url_length, ICU_ENCODE_SPACES_ONLY);
4125 combined_url = heap_alloc(url_length * sizeof(WCHAR));
4126 b = InternetCombineUrlW(orig_url, redirect_url, combined_url, &url_length, ICU_ENCODE_SPACES_ONLY);
4127 if(!b) {
4130 }
4131 }
4132 }
4133
4134 heap_free(orig_url);
4135 heap_free(redirect_url);
4136 return combined_url;
4137}
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
static DWORD HTTP_HttpQueryInfoW(http_request_t *, DWORD, LPVOID, LPDWORD, LPDWORD)
Definition: http.c:3592
BOOL WINAPI InternetCrackUrlW(const WCHAR *lpszUrl, DWORD dwUrlLength, DWORD dwFlags, URL_COMPONENTSW *lpUC)
Definition: internet.c:1625
BOOL WINAPI InternetCreateUrlW(LPURL_COMPONENTSW lpUrlComponents, DWORD dwFlags, LPWSTR lpszUrl, LPDWORD lpdwUrlLength)
Definition: internet.c:4425
BOOL WINAPI InternetCombineUrlW(LPCWSTR lpszBaseUrl, LPCWSTR lpszRelativeUrl, LPWSTR lpszBuffer, LPDWORD lpdwBufferLength, DWORD dwFlags)
Definition: internet.c:4147
#define b
Definition: ke_i.h:79
const char * combined_url
Definition: protocol.c:466
LPWSTR lpszHostName
Definition: wininet.h:215
INTERNET_SCHEME nScheme
Definition: wininet.h:214
LPWSTR lpszScheme
Definition: wininet.h:212
LPWSTR lpszUserName
Definition: wininet.h:218
LPWSTR lpszUrlPath
Definition: wininet.h:222
INTERNET_PORT nPort
Definition: wininet.h:217
DWORD dwSchemeLength
Definition: wininet.h:213
char path[256]
Definition: tftpd.h:94
struct object_header hdr
#define ICU_ENCODE_SPACES_ONLY
Definition: winhttp.h:293
#define INTERNET_SCHEME_HTTP
Definition: winhttp.h:42
#define INTERNET_SCHEME_HTTPS
Definition: winhttp.h:43
#define INTERNET_FLAG_SECURE
Definition: wininet.h:71
#define HTTP_QUERY_LOCATION
Definition: wininet.h:1556

Referenced by HTTP_HttpEndRequestW(), and HTTP_HttpSendRequestW().

◆ get_security_cert_struct()

static DWORD get_security_cert_struct ( http_request_t req,
INTERNET_CERTIFICATE_INFOA info 
)
static

Definition at line 2022 of file http.c.

2023{
2025 DWORD len;
2026
2028 if(!context)
2029 return ERROR_NOT_SUPPORTED;
2030
2031 memset(info, 0, sizeof(*info));
2032 info->ftExpiry = context->pCertInfo->NotAfter;
2033 info->ftStart = context->pCertInfo->NotBefore;
2034 len = CertNameToStrA(context->dwCertEncodingType,
2035 &context->pCertInfo->Subject, CERT_SIMPLE_NAME_STR|CERT_NAME_STR_CRLF_FLAG, NULL, 0);
2036 info->lpszSubjectInfo = LocalAlloc(0, len);
2037 if(info->lpszSubjectInfo)
2038 CertNameToStrA(context->dwCertEncodingType,
2040 info->lpszSubjectInfo, len);
2041 len = CertNameToStrA(context->dwCertEncodingType,
2042 &context->pCertInfo->Issuer, CERT_SIMPLE_NAME_STR|CERT_NAME_STR_CRLF_FLAG, NULL, 0);
2043 info->lpszIssuerInfo = LocalAlloc(0, len);
2044 if(info->lpszIssuerInfo)
2045 CertNameToStrA(context->dwCertEncodingType,
2047 info->lpszIssuerInfo, len);
2048 info->dwKeySize = NETCON_GetCipherStrength(req->netconn);
2049
2051 return ERROR_SUCCESS;
2052}
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
DWORD WINAPI CertNameToStrA(DWORD dwCertEncodingType, PCERT_NAME_BLOB pName, DWORD dwStrType, LPSTR psz, DWORD csz)
Definition: str.c:414
#define ERROR_NOT_SUPPORTED
Definition: compat.h:100
HLOCAL NTAPI LocalAlloc(UINT uFlags, SIZE_T dwBytes)
Definition: heapmem.c:1390
LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN
int NETCON_GetCipherStrength(netconn_t *) DECLSPEC_HIDDEN
#define memset(x, y, z)
Definition: compat.h:39
Definition: http.c:7252
#define CERT_SIMPLE_NAME_STR
Definition: wincrypt.h:3484
#define CERT_NAME_STR_CRLF_FLAG
Definition: wincrypt.h:3490
const CERT_CONTEXT * PCCERT_CONTEXT
Definition: wincrypt.h:485

Referenced by HTTPREQ_QueryOption().

◆ get_server()

server_t * get_server ( substr_t  name,
INTERNET_PORT  port,
BOOL  is_https,
BOOL  do_create 
)

Definition at line 198 of file http.c.

199{
200 server_t *iter, *server = NULL;
201
203
205 if(iter->port == port && name.len == lstrlenW(iter->name) && !wcsnicmp(iter->name, name.str, name.len)
206 && iter->is_https == is_https) {
207 server = iter;
209 break;
210 }
211 }
212
213 if(!server && do_create) {
214 server = heap_alloc_zero(sizeof(*server));
215 if(server) {
216 server->ref = 2; /* list reference and return */
217 server->port = port;
218 server->is_https = is_https;
219 list_init(&server->conn_pool);
220 server->name = heap_strndupW(name.str, name.len);
221 if(server->name && process_host_port(server)) {
223 }else {
225 server = NULL;
226 }
227 }
228 }
229
231
232 return server;
233}
USHORT port
Definition: uri.c:228
static BOOL process_host_port(server_t *server)
Definition: http.c:174
void server_addref(server_t *server)
Definition: http.c:149
Definition: name.c:39
WCHAR * name
Definition: internet.h:36
INTERNET_PORT port
Definition: internet.h:37

Referenced by HTTP_DealWithProxy(), HTTP_HandleRedirect(), and HTTP_HttpOpenRequestW().

◆ gzip_destroy()

static void gzip_destroy ( data_stream_t stream)
static

Definition at line 450 of file http.c.

451{
452 gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
453
455
456 if(!gzip_stream->end_of_data)
457 inflateEnd(&gzip_stream->zstream);
458 heap_free(gzip_stream);
459}
int inflateEnd(z_streamp strm)
Definition: inflate.c:1910
static void destroy_data_stream(data_stream_t *stream)
Definition: http.c:342
z_stream zstream
Definition: http.c:367
BOOL end_of_data
Definition: http.c:371
data_stream_t * parent_stream
Definition: http.c:366

◆ gzip_drain_content()

static DWORD gzip_drain_content ( data_stream_t stream,
http_request_t req,
BOOL  allow_blocking 
)
static

Definition at line 444 of file http.c.

445{
446 gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
447 return gzip_stream->parent_stream->vtbl->drain_content(gzip_stream->parent_stream, req, allow_blocking);
448}

◆ gzip_end_of_data()

static BOOL gzip_end_of_data ( data_stream_t stream,
http_request_t req 
)
static

Definition at line 374 of file http.c.

375{
376 gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
377 return gzip_stream->end_of_data
378 || (!gzip_stream->buf_size && gzip_stream->parent_stream->vtbl->end_of_data(gzip_stream->parent_stream, req));
379}
DWORD buf_size
Definition: http.c:369

◆ gzip_read()

static DWORD gzip_read ( data_stream_t stream,
http_request_t req,
BYTE buf,
DWORD  size,
DWORD read,
BOOL  allow_blocking 
)
static

Definition at line 381 of file http.c.

383{
384 gzip_stream_t *gzip_stream = (gzip_stream_t*)stream;
385 z_stream *zstream = &gzip_stream->zstream;
386 DWORD current_read, ret_read = 0;
387 int zres;
389
390 TRACE("(%d %x)\n", size, allow_blocking);
391
392 while(size && !gzip_stream->end_of_data) {
393 if(!gzip_stream->buf_size) {
394 if(gzip_stream->buf_pos) {
395 if(gzip_stream->buf_size)
396 memmove(gzip_stream->buf, gzip_stream->buf+gzip_stream->buf_pos, gzip_stream->buf_size);
397 gzip_stream->buf_pos = 0;
398 }
399 res = gzip_stream->parent_stream->vtbl->read(gzip_stream->parent_stream, req, gzip_stream->buf+gzip_stream->buf_size,
400 sizeof(gzip_stream->buf)-gzip_stream->buf_size, &current_read, allow_blocking);
401 if(res != ERROR_SUCCESS)
402 break;
403
404 gzip_stream->buf_size += current_read;
405 if(!current_read) {
406 WARN("unexpected end of data\n");
407 gzip_stream->end_of_data = TRUE;
408 break;
409 }
410 }
411
412 zstream->next_in = gzip_stream->buf+gzip_stream->buf_pos;
413 zstream->avail_in = gzip_stream->buf_size;
414 zstream->next_out = buf+ret_read;
415 zstream->avail_out = size;
416 zres = inflate(&gzip_stream->zstream, 0);
417 current_read = size - zstream->avail_out;
418 size -= current_read;
419 ret_read += current_read;
420 gzip_stream->buf_size -= zstream->next_in - (gzip_stream->buf+gzip_stream->buf_pos);
421 gzip_stream->buf_pos = zstream->next_in-gzip_stream->buf;
422 if(zres == Z_STREAM_END) {
423 TRACE("end of data\n");
424 gzip_stream->end_of_data = TRUE;
425 inflateEnd(zstream);
426 }else if(zres != Z_OK) {
427 WARN("inflate failed %d: %s\n", zres, debugstr_a(zstream->msg));
428 if(!ret_read)
430 break;
431 }
432
433 if(ret_read)
434 allow_blocking = FALSE;
435 }
436
437 TRACE("read %u bytes\n", ret_read);
438 if(ret_read)
440 *read = ret_read;
441 return res;
442}
int inflate(z_streamp strm, int flush)
Definition: inflate.c:1257
#define Z_STREAM_END
Definition: zlib.h:115
#define Z_OK
Definition: zlib.h:114
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
DWORD(* read)(data_stream_t *, http_request_t *, BYTE *, DWORD, DWORD *, BOOL)
Definition: http.c:318
DWORD buf_pos
Definition: http.c:370
BYTE buf[READ_BUFFER_SIZE]
Definition: http.c:368
uInt avail_in
Definition: zlib.h:60
z_const Bytef * next_in
Definition: zlib.h:59
uInt avail_out
Definition: zlib.h:64
Bytef * next_out
Definition: zlib.h:63
z_const char * msg
Definition: zlib.h:67
#define ERROR_INTERNET_DECODING_FAILED
Definition: wininet.h:2083

◆ HTTP_build_req()

static LPWSTR HTTP_build_req ( LPCWSTR list,
int  len 
)
static

Definition at line 4259 of file http.c.

4260{
4261 LPCWSTR *t;
4262 LPWSTR str;
4263
4264 for( t = list; *t ; t++ )
4265 len += lstrlenW( *t );
4266 len++;
4267
4268 str = heap_alloc(len*sizeof(WCHAR));
4269 *str = 0;
4270
4271 for( t = list; *t ; t++ )
4272 lstrcatW( str, *t );
4273
4274 return str;
4275}
GLdouble GLdouble t
Definition: gl.h:2047
LPWSTR WINAPI lstrcatW(LPWSTR lpString1, LPCWSTR lpString2)
Definition: lstring.c:274

Referenced by build_request_header(), and build_response_header().

◆ HTTP_clear_response_headers()

static void HTTP_clear_response_headers ( http_request_t request)
static

Definition at line 5901 of file http.c.

5902{
5903 DWORD i;
5904
5905 EnterCriticalSection( &request->headers_section );
5906
5907 for( i=0; i<request->nCustHeaders; i++)
5908 {
5909 if( !request->custHeaders[i].lpszField )
5910 continue;
5911 if( !request->custHeaders[i].lpszValue )
5912 continue;
5913 if ( request->custHeaders[i].wFlags & HDR_ISREQUEST )
5914 continue;
5916 i--;
5917 }
5918
5919 LeaveCriticalSection( &request->headers_section );
5920}
static BOOL HTTP_DeleteCustomHeader(http_request_t *req, DWORD index)
Definition: http.c:6322

Referenced by HTTP_GetResponseHeaders().

◆ HTTP_Connect()

DWORD HTTP_Connect ( appinfo_t hIC,
LPCWSTR  lpszServerName,
INTERNET_PORT  serverPort,
LPCWSTR  lpszUserName,
LPCWSTR  lpszPassword,
DWORD  dwFlags,
DWORD_PTR  dwContext,
DWORD  dwInternalFlags,
HINTERNET ret 
)

Definition at line 5836 of file http.c.

5840{
5842
5843 TRACE("-->\n");
5844
5845 if (!lpszServerName || !lpszServerName[0])
5847
5848 assert( hIC->hdr.htype == WH_HINIT );
5849
5851 if (!session)
5852 return ERROR_OUTOFMEMORY;
5853
5854 /*
5855 * According to my tests. The name is not resolved until a request is sent
5856 */
5857
5858 session->hdr.htype = WH_HHTTPSESSION;
5859 session->hdr.dwFlags = dwFlags;
5860 session->hdr.dwContext = dwContext;
5861 session->hdr.dwInternalFlags |= dwInternalFlags;
5862 session->hdr.decoding = hIC->hdr.decoding;
5863
5864 WININET_AddRef( &hIC->hdr );
5865 session->appInfo = hIC;
5866 list_add_head( &hIC->hdr.children, &session->hdr.entry );
5867
5868 session->hostName = heap_strdupW(lpszServerName);
5869 if (lpszUserName && lpszUserName[0])
5870 session->userName = heap_strdupW(lpszUserName);
5871 session->password = heap_strdupW(lpszPassword);
5872 session->hostPort = serverPort;
5874 session->send_timeout = 0;
5876
5877 /* Don't send a handle created callback if this handle was created with InternetOpenUrl */
5878 if (!(session->hdr.dwInternalFlags & INET_OPENURL))
5879 {
5880 INTERNET_SendCallback(&hIC->hdr, dwContext,
5882 sizeof(HINTERNET));
5883 }
5884
5885/*
5886 * an INTERNET_STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on
5887 * windows
5888 */
5889
5890 TRACE("%p --> %p\n", hIC, session);
5891
5892 *ret = session->hdr.hInternet;
5893 return ERROR_SUCCESS;
5894}
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
static const object_vtbl_t HTTPSESSIONVtbl
Definition: http.c:5814
object_header_t * WININET_AddRef(object_header_t *info)
Definition: internet.c:169
void * alloc_object(object_header_t *parent, const object_vtbl_t *vtbl, size_t size)
Definition: internet.c:103
#define INET_OPENURL
Definition: internet.h:243
@ WH_HHTTPSESSION
Definition: internet.h:237
@ WH_HINIT
Definition: internet.h:234
WH_TYPE htype
Definition: internet.h:273
struct list children
Definition: internet.h:286
DWORD connect_timeout
Definition: internet.h:298
object_header_t hdr
Definition: internet.h:291
int receive_timeout
struct object_header hdr
int send_timeout
int connect_timeout
_In_opt_ LPSTR _In_opt_ LPSTR lpszPassword
Definition: winbase.h:2737
_In_ PCCERT_CONTEXT _In_ DWORD dwFlags
Definition: wincrypt.h:1176
#define INTERNET_STATUS_HANDLE_CREATED
Definition: wininet.h:895

Referenced by INTERNET_InternetOpenUrlW(), and InternetConnectW().

◆ HTTP_DealWithProxy()

static BOOL HTTP_DealWithProxy ( appinfo_t hIC,
http_session_t session,
http_request_t request 
)
static

Definition at line 1748 of file http.c.

1749{
1750 static WCHAR szNul[] = L"";
1751 URL_COMPONENTSW UrlComponents = { sizeof(UrlComponents) };
1752 server_t *new_server = NULL;
1753 WCHAR *proxy;
1754
1756 if(!proxy)
1757 return FALSE;
1759 proxy, lstrlenW(L"http://"), L"http://", lstrlenW(L"http://"))) {
1760 WCHAR *proxy_url = heap_alloc(lstrlenW(proxy)*sizeof(WCHAR) + sizeof(L"http://"));
1761 if(!proxy_url) {
1763 return FALSE;
1764 }
1765 lstrcpyW(proxy_url, L"http://");
1766 lstrcatW(proxy_url, proxy);
1768 proxy = proxy_url;
1769 }
1770
1771 UrlComponents.dwHostNameLength = 1;
1772 if(InternetCrackUrlW(proxy, 0, 0, &UrlComponents) && UrlComponents.dwHostNameLength) {
1773 if( !request->path )
1774 request->path = szNul;
1775
1776 new_server = get_server(substr(UrlComponents.lpszHostName, UrlComponents.dwHostNameLength),
1777 UrlComponents.nPort, UrlComponents.nScheme == INTERNET_SCHEME_HTTPS, TRUE);
1778 }
1780 if(!new_server)
1781 return FALSE;
1782
1783 request->proxy = new_server;
1784
1785 TRACE("proxy server=%s port=%d\n", debugstr_w(new_server->name), new_server->port);
1786 return TRUE;
1787}
INT WINAPI CompareStringW(LCID lcid, DWORD flags, LPCWSTR str1, INT len1, LPCWSTR str2, INT len2)
Definition: locale.c:4014
server_t * get_server(substr_t name, INTERNET_PORT port, BOOL is_https, BOOL do_create)
Definition: http.c:198
WCHAR * INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto)
Definition: internet.c:384
int proxy
Definition: main.c:67
static substr_t substr(const WCHAR *str, size_t len)
Definition: internet.h:203
#define LOCALE_SYSTEM_DEFAULT
DWORD dwHostNameLength
Definition: wininet.h:216
LPWSTR proxy
Definition: internet.h:293
#define NORM_IGNORECASE
Definition: winnls.h:178
#define CSTR_EQUAL
Definition: winnls.h:458

Referenced by HTTP_HttpOpenRequestW().

◆ HTTP_DecodeBase64()

static UINT HTTP_DecodeBase64 ( LPCWSTR  base64,
LPSTR  bin 
)
static

Definition at line 1524 of file http.c.

1525{
1526 unsigned int n = 0;
1527
1528 while(*base64)
1529 {
1530 signed char in[4];
1531
1532 if (base64[0] >= ARRAY_SIZE(HTTP_Base64Dec) ||
1533 ((in[0] = HTTP_Base64Dec[base64[0]]) == -1) ||
1534 base64[1] >= ARRAY_SIZE(HTTP_Base64Dec) ||
1535 ((in[1] = HTTP_Base64Dec[base64[1]]) == -1))
1536 {
1537 WARN("invalid base64: %s\n", debugstr_w(base64));
1538 return 0;
1539 }
1540 if (bin)
1541 bin[n] = (unsigned char) (in[0] << 2 | in[1] >> 4);
1542 n++;
1543
1544 if ((base64[2] == '=') && (base64[3] == '='))
1545 break;
1546 if (base64[2] > ARRAY_SIZE(HTTP_Base64Dec) ||
1547 ((in[2] = HTTP_Base64Dec[base64[2]]) == -1))
1548 {
1549 WARN("invalid base64: %s\n", debugstr_w(&base64[2]));
1550 return 0;
1551 }
1552 if (bin)
1553 bin[n] = (unsigned char) (in[1] << 4 | in[2] >> 2);
1554 n++;
1555
1556 if (base64[3] == '=')
1557 break;
1558 if (base64[3] > ARRAY_SIZE(HTTP_Base64Dec) ||
1559 ((in[3] = HTTP_Base64Dec[base64[3]]) == -1))
1560 {
1561 WARN("invalid base64: %s\n", debugstr_w(&base64[3]));
1562 return 0;
1563 }
1564 if (bin)
1565 bin[n] = (unsigned char) (((in[2] << 6) & 0xc0) | in[3]);
1566 n++;
1567
1568 base64 += 4;
1569 }
1570
1571 return n;
1572}
unsigned char
Definition: typeof.h:29
static const signed char HTTP_Base64Dec[]
Definition: http.c:1509
GLuint in
Definition: glext.h:9616
static struct _PeImage bin

Referenced by HTTP_DoAuthorization().

◆ HTTP_DeleteCustomHeader()

static BOOL HTTP_DeleteCustomHeader ( http_request_t req,
DWORD  index 
)
static

Definition at line 6322 of file http.c.

6323{
6324 if( request->nCustHeaders <= 0 )
6325 return FALSE;
6326 if( index >= request->nCustHeaders )
6327 return FALSE;
6328 request->nCustHeaders--;
6329
6330 heap_free(request->custHeaders[index].lpszField);
6331 heap_free(request->custHeaders[index].lpszValue);
6332
6333 memmove( &request->custHeaders[index], &request->custHeaders[index+1],
6334 (request->nCustHeaders - index)* sizeof(HTTPHEADERW) );
6335 memset( &request->custHeaders[request->nCustHeaders], 0, sizeof(HTTPHEADERW) );
6336
6337 return TRUE;
6338}
GLuint index
Definition: glext.h:6031

Referenced by HTTP_clear_response_headers(), HTTP_ProcessHeader(), remove_header(), and set_content_length().

◆ HTTP_DoAuthorization()

static BOOL HTTP_DoAuthorization ( http_request_t request,
LPCWSTR  pszAuthValue,
struct HttpAuthInfo **  ppAuthInfo,
LPWSTR  domain_and_username,
LPWSTR  password,
LPWSTR  host 
)
static

Definition at line 974 of file http.c.

978{
979 SECURITY_STATUS sec_status;
980 struct HttpAuthInfo *pAuthInfo = *ppAuthInfo;
981 BOOL first = FALSE;
982 LPWSTR szRealm = NULL;
983
984 TRACE("%s\n", debugstr_w(pszAuthValue));
985
986 if (!pAuthInfo)
987 {
989
990 first = TRUE;
991 pAuthInfo = heap_alloc(sizeof(*pAuthInfo));
992 if (!pAuthInfo)
993 return FALSE;
994
995 SecInvalidateHandle(&pAuthInfo->cred);
996 SecInvalidateHandle(&pAuthInfo->ctx);
997 memset(&pAuthInfo->exp, 0, sizeof(pAuthInfo->exp));
998 pAuthInfo->attr = 0;
999 pAuthInfo->auth_data = NULL;
1000 pAuthInfo->auth_data_len = 0;
1001 pAuthInfo->finished = FALSE;
1002
1003 if (is_basic_auth_value(pszAuthValue,NULL))
1004 {
1005 pAuthInfo->scheme = heap_strdupW(L"Basic");
1006 if (!pAuthInfo->scheme)
1007 {
1008 heap_free(pAuthInfo);
1009 return FALSE;
1010 }
1011 }
1012 else
1013 {
1014 PVOID pAuthData;
1015 SEC_WINNT_AUTH_IDENTITY_W nt_auth_identity;
1016
1017 pAuthInfo->scheme = heap_strdupW(pszAuthValue);
1018 if (!pAuthInfo->scheme)
1019 {
1020 heap_free(pAuthInfo);
1021 return FALSE;
1022 }
1023
1024 if (domain_and_username)
1025 {
1026 WCHAR *user = wcschr(domain_and_username, '\\');
1027 WCHAR *domain = domain_and_username;
1028
1029 /* FIXME: make sure scheme accepts SEC_WINNT_AUTH_IDENTITY before calling AcquireCredentialsHandle */
1030
1031 pAuthData = &nt_auth_identity;
1032
1033 if (user) user++;
1034 else
1035 {
1036 user = domain_and_username;
1037 domain = NULL;
1038 }
1039
1040 nt_auth_identity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
1041 nt_auth_identity.User = user;
1042 nt_auth_identity.UserLength = lstrlenW(nt_auth_identity.User);
1043 nt_auth_identity.Domain = domain;
1044 nt_auth_identity.DomainLength = domain ? user - domain - 1 : 0;
1045 nt_auth_identity.Password = password;
1046 nt_auth_identity.PasswordLength = lstrlenW(nt_auth_identity.Password);
1047
1048 cache_authorization(host, pAuthInfo->scheme, &nt_auth_identity);
1049 }
1050 else if(retrieve_cached_authorization(host, pAuthInfo->scheme, &nt_auth_identity))
1051 pAuthData = &nt_auth_identity;
1052 else
1053 /* use default credentials */
1054 pAuthData = NULL;
1055
1056 sec_status = AcquireCredentialsHandleW(NULL, pAuthInfo->scheme,
1058 pAuthData, NULL,
1059 NULL, &pAuthInfo->cred,
1060 &exp);
1061
1062 if(pAuthData && !domain_and_username) {
1063 heap_free(nt_auth_identity.User);
1064 heap_free(nt_auth_identity.Domain);
1065 heap_free(nt_auth_identity.Password);
1066 }
1067
1068 if (sec_status == SEC_E_OK)
1069 {
1070 PSecPkgInfoW sec_pkg_info;
1071 sec_status = QuerySecurityPackageInfoW(pAuthInfo->scheme, &sec_pkg_info);
1072 if (sec_status == SEC_E_OK)
1073 {
1074 pAuthInfo->max_token = sec_pkg_info->cbMaxToken;
1075 FreeContextBuffer(sec_pkg_info);
1076 }
1077 }
1078 if (sec_status != SEC_E_OK)
1079 {
1080 WARN("AcquireCredentialsHandleW for scheme %s failed with error 0x%08x\n",
1081 debugstr_w(pAuthInfo->scheme), sec_status);
1082 heap_free(pAuthInfo->scheme);
1083 heap_free(pAuthInfo);
1084 return FALSE;
1085 }
1086 }
1087 *ppAuthInfo = pAuthInfo;
1088 }
1089 else if (pAuthInfo->finished)
1090 return FALSE;
1091
1092 if ((lstrlenW(pszAuthValue) < lstrlenW(pAuthInfo->scheme)) ||
1093 wcsnicmp(pszAuthValue, pAuthInfo->scheme, lstrlenW(pAuthInfo->scheme)))
1094 {
1095 ERR("authentication scheme changed from %s to %s\n",
1096 debugstr_w(pAuthInfo->scheme), debugstr_w(pszAuthValue));
1097 return FALSE;
1098 }
1099
1100 if (is_basic_auth_value(pszAuthValue,&szRealm))
1101 {
1102 int userlen;
1103 int passlen;
1104 char *auth_data = NULL;
1105 UINT auth_data_len = 0;
1106
1107 TRACE("basic authentication realm %s\n",debugstr_w(szRealm));
1108
1109 if (!domain_and_username)
1110 {
1111 if (host && szRealm)
1113 if (auth_data_len == 0)
1114 {
1115 heap_free(szRealm);
1116 return FALSE;
1117 }
1118 }
1119 else
1120 {
1121 userlen = WideCharToMultiByte(CP_UTF8, 0, domain_and_username, lstrlenW(domain_and_username), NULL, 0, NULL, NULL);
1123
1124 /* length includes a nul terminator, which will be re-used for the ':' */
1125 auth_data = heap_alloc(userlen + 1 + passlen);
1126 if (!auth_data)
1127 {
1128 heap_free(szRealm);
1129 return FALSE;
1130 }
1131
1132 WideCharToMultiByte(CP_UTF8, 0, domain_and_username, -1, auth_data, userlen, NULL, NULL);
1133 auth_data[userlen] = ':';
1134 WideCharToMultiByte(CP_UTF8, 0, password, -1, &auth_data[userlen+1], passlen, NULL, NULL);
1135 auth_data_len = userlen + 1 + passlen;
1136 if (host && szRealm)
1138 }
1139
1140 pAuthInfo->auth_data = auth_data;
1141 pAuthInfo->auth_data_len = auth_data_len;
1142 pAuthInfo->finished = TRUE;
1143 heap_free(szRealm);
1144 return TRUE;
1145 }
1146 else
1147 {
1148 LPCWSTR pszAuthData;
1149 SecBufferDesc out_desc, in_desc;
1150 SecBuffer out, in;
1151 unsigned char *buffer;
1154
1155 in.BufferType = SECBUFFER_TOKEN;
1156 in.cbBuffer = 0;
1157 in.pvBuffer = NULL;
1158
1159 in_desc.ulVersion = 0;
1160 in_desc.cBuffers = 1;
1161 in_desc.pBuffers = &in;
1162
1163 pszAuthData = pszAuthValue + lstrlenW(pAuthInfo->scheme);
1164 if (*pszAuthData == ' ')
1165 {
1166 pszAuthData++;
1167 in.cbBuffer = HTTP_DecodeBase64(pszAuthData, NULL);
1168 in.pvBuffer = heap_alloc(in.cbBuffer);
1169 HTTP_DecodeBase64(pszAuthData, in.pvBuffer);
1170 }
1171
1172 buffer = heap_alloc(pAuthInfo->max_token);
1173
1174 out.BufferType = SECBUFFER_TOKEN;
1175 out.cbBuffer = pAuthInfo->max_token;
1176 out.pvBuffer = buffer;
1177
1178 out_desc.ulVersion = 0;
1179 out_desc.cBuffers = 1;
1180 out_desc.pBuffers = &out;
1181
1182 sec_status = InitializeSecurityContextW(first ? &pAuthInfo->cred : NULL,
1183 first ? NULL : &pAuthInfo->ctx,
1184 first ? request->server->name : NULL,
1185 context_req, 0, SECURITY_NETWORK_DREP,
1186 in.pvBuffer ? &in_desc : NULL,
1187 0, &pAuthInfo->ctx, &out_desc,
1188 &pAuthInfo->attr, &pAuthInfo->exp);
1189 if (sec_status == SEC_E_OK)
1190 {
1191 pAuthInfo->finished = TRUE;
1192 pAuthInfo->auth_data = out.pvBuffer;
1193 pAuthInfo->auth_data_len = out.cbBuffer;
1194 TRACE("sending last auth packet\n");
1195 }
1196 else if (sec_status == SEC_I_CONTINUE_NEEDED)
1197 {
1198 pAuthInfo->auth_data = out.pvBuffer;
1199 pAuthInfo->auth_data_len = out.cbBuffer;
1200 TRACE("sending next auth packet\n");
1201 }
1202 else
1203 {
1204 ERR("InitializeSecurityContextW returned error 0x%08x\n", sec_status);
1205 heap_free(out.pvBuffer);
1206 destroy_authinfo(pAuthInfo);
1207 *ppAuthInfo = NULL;
1208 return FALSE;
1209 }
1210 }
1211
1212 return TRUE;
1213}
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define ERR(fmt,...)
Definition: precomp.h:57
static BOOL retrieve_cached_authorization(LPWSTR host, LPWSTR scheme, SEC_WINNT_AUTH_IDENTITY_W *nt_auth_identity)
Definition: http.c:854
static BOOL is_basic_auth_value(LPCWSTR pszAuthValue, LPWSTR *pszRealm)
Definition: http.c:727
static void destroy_authinfo(struct HttpAuthInfo *authinfo)
Definition: http.c:763
static void cache_authorization(LPWSTR host, LPWSTR scheme, SEC_WINNT_AUTH_IDENTITY_W *nt_auth_identity)
Definition: http.c:891
static void cache_basic_authorization(LPWSTR host, LPWSTR realm, LPSTR auth_data, UINT auth_data_len)
Definition: http.c:814
static UINT retrieve_cached_basic_authorization(http_request_t *req, const WCHAR *host, const WCHAR *realm, char **auth_data)
Definition: http.c:777
static UINT HTTP_DecodeBase64(LPCWSTR base64, LPSTR bin)
Definition: http.c:1524
GLuint buffer
Definition: glext.h:5915
const GLint * first
Definition: glext.h:5794
DWORD exp
Definition: msg.c:16058
static WCHAR password[]
Definition: url.c:33
LONG SECURITY_STATUS
Definition: sspi.h:34
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:291
#define SECBUFFER_TOKEN
Definition: sspi.h:161
#define SECURITY_NETWORK_DREP
Definition: sspi.h:474
#define ISC_REQ_DELEGATE
Definition: sspi.h:362
#define ISC_REQ_MUTUAL_AUTH
Definition: sspi.h:363
#define SecInvalidateHandle(x)
Definition: sspi.h:58
#define ISC_REQ_CONNECTION
Definition: sspi.h:373
#define ISC_REQ_USE_DCE_STYLE
Definition: sspi.h:371
static FILE * out
Definition: regtests2xml.c:44
#define SEC_WINNT_AUTH_IDENTITY_UNICODE
Definition: rpcdce.h:310
#define CP_UTF8
Definition: nls.h:20
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
ULONG max_token
Definition: http.c:83
void * auth_data
Definition: http.c:84
TimeStamp exp
Definition: http.c:81
ULONG attr
Definition: http.c:82
unsigned int auth_data_len
Definition: http.c:85
LPWSTR scheme
Definition: http.c:78
CtxtHandle ctx
Definition: http.c:80
BOOL finished
Definition: http.c:86
CredHandle cred
Definition: http.c:79
ULONG cBuffers
Definition: sspi.h:182
ULONG ulVersion
Definition: sspi.h:181
ULONG cbMaxToken
Definition: sspi.h:117
Definition: cookie.c:42
uint32_t ULONG
Definition: typedefs.h:59
#define SEC_E_OK
Definition: winerror.h:2356
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
SECURITY_STATUS WINAPI AcquireCredentialsHandleW(SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse, PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
Definition: wrapper.c:105
SECURITY_STATUS WINAPI InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:301
SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName, PSecPkgInfoW *ppPackageInfo)
Definition: wrapper.c:750

Referenced by HTTP_HttpSendRequestW().

◆ HTTP_DomainMatches()

static BOOL HTTP_DomainMatches ( LPCWSTR  server,
substr_t  domain 
)
static

Definition at line 1680 of file http.c.

1681{
1682 const WCHAR *dot, *ptr;
1683 int len;
1684
1685 if(domain.len == ARRAY_SIZE(L"<local>")-1 && !wcsnicmp(domain.str, L"<local>", domain.len) && !wcschr(server, '.' ))
1686 return TRUE;
1687
1688 if(domain.len && *domain.str != '*')
1689 return domain.len == lstrlenW(server) && !wcsnicmp(server, domain.str, domain.len);
1690
1691 if(domain.len < 2 || domain.str[1] != '.')
1692 return FALSE;
1693
1694 /* For a hostname to match a wildcard, the last domain must match
1695 * the wildcard exactly. E.g. if the wildcard is *.a.b, and the
1696 * hostname is www.foo.a.b, it matches, but a.b does not.
1697 */
1698 dot = wcschr(server, '.');
1699 if(!dot)
1700 return FALSE;
1701
1702 len = lstrlenW(dot + 1);
1703 if(len < domain.len - 2)
1704 return FALSE;
1705
1706 /* The server's domain is longer than the wildcard, so it
1707 * could be a subdomain. Compare the last portion of the
1708 * server's domain.
1709 */
1710 ptr = dot + 1 + len - domain.len + 2;
1711 if(!wcsnicmp(ptr, domain.str+2, domain.len-2))
1712 /* This is only a match if the preceding character is
1713 * a '.', i.e. that it is a matching domain. E.g.
1714 * if domain is '*.b.c' and server is 'www.ab.c' they
1715 * do not match.
1716 */
1717 return *(ptr - 1) == '.';
1718
1719 return len == domain.len-2 && !wcsnicmp(dot + 1, domain.str + 2, len);
1720}

Referenced by HTTP_ShouldBypassProxy().

◆ HTTP_EncodeBase64()

static UINT HTTP_EncodeBase64 ( LPCSTR  bin,
unsigned int  len,
LPWSTR  base64 
)
static

Definition at line 1468 of file http.c.

1469{
1470 UINT n = 0, x;
1471 static const CHAR HTTP_Base64Enc[] =
1472 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1473
1474 while( len > 0 )
1475 {
1476 /* first 6 bits, all from bin[0] */
1477 base64[n++] = HTTP_Base64Enc[(bin[0] & 0xfc) >> 2];
1478 x = (bin[0] & 3) << 4;
1479
1480 /* next 6 bits, 2 from bin[0] and 4 from bin[1] */
1481 if( len == 1 )
1482 {
1483 base64[n++] = HTTP_Base64Enc[x];
1484 base64[n++] = '=';
1485 base64[n++] = '=';
1486 break;
1487 }
1488 base64[n++] = HTTP_Base64Enc[ x | ( (bin[1]&0xf0) >> 4 ) ];
1489 x = ( bin[1] & 0x0f ) << 2;
1490
1491 /* next 6 bits 4 from bin[1] and 2 from bin[2] */
1492 if( len == 2 )
1493 {
1494 base64[n++] = HTTP_Base64Enc[x];
1495 base64[n++] = '=';
1496 break;
1497 }
1498 base64[n++] = HTTP_Base64Enc[ x | ( (bin[2]&0xc0 ) >> 6 ) ];
1499
1500 /* last 6 bits, all from bin [2] */
1501 base64[n++] = HTTP_Base64Enc[ bin[2] & 0x3f ];
1502 bin += 3;
1503 len -= 3;
1504 }
1505 base64[n] = 0;
1506 return n;
1507}
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
char CHAR
Definition: xmlstorage.h:175

Referenced by encode_auth_data().

◆ HTTP_FixURL()

static void HTTP_FixURL ( http_request_t request)
static

Definition at line 524 of file http.c.

525{
526 /* If we don't have a path we set it to root */
527 if (NULL == request->path)
528 request->path = heap_strdupW(L"/");
529 else /* remove \r and \n*/
530 {
531 int nLen = lstrlenW(request->path);
532 while ((nLen >0 ) && ((request->path[nLen-1] == '\r')||(request->path[nLen-1] == '\n')))
533 {
534 nLen--;
535 request->path[nLen]='\0';
536 }
537 /* Replace '\' with '/' */
538 while (nLen>0) {
539 nLen--;
540 if (request->path[nLen] == '\\') request->path[nLen]='/';
541 }
542 }
543
545 request->path, lstrlenW(request->path), L"http://", lstrlenW(L"http://") )
546 && request->path[0] != '/') /* not an absolute path ?? --> fix it !! */
547 {
548 WCHAR *fixurl = heap_alloc((lstrlenW(request->path) + 2)*sizeof(WCHAR));
549 *fixurl = '/';
550 lstrcpyW(fixurl + 1, request->path);
552 request->path = fixurl;
553 }
554}
#define LOCALE_INVARIANT

Referenced by HTTP_HttpSendRequestW().

◆ HTTP_FreeTokens()

static void HTTP_FreeTokens ( LPWSTR token_array)
static

Definition at line 517 of file http.c.

518{
519 int i;
520 for (i = 0; token_array[i]; i++) heap_free(token_array[i]);
521 heap_free(token_array);
522}

Referenced by HTTP_GetResponseHeaders(), HTTP_HttpAddRequestHeadersW(), and HTTP_InterpretHttpHeader().

◆ HTTP_GetCustomHeaderIndex() [1/2]

◆ HTTP_GetCustomHeaderIndex() [2/2]

static INT HTTP_GetCustomHeaderIndex ( http_request_t request,
LPCWSTR  lpszField,
int  requested_index,
BOOL  request_only 
)
static

Definition at line 6252 of file http.c.

6254{
6255 DWORD index;
6256
6257 TRACE("%s, %d, %d\n", debugstr_w(lpszField), requested_index, request_only);
6258
6259 for (index = 0; index < request->nCustHeaders; index++)
6260 {
6261 if (wcsicmp(request->custHeaders[index].lpszField, lpszField))
6262 continue;
6263
6264 if (request_only && !(request->custHeaders[index].wFlags & HDR_ISREQUEST))
6265 continue;
6266
6267 if (!request_only && (request->custHeaders[index].wFlags & HDR_ISREQUEST))
6268 continue;
6269
6270 if (requested_index == 0)
6271 break;
6272 requested_index --;
6273 }
6274
6275 if (index >= request->nCustHeaders)
6276 index = -1;
6277
6278 TRACE("Return: %d\n", index);
6279 return index;
6280}
#define index(s, c)
Definition: various.h:29

◆ HTTP_GetHeader()

static LPHTTPHEADERW HTTP_GetHeader ( http_request_t req,
LPCWSTR  head 
)
static

Definition at line 294 of file http.c.

295{
296 int HeaderIndex = 0;
297 HeaderIndex = HTTP_GetCustomHeaderIndex(req, head, 0, TRUE);
298 if (HeaderIndex == -1)
299 return NULL;
300 else
301 return &req->custHeaders[HeaderIndex];
302}
struct outqueuenode * head
Definition: adnsresfilter.c:66

Referenced by get_host_header(), and HTTP_HttpSendRequestW().

◆ HTTP_GetResponseHeaders()

static DWORD HTTP_GetResponseHeaders ( http_request_t req,
INT len 
)
static

Definition at line 5932 of file http.c.

5933{
5934 INT cbreaks = 0;
5936 DWORD buflen = MAX_REPLY_LEN;
5937 INT rc = 0;
5938 char bufferA[MAX_REPLY_LEN];
5939 LPWSTR status_code = NULL, status_text = NULL;
5941 BOOL codeHundred = FALSE;
5942
5943 TRACE("-->\n");
5944
5946 goto lend;
5947
5948 /* clear old response headers (eg. from a redirect response) */
5950
5952 do {
5953 /*
5954 * We should first receive 'HTTP/1.x nnn OK' where nnn is the status code.
5955 */
5956 buflen = MAX_REPLY_LEN;
5957 if ((res = read_line(request, bufferA, &buflen)))
5958 goto lend;
5959
5960 if (!buflen) goto lend;
5961
5962 rc += buflen;
5963 MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN );
5964 /* check is this a status code line? */
5965 if (!wcsncmp(buffer, L"HTTP/1.0", 4))
5966 {
5967 /* split the version from the status code */
5968 status_code = wcschr( buffer, ' ' );
5969 if( !status_code )
5970 goto lend;
5971 *status_code++=0;
5972
5973 /* split the status code from the status text */
5974 status_text = wcschr( status_code, ' ' );
5975 if( status_text )
5976 *status_text++=0;
5977
5978 request->status_code = wcstol(status_code, NULL, 10);
5979
5980 TRACE("version [%s] status code [%s] status text [%s]\n",
5982
5983 codeHundred = request->status_code == HTTP_STATUS_CONTINUE;
5984 }
5985 else if (!codeHundred)
5986 {
5987 WARN("No status line at head of response (%s)\n", debugstr_w(buffer));
5988
5990 heap_free(request->statusText);
5991
5992 request->status_code = HTTP_STATUS_OK;
5993 request->version = heap_strdupW(L"HTTP/1.0");
5994 request->statusText = heap_strdupW(L"OK");
5995
5996 goto lend;
5997 }
5998 } while (codeHundred);
5999
6000 /* Add status code */
6003
6005 heap_free(request->statusText);
6006
6008 request->statusText = heap_strdupW(status_text ? status_text : L"");
6009
6010 /* Restore the spaces */
6011 *(status_code-1) = ' ';
6012 if (status_text)
6013 *(status_text-1) = ' ';
6014
6015 /* Parse each response line */
6016 do
6017 {
6018 buflen = MAX_REPLY_LEN;
6019 if (!read_line(request, bufferA, &buflen) && buflen)
6020 {
6021 LPWSTR * pFieldAndValue;
6022
6023 TRACE("got line %s, now interpreting\n", debugstr_a(bufferA));
6024
6025 if (!bufferA[0]) break;
6026 MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN );
6027
6028 pFieldAndValue = HTTP_InterpretHttpHeader(buffer);
6029 if (pFieldAndValue)
6030 {
6031 HTTP_ProcessHeader(request, pFieldAndValue[0], pFieldAndValue[1],
6033 HTTP_FreeTokens(pFieldAndValue);
6034 }
6035 }
6036 else
6037 {
6038 cbreaks++;
6039 if (cbreaks >= 2)
6040 break;
6041 }
6042 }while(1);
6043
6045
6046lend:
6047
6048 *len = rc;
6049 TRACE("<--\n");
6050 return res;
6051}
#define MultiByteToWideChar
Definition: compat.h:110
static LPWSTR * HTTP_InterpretHttpHeader(LPCWSTR buffer)
Definition: http.c:6063
static DWORD HTTP_ProcessHeader(http_request_t *req, LPCWSTR field, LPCWSTR value, DWORD dwModifier)
Definition: http.c:6117
static void HTTP_FreeTokens(LPWSTR *token_array)
Definition: http.c:517
static void HTTP_clear_response_headers(http_request_t *request)
Definition: http.c:5901
#define HTTP_ADDHDR_FLAG_REPLACE
Definition: http.c:71
#define HTTP_ADDHDR_FLAG_ADD
Definition: http.c:67
_Check_return_ long __cdecl wcstol(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN
#define MAX_REPLY_LEN
Definition: request.c:2568
_Check_return_ _CRTIMP int __cdecl wcsncmp(_In_reads_or_z_(_MaxCount) const wchar_t *_Str1, _In_reads_or_z_(_MaxCount) const wchar_t *_Str2, _In_ size_t _MaxCount)
int receive_timeout
struct netconn * netconn
int read_line()
int32_t INT
Definition: typedefs.h:58
#define HTTP_STATUS_OK
Definition: winhttp.h:240
#define HTTP_STATUS_CONTINUE
Definition: winhttp.h:238
#define HTTP_ADDREQ_FLAG_ADD
Definition: wininet.h:1707
#define ERROR_HTTP_INVALID_SERVER_RESPONSE
Definition: wininet.h:2060

Referenced by HTTP_HttpEndRequestW(), and HTTP_HttpSendRequestW().

◆ HTTP_HandleRedirect()

static DWORD HTTP_HandleRedirect ( http_request_t request,
WCHAR url 
)
static

Definition at line 4143 of file http.c.

4144{
4145 URL_COMPONENTSW urlComponents = { sizeof(urlComponents) };
4146 http_session_t *session = request->session;
4147 size_t url_len = lstrlenW(url);
4148
4149 if(url[0] == '/')
4150 {
4151 /* if it's an absolute path, keep the same session info */
4152 urlComponents.lpszUrlPath = url;
4153 urlComponents.dwUrlPathLength = url_len;
4154 }
4155 else
4156 {
4157 urlComponents.dwHostNameLength = 1;
4158 urlComponents.dwUserNameLength = 1;
4159 urlComponents.dwUrlPathLength = 1;
4160 if(!InternetCrackUrlW(url, url_len, 0, &urlComponents))
4161 return INTERNET_GetLastError();
4162
4163 if(!urlComponents.dwHostNameLength)
4165 }
4166
4168 url, (url_len + 1) * sizeof(WCHAR));
4169
4170 if(urlComponents.dwHostNameLength) {
4171 BOOL custom_port = FALSE;
4172 substr_t host;
4173
4174 if(urlComponents.nScheme == INTERNET_SCHEME_HTTP) {
4175 if(request->hdr.dwFlags & INTERNET_FLAG_SECURE) {
4176 TRACE("redirect from secure page to non-secure page\n");
4177 /* FIXME: warn about from secure redirect to non-secure page */
4178 request->hdr.dwFlags &= ~INTERNET_FLAG_SECURE;
4179 }
4180
4181 custom_port = urlComponents.nPort != INTERNET_DEFAULT_HTTP_PORT;
4182 }else if(urlComponents.nScheme == INTERNET_SCHEME_HTTPS) {
4183 if(!(request->hdr.dwFlags & INTERNET_FLAG_SECURE)) {
4184 TRACE("redirect from non-secure page to secure page\n");
4185 /* FIXME: notify about redirect to secure page */
4186 request->hdr.dwFlags |= INTERNET_FLAG_SECURE;
4187 }
4188
4189 custom_port = urlComponents.nPort != INTERNET_DEFAULT_HTTPS_PORT;
4190 }
4191
4192 heap_free(session->hostName);
4193
4194 session->hostName = heap_strndupW(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
4195 session->hostPort = urlComponents.nPort;
4196
4197 heap_free(session->userName);
4198 session->userName = NULL;
4199 if (urlComponents.dwUserNameLength)
4200 session->userName = heap_strndupW(urlComponents.lpszUserName, urlComponents.dwUserNameLength);
4201
4203
4204 host = substr(urlComponents.lpszHostName, urlComponents.dwHostNameLength);
4205
4206 if(host.len != lstrlenW(request->server->name) || wcsnicmp(request->server->name, host.str, host.len)
4207 || request->server->port != urlComponents.nPort) {
4208 server_t *new_server;
4209
4210 new_server = get_server(host, urlComponents.nPort, urlComponents.nScheme == INTERNET_SCHEME_HTTPS, TRUE);
4211 server_release(request->server);
4212 request->server = new_server;
4213 }
4214
4215 if (custom_port)
4216 HTTP_ProcessHeader(request, L"Host", request->server->host_port,
4218 else
4219 HTTP_ProcessHeader(request, L"Host", request->server->name,
4221 }
4222
4224 request->path = NULL;
4225 if(urlComponents.dwUrlPathLength)
4226 {
4227 DWORD needed = 1;
4228 HRESULT rc;
4229 WCHAR dummy[] = L"";
4230 WCHAR *path;
4231
4232 path = heap_strndupW(urlComponents.lpszUrlPath, urlComponents.dwUrlPathLength);
4234 if (rc != E_POINTER)
4235 ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
4236 request->path = heap_alloc(needed*sizeof(WCHAR));
4237 rc = UrlEscapeW(path, request->path, &needed,
4239 if (rc != S_OK)
4240 {
4241 ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(path),rc);
4243 }
4244 heap_free(path);
4245 }
4246
4247 /* Remove custom content-type/length headers on redirects. */
4248 remove_header(request, L"Content-Type", TRUE);
4249 remove_header(request, L"Content-Length", TRUE);
4250
4251 return ERROR_SUCCESS;
4252}
HRESULT WINAPI UrlEscapeW(LPCWSTR pszUrl, LPWSTR pszEscaped, LPDWORD pcchEscaped, DWORD dwFlags)
Definition: url.c:1076
#define HTTP_ADDHDR_FLAG_REQ
Definition: http.c:72
static void remove_header(http_request_t *request, const WCHAR *str, BOOL from_request)
Definition: http.c:355
static void reset_data_stream(http_request_t *req)
Definition: http.c:347
DWORD INTERNET_GetLastError(void)
Definition: internet.c:3858
#define S_OK
Definition: intsafe.h:52
#define URL_ESCAPE_SPACES_ONLY
Definition: shlwapi.h:1242
DWORD dwUrlPathLength
Definition: wininet.h:223
DWORD dwUserNameLength
Definition: wininet.h:219
#define E_POINTER
Definition: winerror.h:2365
#define INTERNET_DEFAULT_HTTP_PORT
Definition: winhttp.h:36
#define INTERNET_DEFAULT_HTTPS_PORT
Definition: winhttp.h:37
#define HTTP_ADDREQ_FLAG_REPLACE
Definition: wininet.h:1711
#define ERROR_INTERNET_INVALID_URL
Definition: wininet.h:1994
#define INTERNET_STATUS_REDIRECT
Definition: wininet.h:899

Referenced by HTTP_HttpEndRequestW(), and HTTP_HttpSendRequestW().

◆ HTTP_HttpAddRequestHeadersW()

static DWORD HTTP_HttpAddRequestHeadersW ( http_request_t request,
LPCWSTR  lpszHeader,
DWORD  dwHeaderLength,
DWORD  dwModifier 
)
static

Definition at line 1218 of file http.c.

1220{
1221 LPWSTR lpszStart;
1222 LPWSTR lpszEnd;
1223 LPWSTR buffer;
1225
1226 TRACE("copying header: %s\n", debugstr_wn(lpszHeader, dwHeaderLength));
1227
1228 if( dwHeaderLength == ~0U )
1229 len = lstrlenW(lpszHeader);
1230 else
1231 len = dwHeaderLength;
1232 buffer = heap_alloc(sizeof(WCHAR)*(len+1));
1233 lstrcpynW( buffer, lpszHeader, len + 1);
1234
1235 lpszStart = buffer;
1236
1237 do
1238 {
1239 LPWSTR * pFieldAndValue;
1240
1241 lpszEnd = lpszStart;
1242
1243 while (*lpszEnd != '\0')
1244 {
1245 if (*lpszEnd == '\r' || *lpszEnd == '\n')
1246 break;
1247 lpszEnd++;
1248 }
1249
1250 if (*lpszStart == '\0')
1251 break;
1252
1253 if (*lpszEnd == '\r' || *lpszEnd == '\n')
1254 {
1255 *lpszEnd = '\0';
1256 lpszEnd++; /* Jump over newline */
1257 }
1258 TRACE("interpreting header %s\n", debugstr_w(lpszStart));
1259 if (*lpszStart == '\0')
1260 {
1261 /* Skip 0-length headers */
1262 lpszStart = lpszEnd;
1264 continue;
1265 }
1266 pFieldAndValue = HTTP_InterpretHttpHeader(lpszStart);
1267 if (pFieldAndValue)
1268 {
1269 res = HTTP_ProcessHeader(request, pFieldAndValue[0],
1270 pFieldAndValue[1], dwModifier | HTTP_ADDHDR_FLAG_REQ);
1271 HTTP_FreeTokens(pFieldAndValue);
1272 }
1273
1274 lpszStart = lpszEnd;
1275 } while (res == ERROR_SUCCESS);
1276
1278 return res;
1279}
#define U(x)
Definition: wordpad.c:45
#define lstrcpynW
Definition: compat.h:738
#define debugstr_wn
Definition: kernel32.h:33
#define ERROR_HTTP_INVALID_HEADER
Definition: wininet.h:2061

Referenced by HTTP_HttpSendRequestW(), HTTP_InsertCookies(), HttpAddRequestHeadersW(), and set_content_length_header().

◆ HTTP_HttpEndRequestW()

static DWORD HTTP_HttpEndRequestW ( http_request_t request,
DWORD  dwFlags,
DWORD_PTR  dwContext 
)
static

Definition at line 5269 of file http.c.

5270{
5271 INT responseLen;
5273
5275 WARN("Not connected\n");
5278 }
5279
5282
5283 if (HTTP_GetResponseHeaders(request, &responseLen) || !responseLen)
5285
5287 INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, sizeof(DWORD));
5288
5289 /* process cookies here. Is this right? */
5294
5296 if(!request->contentLength)
5298 }
5299
5301 {
5302 switch(request->status_code) {
5304 case HTTP_STATUS_MOVED:
5307 WCHAR *new_url;
5308
5309 new_url = get_redirect_url(request);
5310 if(!new_url)
5311 break;
5312
5313 if (wcscmp(request->verb, L"GET") && wcscmp(request->verb, L"HEAD") &&
5315 {
5317 request->verb = heap_strdupW(L"GET");
5318 }
5320 res = HTTP_HandleRedirect(request, new_url);
5321 heap_free(new_url);
5322 if (res == ERROR_SUCCESS)
5324 }
5325 }
5326 }
5327
5328 if(res == ERROR_SUCCESS)
5330
5331 if (res == ERROR_SUCCESS && request->contentLength)
5333 else
5335
5336 return res;
5337}
static WCHAR * get_redirect_url(http_request_t *request)
Definition: http.c:4076
static void HTTP_ProcessExpires(http_request_t *request)
Definition: http.c:4681
static void http_process_keep_alive(http_request_t *req)
Definition: http.c:4788
static void HTTP_ProcessLastModified(http_request_t *request)
Definition: http.c:4769
static DWORD HTTP_HandleRedirect(http_request_t *request, WCHAR *url)
Definition: http.c:4143
static void HTTP_ProcessCookies(http_request_t *request)
Definition: http.c:666
static DWORD HTTP_GetResponseHeaders(http_request_t *req, INT *len)
Definition: http.c:5932
static void HTTP_ReceiveRequestData(http_request_t *req)
Definition: http.c:3025
static void create_cache_entry(http_request_t *req)
Definition: http.c:2449
static DWORD set_content_length(http_request_t *request)
Definition: http.c:2943
WCHAR * verb
#define HTTP_STATUS_REDIRECT_KEEP_VERB
Definition: winhttp.h:254
#define HTTP_STATUS_REDIRECT
Definition: winhttp.h:250
#define HTTP_STATUS_MOVED
Definition: winhttp.h:249
#define HTTP_STATUS_REDIRECT_METHOD
Definition: winhttp.h:251
#define INTERNET_STATUS_RECEIVING_RESPONSE
Definition: wininet.h:889
#define INTERNET_FLAG_NO_AUTO_REDIRECT
Definition: wininet.h:73
#define ERROR_INTERNET_OPERATION_CANCELLED
Definition: wininet.h:2006
#define ERROR_HTTP_HEADER_NOT_FOUND
Definition: wininet.h:2058

Referenced by AsyncHttpEndRequestProc(), and HttpEndRequestW().

◆ HTTP_HttpOpenRequestW()

static DWORD HTTP_HttpOpenRequestW ( http_session_t session,
LPCWSTR  lpszVerb,
LPCWSTR  lpszObjectName,
LPCWSTR  lpszVersion,
LPCWSTR  lpszReferrer,
LPCWSTR lpszAcceptTypes,
DWORD  dwFlags,
DWORD_PTR  dwContext,
HINTERNET ret 
)
static

Definition at line 3354 of file http.c.

3358{
3359 appinfo_t *hIC = session->appInfo;
3361 DWORD port, len;
3362
3363 TRACE("-->\n");
3364
3366 if(!request)
3367 return ERROR_OUTOFMEMORY;
3368
3369 request->hdr.htype = WH_HHTTPREQ;
3370 request->hdr.dwFlags = dwFlags;
3371 request->hdr.dwContext = dwContext;
3372 request->hdr.decoding = session->hdr.decoding;
3373 request->contentLength = ~0;
3374
3375 request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl;
3376 request->data_stream = &request->netconn_stream.data_stream;
3380
3381 InitializeCriticalSection( &request->headers_section );
3382 request->headers_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.headers_section");
3383
3384 InitializeCriticalSection( &request->read_section );
3385 request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section");
3386
3388 request->session = session;
3389 list_add_head( &session->hdr.children, &request->hdr.entry );
3390
3391 port = session->hostPort;
3393 port = (session->hdr.dwFlags & INTERNET_FLAG_SECURE) ?
3395
3396 request->server = get_server(substrz(session->hostName), port, (dwFlags & INTERNET_FLAG_SECURE) != 0, TRUE);
3397 if(!request->server) {
3399 return ERROR_OUTOFMEMORY;
3400 }
3401
3406
3407 if (lpszObjectName && *lpszObjectName) {
3408 HRESULT rc;
3409 WCHAR dummy;
3410
3411 len = 1;
3412 rc = UrlCanonicalizeW(lpszObjectName, &dummy, &len, URL_ESCAPE_SPACES_ONLY);
3413 if (rc != E_POINTER)
3414 len = lstrlenW(lpszObjectName)+1;
3415 request->path = heap_alloc(len*sizeof(WCHAR));
3416 rc = UrlCanonicalizeW(lpszObjectName, request->path, &len,
3418 if (rc != S_OK)
3419 {
3420 ERR("Unable to escape string!(%s) (%d)\n",debugstr_w(lpszObjectName),rc);
3421 lstrcpyW(request->path,lpszObjectName);
3422 }
3423 }else {
3424 request->path = heap_strdupW(L"/");
3425 }
3426
3427 if (lpszReferrer && *lpszReferrer)
3429
3430 if (lpszAcceptTypes)
3431 {
3432 int i;
3433 for (i = 0; lpszAcceptTypes[i]; i++)
3434 {
3435 if (!*lpszAcceptTypes[i]) continue;
3436 HTTP_ProcessHeader(request, L"Accept", lpszAcceptTypes[i],
3440 }
3441 }
3442
3443 request->verb = heap_strdupW(lpszVerb && *lpszVerb ? lpszVerb : L"GET");
3444 request->version = heap_strdupW(lpszVersion && *lpszVersion ? lpszVersion : L"HTTP/1.1");
3445
3446 if (hIC->proxy && hIC->proxy[0] && !HTTP_ShouldBypassProxy(hIC, session->hostName))
3448
3449 INTERNET_SendCallback(&session->hdr, dwContext,
3451 sizeof(HINTERNET));
3452
3453 TRACE("<-- (%p)\n", request);
3454
3455 *ret = request->hdr.hInternet;
3456 return ERROR_SUCCESS;
3457}
HRESULT WINAPI UrlCanonicalizeW(LPCWSTR pszUrl, LPWSTR pszCanonicalized, LPDWORD pcchCanonicalized, DWORD dwFlags)
Definition: url.c:282
static const object_vtbl_t HTTPREQVtbl
Definition: http.c:3332
static BOOL HTTP_ShouldBypassProxy(appinfo_t *lpwai, LPCWSTR server)
Definition: http.c:1722
static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_request_t *request)
Definition: http.c:1748
#define HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA
Definition: http.c:69
static const data_stream_vtbl_t netconn_stream_vtbl
Definition: http.c:2740
BOOL WININET_Release(object_header_t *info)
Definition: internet.c:211
@ WH_HHTTPREQ
Definition: internet.h:240
static substr_t substrz(const WCHAR *str)
Definition: internet.h:209
int send_timeout
DWORD security_flags
int connect_timeout
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
#define DWORD_PTR
Definition: treelist.c:76
#define SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
Definition: winhttp.h:282
#define SECURITY_FLAG_IGNORE_CERT_CN_INVALID
Definition: winhttp.h:283
#define INTERNET_INVALID_PORT_NUMBER
Definition: wininet.h:36
#define INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
Definition: wininet.h:80
#define INTERNET_FLAG_IGNORE_CERT_CN_INVALID
Definition: wininet.h:81

Referenced by HttpOpenRequestW().

◆ HTTP_HttpQueryInfoW()

static DWORD HTTP_HttpQueryInfoW ( http_request_t request,
DWORD  dwInfoLevel,
LPVOID  lpBuffer,
LPDWORD  lpdwBufferLength,
LPDWORD  lpdwIndex 
)
static

Definition at line 3592 of file http.c.

3594{
3595 LPHTTPHEADERW lphttpHdr = NULL;
3597 INT requested_index = lpdwIndex ? *lpdwIndex : 0;
3598 DWORD level = (dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK);
3599 INT index = -1;
3600
3601 EnterCriticalSection( &request->headers_section );
3602
3603 /* Find requested header structure */
3604 switch (level)
3605 {
3606 case HTTP_QUERY_CUSTOM:
3607 if (!lpBuffer)
3608 {
3609 LeaveCriticalSection( &request->headers_section );
3611 }
3612 index = HTTP_GetCustomHeaderIndex(request, lpBuffer, requested_index, request_only);
3613 break;
3615 {
3617 DWORD len = 0;
3619
3620 if (request_only)
3622 else
3624 if (!headers)
3625 {
3626 LeaveCriticalSection( &request->headers_section );
3627 return ERROR_OUTOFMEMORY;
3628 }
3629
3630 len = lstrlenW(headers) * sizeof(WCHAR);
3631 if (len + sizeof(WCHAR) > *lpdwBufferLength)
3632 {
3633 len += sizeof(WCHAR);
3635 }
3636 else if (lpBuffer)
3637 {
3638 memcpy(lpBuffer, headers, len + sizeof(WCHAR));
3639 TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len / sizeof(WCHAR)));
3641 }
3643
3645 LeaveCriticalSection( &request->headers_section );
3646 return res;
3647 }
3649 {
3651 DWORD len;
3652
3653 if (request_only)
3655 else
3657
3658 if (!headers)
3659 {
3660 LeaveCriticalSection( &request->headers_section );
3661 return ERROR_OUTOFMEMORY;
3662 }
3663
3664 len = lstrlenW(headers) * sizeof(WCHAR);
3665 if (len > *lpdwBufferLength)
3666 {
3669 LeaveCriticalSection( &request->headers_section );
3671 }
3672
3673 if (lpBuffer)
3674 {
3675 DWORD i;
3676
3677 TRACE("returning data: %s\n", debugstr_wn(headers, len / sizeof(WCHAR)));
3678
3679 for (i = 0; i < len / sizeof(WCHAR); i++)
3680 {
3681 if (headers[i] == '\n')
3682 headers[i] = 0;
3683 }
3685 }
3686 *lpdwBufferLength = len - sizeof(WCHAR);
3687
3689 LeaveCriticalSection( &request->headers_section );
3690 return ERROR_SUCCESS;
3691 }
3693 if (request->statusText)
3694 {
3695 DWORD len = lstrlenW(request->statusText);
3696 if (len + 1 > *lpdwBufferLength/sizeof(WCHAR))
3697 {
3698 *lpdwBufferLength = (len + 1) * sizeof(WCHAR);
3699 LeaveCriticalSection( &request->headers_section );
3701 }
3702 if (lpBuffer)
3703 {
3704 memcpy(lpBuffer, request->statusText, (len + 1) * sizeof(WCHAR));
3705 TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len));
3706 }
3707 *lpdwBufferLength = len * sizeof(WCHAR);
3708 LeaveCriticalSection( &request->headers_section );
3709 return ERROR_SUCCESS;
3710 }
3711 break;
3712 case HTTP_QUERY_VERSION:
3713 if (request->version)
3714 {
3716 if (len + 1 > *lpdwBufferLength/sizeof(WCHAR))
3717 {
3718 *lpdwBufferLength = (len + 1) * sizeof(WCHAR);
3719 LeaveCriticalSection( &request->headers_section );
3721 }
3722 if (lpBuffer)
3723 {
3724 memcpy(lpBuffer, request->version, (len + 1) * sizeof(WCHAR));
3725 TRACE("returning data: %s\n", debugstr_wn(lpBuffer, len));
3726 }
3727 *lpdwBufferLength = len * sizeof(WCHAR);
3728 LeaveCriticalSection( &request->headers_section );
3729 return ERROR_SUCCESS;
3730 }
3731 break;
3734 requested_index,request_only);
3735 break;
3738
3739 if(request_only)
3740 {
3741 LeaveCriticalSection( &request->headers_section );
3743 }
3744
3745 if(requested_index)
3746 break;
3747
3749 if(*lpdwBufferLength >= sizeof(DWORD))
3750 *(DWORD*)lpBuffer = request->status_code;
3751 else
3753 *lpdwBufferLength = sizeof(DWORD);
3754 }else {
3755 WCHAR buf[12];
3756 DWORD size;
3757
3758 size = swprintf(buf, ARRAY_SIZE(buf), L"%u", request->status_code) * sizeof(WCHAR);
3759
3760 if(size <= *lpdwBufferLength) {
3761 memcpy(lpBuffer, buf, size+sizeof(WCHAR));
3762 }else {
3763 size += sizeof(WCHAR);
3765 }
3766
3768 }
3769 LeaveCriticalSection( &request->headers_section );
3770 return res;
3771 }
3772 default:
3774
3777 requested_index,request_only);
3778 }
3779
3780 if (index >= 0)
3781 lphttpHdr = &request->custHeaders[index];
3782
3783 /* Ensure header satisfies requested attributes */
3784 if (!lphttpHdr ||
3786 (~lphttpHdr->wFlags & HDR_ISREQUEST)))
3787 {
3788 LeaveCriticalSection( &request->headers_section );
3790 }
3791
3792 /* coalesce value to requested type */
3794 {
3795 unsigned long value;
3796
3797 if (*lpdwBufferLength != sizeof(DWORD))
3798 {
3799 LeaveCriticalSection( &request->headers_section );
3801 }
3802
3803 errno = 0;
3804 value = wcstoul( lphttpHdr->lpszValue, NULL, 10 );
3805 if (value > UINT_MAX || (value == ULONG_MAX && errno == ERANGE))
3806 {
3807 LeaveCriticalSection( &request->headers_section );
3809 }
3810
3811 *(DWORD *)lpBuffer = value;
3812 TRACE(" returning number: %u\n", *(DWORD *)lpBuffer);
3813 }
3815 {
3816 time_t tmpTime;
3817 struct tm tmpTM;
3818 SYSTEMTIME *STHook;
3819
3820 tmpTime = ConvertTimeString(lphttpHdr->lpszValue);
3821
3822 tmpTM = *gmtime(&tmpTime);
3823 STHook = (SYSTEMTIME *)lpBuffer;
3824 STHook->wDay = tmpTM.tm_mday;
3825 STHook->wHour = tmpTM.tm_hour;
3826 STHook->wMilliseconds = 0;
3827 STHook->wMinute = tmpTM.tm_min;
3828 STHook->wDayOfWeek = tmpTM.tm_wday;
3829 STHook->wMonth = tmpTM.tm_mon + 1;
3830 STHook->wSecond = tmpTM.tm_sec;
3831 STHook->wYear = 1900+tmpTM.tm_year;
3832
3833 TRACE(" returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n",
3834 STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek,
3835 STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds);
3836 }
3837 else if (lphttpHdr->lpszValue)
3838 {
3839 DWORD len = (lstrlenW(lphttpHdr->lpszValue) + 1) * sizeof(WCHAR);
3840
3841 if (len > *lpdwBufferLength)
3842 {
3844 LeaveCriticalSection( &request->headers_section );
3846 }
3847 if (lpBuffer)
3848 {
3849 memcpy(lpBuffer, lphttpHdr->lpszValue, len);
3850 TRACE("! returning string: %s\n", debugstr_w(lpBuffer));
3851 }
3852 *lpdwBufferLength = len - sizeof(WCHAR);
3853 }
3854 if (lpdwIndex) (*lpdwIndex)++;
3855
3856 LeaveCriticalSection( &request->headers_section );
3857 return ERROR_SUCCESS;
3858}
#define ERANGE
Definition: acclib.h:92
static TAGREF LPCWSTR LPDWORD LPVOID lpBuffer
Definition: db.cpp:175
static const LPCWSTR header_lookup[]
Definition: http.c:3515
static WCHAR * build_request_header(http_request_t *request, const WCHAR *verb, const WCHAR *path, const WCHAR *version, BOOL use_cr)
Definition: http.c:556
__kernel_time_t time_t
Definition: linux.h:252
GLint level
Definition: gl.h:1546
_Check_return_ unsigned long __cdecl wcstoul(_In_z_ const wchar_t *_Str, _Out_opt_ _Deref_post_z_ wchar_t **_EndPtr, _In_ int _Radix)
time_t ConvertTimeString(LPCWSTR asctime) DECLSPEC_HIDDEN
Definition: utility.c:49
#define ULONG_MAX
Definition: intsafe.h:155
#define UINT_MAX
Definition: intsafe.h:152
#define errno
Definition: errno.h:18
_CRTIMP struct tm *__cdecl gmtime(const time_t *_Time)
Definition: time.h:415
vector< Header * > headers
Definition: sdkparse.cpp:39
WORD wFlags
Definition: internet.h:322
Definition: time.h:68
Definition: pdh_main.c:94
_In_ _In_opt_ _Out_writes_bytes_to_opt_ lpdwBufferLength _Inout_ LPDWORD lpdwBufferLength
Definition: winhttp.h:675
#define HTTP_QUERY_UNLESS_MODIFIED_SINCE
Definition: wininet.h:1593
#define HTTP_QUERY_FLAG_SYSTEMTIME
Definition: wininet.h:1605
#define HTTP_QUERY_RAW_HEADERS_CRLF
Definition: wininet.h:1545
#define HTTP_QUERY_STATUS_TEXT
Definition: wininet.h:1543
#define HTTP_QUERY_VERSION
Definition: wininet.h:1541
#define HTTP_QUERY_FLAG_NUMBER
Definition: wininet.h:1606
#define HTTP_QUERY_CONTENT_TYPE
Definition: wininet.h:1524
#define HTTP_QUERY_STATUS_CODE
Definition: wininet.h:1542
#define HTTP_QUERY_RAW_HEADERS
Definition: wininet.h:1544
#define HTTP_QUERY_CONTENT_ENCODING
Definition: wininet.h:1552
#define HTTP_QUERY_CUSTOM
Definition: wininet.h:1603
#define ERROR_HTTP_INVALID_QUERY_REQUEST
Definition: wininet.h:2062
#define HTTP_QUERY_FLAG_REQUEST_HEADERS
Definition: wininet.h:1604
_In_ DWORD dwInfoLevel
Definition: winsvc.h:422

Referenced by get_redirect_url(), HTTP_HttpSendRequestW(), HTTP_KeepAlive(), HttpQueryInfoW(), and set_content_length().

◆ HTTP_HttpSendRequestW()

static DWORD HTTP_HttpSendRequestW ( http_request_t request,
LPCWSTR  lpszHeaders,
DWORD  dwHeaderLength,
LPVOID  lpOptional,
DWORD  dwOptionalLength,
DWORD  dwContentLength,
BOOL  bEndRequest 
)
static

Definition at line 4910 of file http.c.

4913{
4914 BOOL redirected = FALSE, secure_proxy_connect = FALSE, loop_next;
4915 WCHAR *request_header = NULL;
4916 INT responseLen, cnt;
4917 DWORD res;
4918
4919 TRACE("--> %p\n", request);
4920
4921 assert(request->hdr.htype == WH_HHTTPREQ);
4922
4923 /* if the verb is NULL default to GET */
4924 if (!request->verb)
4925 request->verb = heap_strdupW(L"GET");
4926
4927 HTTP_ProcessHeader(request, L"Host", request->server->canon_host_port,
4929
4930 if (dwContentLength || wcscmp(request->verb, L"GET"))
4931 {
4933 request->bytesToWrite = dwContentLength;
4934 }
4935 if (request->session->appInfo->agent)
4936 {
4937 WCHAR *agent_header;
4938 int len;
4939
4940 len = lstrlenW(request->session->appInfo->agent) + lstrlenW(L"User-Agent: %s\r\n");
4941 agent_header = heap_alloc(len * sizeof(WCHAR));
4942 swprintf(agent_header, len, L"User-Agent: %s\r\n", request->session->appInfo->agent);
4943
4945 heap_free(agent_header);
4946 }
4948 {
4949 HTTP_HttpAddRequestHeadersW(request, L"Pragma: no-cache\r\n",
4950 lstrlenW(L"Pragma: no-cache\r\n"), HTTP_ADDREQ_FLAG_ADD_IF_NEW);
4951 }
4952 if ((request->hdr.dwFlags & INTERNET_FLAG_NO_CACHE_WRITE) && wcscmp(request->verb, L"GET"))
4953 {
4954 HTTP_HttpAddRequestHeadersW(request, L"Cache-Control: no-cache\r\n",
4955 lstrlenW(L"Cache-Control: no-cache\r\n"), HTTP_ADDREQ_FLAG_ADD_IF_NEW);
4956 }
4957
4958 /* add the headers the caller supplied */
4959 if( lpszHeaders && dwHeaderLength )
4961
4962 do
4963 {
4964 DWORD len, data_len = dwOptionalLength;
4965 BOOL reusing_connection;
4966 char *ascii_req;
4967
4968 loop_next = FALSE;
4969
4970 if(redirected) {
4971 request->contentLength = ~0;
4972 request->bytesToWrite = 0;
4973 }
4974
4975 if (TRACE_ON(wininet))
4976 {
4978
4979 EnterCriticalSection( &request->headers_section );
4980 host = HTTP_GetHeader(request, L"Host");
4981 TRACE("Going to url %s %s\n", debugstr_w(host->lpszValue), debugstr_w(request->path));
4982 LeaveCriticalSection( &request->headers_section );
4983 }
4984
4987 {
4988 HTTP_ProcessHeader(request, L"Connection", L"Keep-Alive",
4990 }
4991 HTTP_InsertAuthorization(request, request->authInfo, L"Authorization");
4992 HTTP_InsertAuthorization(request, request->proxyAuthInfo, L"Proxy-Authorization");
4993
4994 if (!(request->hdr.dwFlags & INTERNET_FLAG_NO_COOKIES))
4996
4997 res = open_http_connection(request, &reusing_connection);
4998 if (res != ERROR_SUCCESS)
4999 break;
5000
5001 if (!reusing_connection && (request->hdr.dwFlags & INTERNET_FLAG_SECURE))
5002 {
5003 if (request->proxy) secure_proxy_connect = TRUE;
5004 else
5005 {
5006 res =