[WINHTTP] Sync with Wine Staging 1.7.47. CORE-9924

svn path=/trunk/; revision=68557
This commit is contained in:
Amine Khaldi 2015-07-22 19:39:23 +00:00
parent d173b48397
commit 4f5f0ecab5
7 changed files with 308 additions and 224 deletions

View file

@ -42,7 +42,7 @@ static cookie_t *find_cookie( domain_t *domain, const WCHAR *path, const WCHAR *
LIST_FOR_EACH( item, &domain->cookies )
{
cookie = LIST_ENTRY( item, cookie_t, entry );
if (!strcmpW( cookie->path, path ) && !strcmpiW( cookie->name, name ))
if (!strcmpW( cookie->path, path ) && !strcmpW( cookie->name, name ))
{
TRACE("found %s=%s\n", debugstr_w(cookie->name), debugstr_w(cookie->value));
return cookie;
@ -109,7 +109,7 @@ static BOOL add_cookie( session_t *session, cookie_t *cookie, WCHAR *domain_name
else if ((old_cookie = find_cookie( domain, path, cookie->name ))) delete_cookie( old_cookie );
cookie->path = strdupW( path );
list_add_tail( &domain->cookies, &cookie->entry );
list_add_head( &domain->cookies, &cookie->entry );
TRACE("domain %s path %s <- %s=%s\n", debugstr_w(domain_name), debugstr_w(cookie->path),
debugstr_w(cookie->name), debugstr_w(cookie->value));
@ -122,22 +122,14 @@ static cookie_t *parse_cookie( const WCHAR *string )
const WCHAR *p;
int len;
if (!(p = strchrW( string, '=' )))
{
WARN("no '=' in %s\n", debugstr_w(string));
return NULL;
}
if (p == string)
{
WARN("empty cookie name in %s\n", debugstr_w(string));
return NULL;
}
if (!(p = strchrW( string, '=' ))) p = string + strlenW( string );
len = p - string;
while (len && string[len - 1] == ' ') len--;
if (!len) return NULL;
if (!(cookie = heap_alloc_zero( sizeof(cookie_t) ))) return NULL;
list_init( &cookie->entry );
len = p - string;
if (!(cookie->name = heap_alloc( (len + 1) * sizeof(WCHAR) )))
{
heap_free( cookie );
@ -146,18 +138,20 @@ static cookie_t *parse_cookie( const WCHAR *string )
memcpy( cookie->name, string, len * sizeof(WCHAR) );
cookie->name[len] = 0;
p++; /* skip '=' */
while (*p == ' ') p++;
len = strlenW( p );
if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
if (*p++ == '=')
{
free_cookie( cookie );
return NULL;
}
memcpy( cookie->value, p, len * sizeof(WCHAR) );
cookie->value[len] = 0;
while (*p && *p == ' ') p++;
len = strlenW( p );
while (len && p[len - 1] == ' ') len--;
if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
{
free_cookie( cookie );
return NULL;
}
memcpy( cookie->value, p, len * sizeof(WCHAR) );
cookie->value[len] = 0;
}
return cookie;
}
@ -247,17 +241,25 @@ BOOL add_cookie_headers( request_t *request )
if (strstrW( request->path, cookie->path ) == request->path)
{
const WCHAR format[] = {'C','o','o','k','i','e',':',' ','%','s','=','%','s',0};
int len;
const WCHAR cookieW[] = {'C','o','o','k','i','e',':',' '};
int len, len_cookie = sizeof(cookieW) / sizeof(cookieW[0]), len_name = strlenW( cookie->name );
WCHAR *header;
len = strlenW( cookie->name ) + strlenW( format ) + strlenW( cookie->value );
len = len_cookie + len_name;
if (cookie->value) len += strlenW( cookie->value ) + 1;
if (!(header = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
sprintfW( header, format, cookie->name, cookie->value );
memcpy( header, cookieW, len_cookie * sizeof(WCHAR) );
strcpyW( header + len_cookie, cookie->name );
if (cookie->value)
{
header[len_cookie + len_name] = '=';
strcpyW( header + len_cookie + len_name + 1, cookie->value );
}
TRACE("%s\n", debugstr_w(header));
add_request_headers( request, header, len, WINHTTP_ADDREQ_FLAG_ADD );
add_request_headers( request, header, len,
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON );
heap_free( header );
}
}

View file

@ -353,6 +353,7 @@ BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned
res = sock_get_error( errno );
if (res == WSAEWOULDBLOCK || res == WSAEINPROGRESS)
{
#ifdef __REACTOS__
/* ReactOS: use select instead of poll */
fd_set outfd;
struct timeval tv;
@ -364,6 +365,13 @@ BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned
tv.tv_usec = timeout * 1000;
if (select( 0, NULL, &outfd, NULL, &tv ) > 0)
#else
struct pollfd pfd;
pfd.fd = conn->socket;
pfd.events = POLLOUT;
if (poll( &pfd, 1, timeout ) > 0)
#endif
ret = TRUE;
else
res = sock_get_error( errno );

View file

@ -316,12 +316,8 @@ static header_t *parse_header( LPCWSTR string )
q++; /* skip past colon */
while (*q == ' ') q++;
if (!*q)
{
WARN("no value in line %s\n", debugstr_w(string));
return header;
}
len = strlenW( q );
if (!(header->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
{
free_header( header );
@ -393,76 +389,65 @@ static BOOL delete_header( request_t *request, DWORD index )
static BOOL process_header( request_t *request, LPCWSTR field, LPCWSTR value, DWORD flags, BOOL request_only )
{
int index;
header_t *header;
header_t hdr;
TRACE("%s: %s 0x%08x\n", debugstr_w(field), debugstr_w(value), flags);
/* replace wins out over add */
if (flags & WINHTTP_ADDREQ_FLAG_REPLACE) flags &= ~WINHTTP_ADDREQ_FLAG_ADD;
if (flags & WINHTTP_ADDREQ_FLAG_ADD) index = -1;
else
index = get_header_index( request, field, 0, request_only );
if (index >= 0)
if ((index = get_header_index( request, field, 0, request_only )) >= 0)
{
if (flags & WINHTTP_ADDREQ_FLAG_ADD_IF_NEW) return FALSE;
header = &request->headers[index];
}
else if (value)
if (flags & WINHTTP_ADDREQ_FLAG_REPLACE)
{
header_t hdr;
if (index >= 0)
{
delete_header( request, index );
if (!value || !value[0]) return TRUE;
}
else if (!(flags & WINHTTP_ADDREQ_FLAG_ADD))
{
set_last_error( ERROR_WINHTTP_HEADER_NOT_FOUND );
return FALSE;
}
hdr.field = (LPWSTR)field;
hdr.value = (LPWSTR)value;
hdr.is_request = request_only;
return insert_header( request, &hdr );
}
/* no value to delete */
else return TRUE;
if (flags & WINHTTP_ADDREQ_FLAG_REPLACE)
else if (value)
{
delete_header( request, index );
if (value)
if ((flags & (WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA | WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON)) &&
index >= 0)
{
header_t hdr;
WCHAR *tmp;
int len, len_orig, len_value;
header_t *header = &request->headers[index];
hdr.field = (LPWSTR)field;
hdr.value = (LPWSTR)value;
hdr.is_request = request_only;
len_orig = strlenW( header->value );
len_value = strlenW( value );
return insert_header( request, &hdr );
}
return TRUE;
}
else if (flags & (WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA | WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON))
{
WCHAR sep, *tmp;
int len, orig_len, value_len;
orig_len = strlenW( header->value );
value_len = strlenW( value );
if (flags & WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA) sep = ',';
else sep = ';';
len = orig_len + value_len + 2;
if ((tmp = heap_realloc( header->value, (len + 1) * sizeof(WCHAR) )))
{
len = len_orig + len_value + 2;
if (!(tmp = heap_realloc( header->value, (len + 1) * sizeof(WCHAR) ))) return FALSE;
header->value = tmp;
header->value[len_orig++] = (flags & WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA) ? ',' : ';';
header->value[len_orig++] = ' ';
header->value[orig_len] = sep;
orig_len++;
header->value[orig_len] = ' ';
orig_len++;
memcpy( &header->value[orig_len], value, value_len * sizeof(WCHAR) );
memcpy( &header->value[len_orig], value, len_value * sizeof(WCHAR) );
header->value[len] = 0;
return TRUE;
}
else
{
hdr.field = (LPWSTR)field;
hdr.value = (LPWSTR)value;
hdr.is_request = request_only;
return insert_header( request, &hdr );
}
}
return TRUE;
}
@ -475,7 +460,8 @@ BOOL add_request_headers( request_t *request, LPCWSTR headers, DWORD len, DWORD
if (len == ~0u) len = strlenW( headers );
if (!len) return TRUE;
if (!(buffer = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
strcpyW( buffer, headers );
memcpy( buffer, headers, len * sizeof(WCHAR) );
buffer[len] = 0;
p = buffer;
do
@ -519,7 +505,7 @@ BOOL WINAPI WinHttpAddRequestHeaders( HINTERNET hrequest, LPCWSTR headers, DWORD
TRACE("%p, %s, 0x%x, 0x%08x\n", hrequest, debugstr_w(headers), len, flags);
if (!headers)
if (!headers || !len)
{
set_last_error( ERROR_INVALID_PARAMETER );
return FALSE;
@ -972,10 +958,10 @@ static BOOL secure_proxy_connect( request_t *request )
#define INET6_ADDRSTRLEN 46
#endif
static WCHAR *addr_to_str( const struct sockaddr *addr )
static WCHAR *addr_to_str( struct sockaddr *addr )
{
char buf[INET6_ADDRSTRLEN];
const void *src;
void *src;
switch (addr->sa_family)
{
@ -1240,6 +1226,8 @@ BOOL WINAPI WinHttpSendRequest( HINTERNET hrequest, LPCWSTR headers, DWORD heade
return FALSE;
}
if (headers && !headers_len) headers_len = strlenW( headers );
if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC)
{
send_request_t *s;
@ -1562,8 +1550,16 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return FALSE;
auth_ptr = &request->authinfo;
auth_target = attr_authorization;
username = request->connect->username;
password = request->connect->password;
if (request->creds[TARGET_SERVER][scheme].username)
{
username = request->creds[TARGET_SERVER][scheme].username;
password = request->creds[TARGET_SERVER][scheme].password;
}
else
{
username = request->connect->username;
password = request->connect->password;
}
break;
case WINHTTP_AUTH_TARGET_PROXY:
@ -1571,8 +1567,16 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return FALSE;
auth_ptr = &request->proxy_authinfo;
auth_target = attr_proxy_authorization;
username = request->connect->session->proxy_username;
password = request->connect->session->proxy_password;
if (request->creds[TARGET_PROXY][scheme].username)
{
username = request->creds[TARGET_PROXY][scheme].username;
password = request->creds[TARGET_PROXY][scheme].password;
}
else
{
username = request->connect->session->proxy_username;
password = request->connect->session->proxy_password;
}
break;
default:
@ -1756,11 +1760,12 @@ static BOOL do_authorization( request_t *request, DWORD target, DWORD scheme_fla
return ret;
}
static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme, const WCHAR *username,
static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme_flag, const WCHAR *username,
const WCHAR *password )
{
if ((scheme == WINHTTP_AUTH_SCHEME_BASIC || scheme == WINHTTP_AUTH_SCHEME_DIGEST) &&
(!username || !password))
enum auth_scheme scheme = scheme_from_flag( scheme_flag );
if (scheme == SCHEME_INVALID || ((scheme == SCHEME_BASIC || scheme == SCHEME_DIGEST) && (!username || !password)))
{
set_last_error( ERROR_INVALID_PARAMETER );
return FALSE;
@ -1769,24 +1774,24 @@ static BOOL set_credentials( request_t *request, DWORD target, DWORD scheme, con
{
case WINHTTP_AUTH_TARGET_SERVER:
{
heap_free( request->connect->username );
if (!username) request->connect->username = NULL;
else if (!(request->connect->username = strdupW( username ))) return FALSE;
heap_free( request->creds[TARGET_SERVER][scheme].username );
if (!username) request->creds[TARGET_SERVER][scheme].username = NULL;
else if (!(request->creds[TARGET_SERVER][scheme].username = strdupW( username ))) return FALSE;
heap_free( request->connect->password );
if (!password) request->connect->password = NULL;
else if (!(request->connect->password = strdupW( password ))) return FALSE;
heap_free( request->creds[TARGET_SERVER][scheme].password );
if (!password) request->creds[TARGET_SERVER][scheme].password = NULL;
else if (!(request->creds[TARGET_SERVER][scheme].password = strdupW( password ))) return FALSE;
break;
}
case WINHTTP_AUTH_TARGET_PROXY:
{
heap_free( request->connect->session->proxy_username );
if (!username) request->connect->session->proxy_username = NULL;
else if (!(request->connect->session->proxy_username = strdupW( username ))) return FALSE;
heap_free( request->creds[TARGET_PROXY][scheme].username );
if (!username) request->creds[TARGET_PROXY][scheme].username = NULL;
else if (!(request->creds[TARGET_PROXY][scheme].username = strdupW( username ))) return FALSE;
heap_free( request->connect->session->proxy_password );
if (!password) request->connect->session->proxy_password = NULL;
else if (!(request->connect->session->proxy_password = strdupW( password ))) return FALSE;
heap_free( request->creds[TARGET_PROXY][scheme].password );
if (!password) request->creds[TARGET_PROXY][scheme].password = NULL;
else if (!(request->creds[TARGET_PROXY][scheme].password = strdupW( password ))) return FALSE;
break;
}
default:
@ -2046,9 +2051,13 @@ static BOOL refill_buffer( request_t *request, BOOL notify )
{
if (!start_next_chunk( request, notify )) return FALSE;
}
len = min( len, request->read_chunked_size );
}
if (!request->read_chunked && request->content_length != ~0u)
else if (request->content_length != ~0u)
{
len = min( len, request->content_length - request->content_read );
}
if (len <= request->read_size) return TRUE;
if (!read_more_data( request, len, notify )) return FALSE;
if (!request->read_size) request->content_length = request->content_read = 0;
@ -2094,7 +2103,9 @@ static BOOL read_reply( request_t *request )
/* we rely on the fact that the protocol is ascii */
MultiByteToWideChar( CP_ACP, 0, status_code, len, status_codeW, len );
status_codeW[len] = 0;
if (!(process_header( request, attr_status, status_codeW, WINHTTP_ADDREQ_FLAG_REPLACE, FALSE ))) return FALSE;
if (!(process_header( request, attr_status, status_codeW,
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE, FALSE )))
return FALSE;
len = status_code - buffer;
if (!(versionW = heap_alloc( len * sizeof(WCHAR) ))) return FALSE;
@ -2265,13 +2276,21 @@ static BOOL handle_redirect( request_t *request, DWORD status )
{
WCHAR *path, *p;
len = strlenW( location ) + 1;
if (location[0] != '/') len++;
if (!(p = path = heap_alloc( len * sizeof(WCHAR) ))) goto end;
if (location[0] != '/') *p++ = '/';
strcpyW( p, location );
if (location[0] == '/')
{
len = strlenW( location );
if (!(path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
strcpyW( path, location );
}
else
{
if ((p = strrchrW( request->path, '/' ))) *p = 0;
len = strlenW( request->path ) + 1 + strlenW( location );
if (!(path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
strcpyW( path, request->path );
strcatW( path, slashW );
strcatW( path, location );
}
heap_free( request->path );
request->path = path;
@ -2316,7 +2335,7 @@ static BOOL handle_redirect( request_t *request, DWORD status )
}
else heap_free( hostname );
if (!(ret = add_host_header( request, WINHTTP_ADDREQ_FLAG_REPLACE ))) goto end;
if (!(ret = add_host_header( request, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE ))) goto end;
if (!(ret = open_connection( request ))) goto end;
heap_free( request->path );
@ -2680,6 +2699,7 @@ struct winhttp_request
LONG send_timeout;
LONG receive_timeout;
WINHTTP_PROXY_INFO proxy;
BOOL async;
};
static inline struct winhttp_request *impl_from_IWinHttpRequest( IWinHttpRequest *iface )
@ -2698,8 +2718,20 @@ static ULONG WINAPI winhttp_request_AddRef(
static void cancel_request( struct winhttp_request *request )
{
if (request->state <= REQUEST_STATE_CANCELLED) return;
if (request->thread) SetEvent( request->cancel );
SetEvent( request->cancel );
LeaveCriticalSection( &request->cs );
WaitForSingleObject( request->thread, INFINITE );
EnterCriticalSection( &request->cs );
request->state = REQUEST_STATE_CANCELLED;
CloseHandle( request->thread );
request->thread = NULL;
CloseHandle( request->wait );
request->wait = NULL;
CloseHandle( request->cancel );
request->cancel = NULL;
}
/* critical section must be held */
@ -3006,6 +3038,7 @@ static void initialize_request( struct winhttp_request *request )
request->bytes_available = 0;
request->bytes_read = 0;
request->error = ERROR_SUCCESS;
request->async = FALSE;
request->logon_policy = WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM;
request->disable_feature = 0;
request->proxy.dwAccessType = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
@ -3019,6 +3052,26 @@ static void initialize_request( struct winhttp_request *request )
request->state = REQUEST_STATE_INITIALIZED;
}
static void reset_request( struct winhttp_request *request )
{
cancel_request( request );
WinHttpCloseHandle( request->hrequest );
request->hrequest = NULL;
WinHttpCloseHandle( request->hconnect );
request->hconnect = NULL;
heap_free( request->buffer );
request->buffer = NULL;
heap_free( request->verb );
request->verb = NULL;
request->offset = 0;
request->bytes_available = 0;
request->bytes_read = 0;
request->error = ERROR_SUCCESS;
request->async = FALSE;
VariantClear( &request->data );
request->state = REQUEST_STATE_INITIALIZED;
}
static HRESULT WINAPI winhttp_request_Open(
IWinHttpRequest *iface,
BSTR method,
@ -3033,10 +3086,9 @@ static HRESULT WINAPI winhttp_request_Open(
'W','i','n','3','2',';',' ','W','i','n','H','t','t','p','.','W','i','n','H','t','t','p',
'R','e','q','u','e','s','t','.','5',')',0};
struct winhttp_request *request = impl_from_IWinHttpRequest( iface );
HINTERNET hsession = NULL, hconnect = NULL, hrequest;
URL_COMPONENTS uc;
WCHAR *hostname, *path = NULL, *verb = NULL;
DWORD err = ERROR_OUTOFMEMORY, len, flags = 0, request_flags = 0;
DWORD err = ERROR_OUTOFMEMORY, len, flags = 0;
TRACE("%p, %s, %s, %s\n", request, debugstr_w(method), debugstr_w(url),
debugstr_variant(&async));
@ -3052,12 +3104,9 @@ static HRESULT WINAPI winhttp_request_Open(
if (!WinHttpCrackUrl( url, 0, 0, &uc )) return HRESULT_FROM_WIN32( get_last_error() );
EnterCriticalSection( &request->cs );
if (request->state != REQUEST_STATE_INITIALIZED)
{
cancel_request( request );
free_request( request );
initialize_request( request );
}
if (request->state < REQUEST_STATE_INITIALIZED) initialize_request( request );
else reset_request( request );
if (!(hostname = heap_alloc( (uc.dwHostNameLength + 1) * sizeof(WCHAR) ))) goto error;
memcpy( hostname, uc.lpszHostName, uc.dwHostNameLength * sizeof(WCHAR) );
hostname[uc.dwHostNameLength] = 0;
@ -3067,37 +3116,44 @@ static HRESULT WINAPI winhttp_request_Open(
path[uc.dwUrlPathLength + uc.dwExtraInfoLength] = 0;
if (!(verb = strdupW( method ))) goto error;
if (SUCCEEDED( VariantChangeType( &async, &async, 0, VT_BOOL )) && V_BOOL( &async )) flags |= WINHTTP_FLAG_ASYNC;
if (!(hsession = WinHttpOpen( user_agentW, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL, flags )))
{
err = get_last_error();
goto error;
}
if (!(hconnect = WinHttpConnect( hsession, hostname, uc.nPort, 0 )))
if (SUCCEEDED( VariantChangeType( &async, &async, 0, VT_BOOL )) && V_BOOL( &async )) request->async = TRUE;
else request->async = FALSE;
if (!request->hsession)
{
if (!(request->hsession = WinHttpOpen( user_agentW, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, NULL, NULL,
WINHTTP_FLAG_ASYNC )))
{
err = get_last_error();
goto error;
}
if (!(request->hconnect = WinHttpConnect( request->hsession, hostname, uc.nPort, 0 )))
{
WinHttpCloseHandle( request->hsession );
request->hsession = NULL;
err = get_last_error();
goto error;
}
}
else if (!(request->hconnect = WinHttpConnect( request->hsession, hostname, uc.nPort, 0 )))
{
err = get_last_error();
goto error;
}
len = sizeof(httpsW) / sizeof(WCHAR);
if (uc.dwSchemeLength == len && !memcmp( uc.lpszScheme, httpsW, len * sizeof(WCHAR) ))
{
request_flags |= WINHTTP_FLAG_SECURE;
flags |= WINHTTP_FLAG_SECURE;
}
if (!(hrequest = WinHttpOpenRequest( hconnect, method, path, NULL, NULL, acceptW, request_flags )))
if (!(request->hrequest = WinHttpOpenRequest( request->hconnect, method, path, NULL, NULL, acceptW, flags )))
{
err = get_last_error();
goto error;
}
if (flags & WINHTTP_FLAG_ASYNC)
{
request->wait = CreateEventW( NULL, FALSE, FALSE, NULL );
request->cancel = CreateEventW( NULL, FALSE, FALSE, NULL );
WinHttpSetOption( hrequest, WINHTTP_OPTION_CONTEXT_VALUE, &request, sizeof(request) );
}
WinHttpSetOption( request->hrequest, WINHTTP_OPTION_CONTEXT_VALUE, &request, sizeof(request) );
request->state = REQUEST_STATE_OPEN;
request->hsession = hsession;
request->hconnect = hconnect;
request->hrequest = hrequest;
request->verb = verb;
heap_free( hostname );
heap_free( path );
@ -3105,8 +3161,8 @@ static HRESULT WINAPI winhttp_request_Open(
return S_OK;
error:
WinHttpCloseHandle( hconnect );
WinHttpCloseHandle( hsession );
WinHttpCloseHandle( request->hconnect );
request->hconnect = NULL;
heap_free( hostname );
heap_free( path );
heap_free( verb );
@ -3148,7 +3204,8 @@ static HRESULT WINAPI winhttp_request_SetRequestHeader(
goto done;
}
sprintfW( str, fmtW, header, value ? value : emptyW );
if (!WinHttpAddRequestHeaders( request->hrequest, str, len, WINHTTP_ADDREQ_FLAG_REPLACE ))
if (!WinHttpAddRequestHeaders( request->hrequest, str, len,
WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE ))
{
err = get_last_error();
}
@ -3268,22 +3325,14 @@ static void CALLBACK wait_status_callback( HINTERNET handle, DWORD_PTR context,
static void wait_set_status_callback( struct winhttp_request *request, DWORD status )
{
if (!request->wait) return;
status |= WINHTTP_CALLBACK_STATUS_REQUEST_ERROR;
WinHttpSetStatusCallback( request->hrequest, wait_status_callback, status, 0 );
}
static DWORD wait_for_completion( struct winhttp_request *request )
{
HANDLE handles[2];
HANDLE handles[2] = { request->wait, request->cancel };
if (!request->wait)
{
request->error = ERROR_SUCCESS;
return ERROR_SUCCESS;
}
handles[0] = request->wait;
handles[1] = request->cancel;
switch (WaitForMultipleObjects( 2, handles, FALSE, INFINITE ))
{
case WAIT_OBJECT_0:
@ -3466,6 +3515,39 @@ static DWORD CALLBACK send_and_receive_proc( void *arg )
return request_send_and_receive( request );
}
/* critical section must be held */
static DWORD request_wait( struct winhttp_request *request, DWORD timeout )
{
HANDLE thread = request->thread;
DWORD err, ret;
LeaveCriticalSection( &request->cs );
while ((err = MsgWaitForMultipleObjects( 1, &thread, FALSE, timeout, QS_ALLINPUT )) == WAIT_OBJECT_0 + 1)
{
MSG msg;
while (PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessageW( &msg );
}
}
switch (err)
{
case WAIT_OBJECT_0:
ret = ERROR_SUCCESS;
break;
case WAIT_TIMEOUT:
ret = ERROR_TIMEOUT;
break;
case WAIT_FAILED:
default:
ret = get_last_error();
break;
}
EnterCriticalSection( &request->cs );
return ret;
}
static HRESULT WINAPI winhttp_request_Send(
IWinHttpRequest *iface,
VARIANT body )
@ -3487,20 +3569,22 @@ static HRESULT WINAPI winhttp_request_Send(
return S_OK;
}
VariantClear( &request->data );
if ((hr = VariantCopyInd( &request->data, &body )) != S_OK) {
if ((hr = VariantCopyInd( &request->data, &body )) != S_OK)
{
LeaveCriticalSection( &request->cs );
return hr;
}
if (request->wait) /* async request */
if (!(request->thread = CreateThread( NULL, 0, send_and_receive_proc, request, 0, NULL )))
{
if (!(request->thread = CreateThread( NULL, 0, send_and_receive_proc, request, 0, NULL )))
{
LeaveCriticalSection( &request->cs );
return HRESULT_FROM_WIN32( get_last_error() );
}
LeaveCriticalSection( &request->cs );
return HRESULT_FROM_WIN32( get_last_error() );
}
request->wait = CreateEventW( NULL, FALSE, FALSE, NULL );
request->cancel = CreateEventW( NULL, FALSE, FALSE, NULL );
if (!request->async)
{
hr = HRESULT_FROM_WIN32( request_wait( request, INFINITE ) );
}
else hr = request_send_and_receive( request );
LeaveCriticalSection( &request->cs );
return hr;
}
@ -3923,39 +4007,6 @@ static HRESULT WINAPI winhttp_request_put_Option(
return hr;
}
/* critical section must be held */
static DWORD wait_for_response( struct winhttp_request *request, DWORD timeout )
{
HANDLE thread = request->thread;
DWORD err, ret;
LeaveCriticalSection( &request->cs );
while ((err = MsgWaitForMultipleObjects( 1, &thread, FALSE, timeout, QS_ALLINPUT )) == WAIT_OBJECT_0 + 1)
{
MSG msg;
while (PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ))
{
TranslateMessage( &msg );
DispatchMessageW( &msg );
}
}
switch (err)
{
case WAIT_OBJECT_0:
ret = ERROR_SUCCESS;
break;
case WAIT_TIMEOUT:
ret = ERROR_TIMEOUT;
break;
case WAIT_FAILED:
default:
ret = get_last_error();
break;
}
EnterCriticalSection( &request->cs );
return ret;
}
static HRESULT WINAPI winhttp_request_WaitForResponse(
IWinHttpRequest *iface,
VARIANT timeout,
@ -3967,17 +4018,12 @@ static HRESULT WINAPI winhttp_request_WaitForResponse(
TRACE("%p, %s, %p\n", request, debugstr_variant(&timeout), succeeded);
EnterCriticalSection( &request->cs );
if (!request->thread)
{
LeaveCriticalSection( &request->cs );
return S_OK;
}
if (request->state >= REQUEST_STATE_RESPONSE_RECEIVED)
{
LeaveCriticalSection( &request->cs );
return S_OK;
}
switch ((err = wait_for_response( request, msecs )))
switch ((err = request_wait( request, msecs )))
{
case ERROR_TIMEOUT:
if (succeeded) *succeeded = VARIANT_FALSE;

View file

@ -535,7 +535,7 @@ end:
static void request_destroy( object_header_t *hdr )
{
request_t *request = (request_t *)hdr;
unsigned int i;
unsigned int i, j;
TRACE("%p\n", request);
@ -546,6 +546,7 @@ static void request_destroy( object_header_t *hdr )
CloseHandle( request->task_thread );
CloseHandle( request->task_cancel );
CloseHandle( request->task_wait );
request->task_cs.DebugInfo->Spare[0] = 0;
DeleteCriticalSection( &request->task_cs );
}
release_object( &request->connect->hdr );
@ -566,6 +567,14 @@ static void request_destroy( object_header_t *hdr )
heap_free( request->headers );
for (i = 0; i < request->num_accept_types; i++) heap_free( request->accept_types[i] );
heap_free( request->accept_types );
for (i = 0; i < TARGET_MAX; i++)
{
for (j = 0; j < SCHEME_MAX; j++)
{
heap_free( request->creds[i][j].username );
heap_free( request->creds[i][j].password );
}
}
heap_free( request );
}
@ -1310,7 +1319,8 @@ static BOOL get_system_proxy_autoconfig_url( char *buf, DWORD buflen )
CFRelease( settings );
return ret;
#else
FIXME( "no support on this platform\n" );
static int once;
if (!once++) FIXME( "no support on this platform\n" );
return FALSE;
#endif
}

View file

@ -163,6 +163,14 @@ typedef struct
BOOL is_request; /* part of request headers? */
} header_t;
enum auth_target
{
TARGET_INVALID = -1,
TARGET_SERVER,
TARGET_PROXY,
TARGET_MAX
};
enum auth_scheme
{
SCHEME_INVALID = -1,
@ -170,7 +178,8 @@ enum auth_scheme
SCHEME_NTLM,
SCHEME_PASSPORT,
SCHEME_DIGEST,
SCHEME_NEGOTIATE
SCHEME_NEGOTIATE,
SCHEME_MAX
};
struct authinfo
@ -221,6 +230,11 @@ typedef struct
HANDLE task_thread;
struct list task_queue;
CRITICAL_SECTION task_cs;
struct
{
WCHAR *username;
WCHAR *password;
} creds[TARGET_MAX][SCHEME_MAX];
} request_t;
typedef struct _task_header_t task_header_t;

View file

@ -1,6 +1,6 @@
diff -pudN e:\wine\dlls\winhttp/net.c dll\win32\winhttp/net.c
diff -pudN e:\wine\dlls\winhttp/net.c e:\reactos\dll\win32\winhttp/net.c
--- e:\wine\dlls\winhttp/net.c 2015-02-21 17:13:15.365542100 +0100
+++ dll\win32\winhttp/net.c 2015-04-09 13:48:12.485050200 +0100
+++ e:\reactos\dll\win32\winhttp/net.c 2015-07-20 14:25:14.321893000 +0100
@@ -73,6 +50,7 @@ static CRITICAL_SECTION cs_gethostbyname
#endif
@ -25,18 +25,15 @@ diff -pudN e:\wine\dlls\winhttp/net.c dll\win32\winhttp/net.c
static int sock_send(int fd, const void *msg, size_t len, int flags)
{
@@ -366,11 +353,17 @@ BOOL netconn_connect( netconn_t *conn, c
@@ -366,11 +353,25 @@ BOOL netconn_connect( netconn_t *conn, c
res = sock_get_error( errno );
if (res == WSAEWOULDBLOCK || res == WSAEINPROGRESS)
{
- struct pollfd pfd;
+#ifdef __REACTOS__
+ /* ReactOS: use select instead of poll */
+ fd_set outfd;
+ struct timeval tv;
- pfd.fd = conn->socket;
- pfd.events = POLLOUT;
- if (poll( &pfd, 1, timeout ) > 0)
+
+ FD_ZERO(&outfd);
+ FD_SET(conn->socket, &outfd);
+
@ -44,13 +41,20 @@ diff -pudN e:\wine\dlls\winhttp/net.c dll\win32\winhttp/net.c
+ tv.tv_usec = timeout * 1000;
+
+ if (select( 0, NULL, &outfd, NULL, &tv ) > 0)
+#else
struct pollfd pfd;
pfd.fd = conn->socket;
pfd.events = POLLOUT;
if (poll( &pfd, 1, timeout ) > 0)
+#endif
ret = TRUE;
else
res = sock_get_error( errno );
diff -pudN e:\wine\dlls\winhttp/request.c dll\win32\winhttp/request.c
--- e:\wine\dlls\winhttp/request.c 2015-02-22 13:25:32.479716600 +0100
+++ dll\win32\winhttp/request.c 2015-04-09 13:49:32.753638400 +0100
@@ -1275,6 +1264,7 @@ BOOL WINAPI WinHttpSendRequest( HINTERNE
diff -pudN e:\wine\dlls\winhttp/request.c e:\reactos\dll\win32\winhttp/request.c
--- e:\wine\dlls\winhttp/request.c 2015-07-14 15:44:36.027191600 +0100
+++ e:\reactos\dll\win32\winhttp/request.c 2015-07-20 14:28:31.803188200 +0100
@@ -1263,6 +1252,7 @@ BOOL WINAPI WinHttpSendRequest( HINTERNE
return ret;
}
@ -58,7 +62,7 @@ diff -pudN e:\wine\dlls\winhttp/request.c dll\win32\winhttp/request.c
#define ARRAYSIZE(array) (sizeof(array) / sizeof((array)[0]))
static const WCHAR basicW[] = {'B','a','s','i','c',0};
@@ -2722,8 +2712,8 @@ static void free_request( struct winhttp
@@ -2754,8 +2744,8 @@ static void free_request( struct winhttp
CloseHandle( request->thread );
CloseHandle( request->wait );
CloseHandle( request->cancel );
@ -69,7 +73,7 @@ diff -pudN e:\wine\dlls\winhttp/request.c dll\win32\winhttp/request.c
heap_free( request->buffer );
heap_free( request->verb );
VariantClear( &request->data );
@@ -2927,16 +2917,16 @@ static HRESULT WINAPI winhttp_request_Se
@@ -2959,16 +2949,16 @@ static HRESULT WINAPI winhttp_request_Se
{
case HTTPREQUEST_PROXYSETTING_DEFAULT:
request->proxy.dwAccessType = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
@ -90,7 +94,7 @@ diff -pudN e:\wine\dlls\winhttp/request.c dll\win32\winhttp/request.c
request->proxy.lpszProxy = NULL;
request->proxy.lpszProxyBypass = NULL;
break;
@@ -2945,12 +2935,12 @@ static HRESULT WINAPI winhttp_request_Se
@@ -2977,12 +2967,12 @@ static HRESULT WINAPI winhttp_request_Se
request->proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
if (V_VT( &proxy_server ) == VT_BSTR)
{
@ -105,9 +109,9 @@ diff -pudN e:\wine\dlls\winhttp/request.c dll\win32\winhttp/request.c
request->proxy.lpszProxyBypass = strdupW( V_BSTR( &bypass_list ) );
}
break;
diff -pudN e:\wine\dlls\winhttp/session.c dll\win32\winhttp/session.c
--- e:\wine\dlls\winhttp/session.c 2015-02-22 13:25:32.480717300 +0100
+++ dll\win32\winhttp/session.c 2015-04-09 13:50:02.955100200 +0100
diff -pudN e:\wine\dlls\winhttp/session.c e:\reactos\dll\win32\winhttp/session.c
--- e:\wine\dlls\winhttp/session.c 2015-07-14 15:44:36.029191700 +0100
+++ e:\reactos\dll\win32\winhttp/session.c 2015-07-20 14:29:15.686698200 +0100
@@ -109,6 +81,9 @@ static void session_destroy( object_head
heap_free( session->proxy_username );
heap_free( session->proxy_password );
@ -149,7 +153,7 @@ diff -pudN e:\wine\dlls\winhttp/session.c dll\win32\winhttp/session.c
goto end;
}
}
@@ -615,7 +595,7 @@ static WCHAR *blob_to_str( DWORD encodin
@@ -624,7 +604,7 @@ static WCHAR *blob_to_str( DWORD encodin
static BOOL convert_sockaddr( const struct sockaddr *addr, SOCKADDR_STORAGE *addr_storage )
{

View file

@ -206,7 +206,7 @@ reactos/dll/win32/windowscodecs # Synced to WineStaging-1.7.47
reactos/dll/win32/windowscodecsext # Synced to WineStaging-1.7.37
reactos/dll/win32/winemp3.acm # Synced to WineStaging-1.7.47
reactos/dll/win32/wing32 # Out of sync
reactos/dll/win32/winhttp # Synced to WineStaging-1.7.37
reactos/dll/win32/winhttp # Synced to WineStaging-1.7.47
reactos/dll/win32/wininet # Synced to WineStaging-1.7.37
reactos/dll/win32/winmm # Forked at Wine-20050628
reactos/dll/win32/winmm/midimap # Forked at Wine-20050628