Commit 7d8730f8 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

winhttp: Resolve the server name only on the first request.

parent c724a615
...@@ -909,53 +909,68 @@ static BOOL secure_proxy_connect( request_t *request ) ...@@ -909,53 +909,68 @@ static BOOL secure_proxy_connect( request_t *request )
#define INET6_ADDRSTRLEN 46 #define INET6_ADDRSTRLEN 46
#endif #endif
static WCHAR *addr_to_str( const struct sockaddr *addr )
{
char buf[INET6_ADDRSTRLEN];
const void *src;
switch (addr->sa_family)
{
case AF_INET:
src = &((struct sockaddr_in *)addr)->sin_addr;
break;
case AF_INET6:
src = &((struct sockaddr_in6 *)addr)->sin6_addr;
break;
default:
WARN("unsupported address family %d\n", addr->sa_family);
return NULL;
}
if (!inet_ntop( addr->sa_family, src, buf, sizeof(buf) )) return NULL;
return strdupAW( buf );
}
static BOOL open_connection( request_t *request ) static BOOL open_connection( request_t *request )
{ {
connect_t *connect; connect_t *connect;
const void *addr; WCHAR *addressW = NULL;
char address[INET6_ADDRSTRLEN];
WCHAR *addressW;
INTERNET_PORT port; INTERNET_PORT port;
socklen_t slen; socklen_t slen;
struct sockaddr *saddr;
DWORD len;
if (netconn_connected( &request->netconn )) return TRUE; if (netconn_connected( &request->netconn )) return TRUE;
connect = request->connect; connect = request->connect;
port = connect->serverport ? connect->serverport : (request->hdr.flags & WINHTTP_FLAG_SECURE ? 443 : 80); port = connect->serverport ? connect->serverport : (request->hdr.flags & WINHTTP_FLAG_SECURE ? 443 : 80);
saddr = (struct sockaddr *)&connect->sockaddr;
slen = sizeof(struct sockaddr);
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME, connect->servername, strlenW(connect->servername) + 1 ); if (!connect->resolved)
slen = sizeof(connect->sockaddr);
if (!netconn_resolve( connect->servername, port, (struct sockaddr *)&connect->sockaddr, &slen, request->resolve_timeout )) return FALSE;
switch (connect->sockaddr.ss_family)
{ {
case AF_INET: len = strlenW( connect->servername ) + 1;
addr = &((struct sockaddr_in *)&connect->sockaddr)->sin_addr; send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME, connect->servername, len );
break;
case AF_INET6:
addr = &((struct sockaddr_in6 *)&connect->sockaddr)->sin6_addr;
break;
default:
WARN("unsupported address family %d\n", connect->sockaddr.ss_family);
return FALSE;
}
inet_ntop( connect->sockaddr.ss_family, addr, address, sizeof(address) );
addressW = strdupAW( address );
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED, addressW, strlenW(addressW) + 1 ); if (!netconn_resolve( connect->servername, port, saddr, &slen, request->resolve_timeout )) return FALSE;
connect->resolved = TRUE;
TRACE("connecting to %s:%u\n", address, port); if (!(addressW = addr_to_str( saddr ))) return FALSE;
len = strlenW( addressW ) + 1;
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED, addressW, len );
}
if (!addressW && !(addressW = addr_to_str( saddr ))) return FALSE;
TRACE("connecting to %s:%u\n", debugstr_w(addressW), port);
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER, addressW, 0 ); send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER, addressW, 0 );
if (!netconn_create( &request->netconn, connect->sockaddr.ss_family, SOCK_STREAM, 0 )) if (!netconn_create( &request->netconn, saddr->sa_family, SOCK_STREAM, 0 ))
{ {
heap_free( addressW ); heap_free( addressW );
return FALSE; return FALSE;
} }
netconn_set_timeout( &request->netconn, TRUE, request->send_timeout ); netconn_set_timeout( &request->netconn, TRUE, request->send_timeout );
netconn_set_timeout( &request->netconn, FALSE, request->recv_timeout ); netconn_set_timeout( &request->netconn, FALSE, request->recv_timeout );
if (!netconn_connect( &request->netconn, (struct sockaddr *)&connect->sockaddr, slen, request->connect_timeout )) if (!netconn_connect( &request->netconn, saddr, slen, request->connect_timeout ))
{ {
netconn_close( &request->netconn ); netconn_close( &request->netconn );
heap_free( addressW ); heap_free( addressW );
......
...@@ -423,7 +423,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT ...@@ -423,7 +423,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT
session->proxy_server, colon - session->proxy_server - 1 )) session->proxy_server, colon - session->proxy_server - 1 ))
{ {
heap_free( connect->servername ); heap_free( connect->servername );
connect->sockaddr.ss_family = 0xffff; connect->resolved = FALSE;
if (!(connect->servername = heap_alloc( if (!(connect->servername = heap_alloc(
(colon - session->proxy_server + 1) * sizeof(WCHAR) ))) (colon - session->proxy_server + 1) * sizeof(WCHAR) )))
{ {
...@@ -445,7 +445,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT ...@@ -445,7 +445,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT
session->proxy_server )) session->proxy_server ))
{ {
heap_free( connect->servername ); heap_free( connect->servername );
connect->sockaddr.ss_family = 0xffff; connect->resolved = FALSE;
if (!(connect->servername = strdupW( session->proxy_server ))) if (!(connect->servername = strdupW( session->proxy_server )))
{ {
ret = FALSE; ret = FALSE;
...@@ -458,7 +458,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT ...@@ -458,7 +458,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT
else if (server) else if (server)
{ {
heap_free( connect->servername ); heap_free( connect->servername );
connect->sockaddr.ss_family = 0xffff; connect->resolved = FALSE;
if (!(connect->servername = strdupW( server ))) if (!(connect->servername = strdupW( server )))
{ {
ret = FALSE; ret = FALSE;
......
...@@ -135,6 +135,16 @@ static const struct notification cache_test[] = ...@@ -135,6 +135,16 @@ static const struct notification cache_test[] =
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION, 0, 1 }, { winhttp_close_handle, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION, 0, 1 },
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED, 0, 1 }, { winhttp_close_handle, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED, 0, 1 },
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 0, 1 }, { winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 0, 1 },
{ winhttp_open_request, WINHTTP_CALLBACK_STATUS_HANDLE_CREATED, 0 },
{ winhttp_send_request, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER, 0 },
{ winhttp_send_request, WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER, 0 },
{ winhttp_send_request, WINHTTP_CALLBACK_STATUS_SENDING_REQUEST, 0 },
{ winhttp_send_request, WINHTTP_CALLBACK_STATUS_REQUEST_SENT, 0 },
{ winhttp_receive_response, WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE, 0 },
{ winhttp_receive_response, WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED, 0 },
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION, 0, 1 },
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED, 0, 1 },
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 0, 1 },
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 1, 1 }, { winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 1, 1 },
{ winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 1, 1 } { winhttp_close_handle, WINHTTP_CALLBACK_STATUS_HANDLE_CLOSING, 1, 1 }
}; };
...@@ -190,6 +200,32 @@ static void test_connection_cache( void ) ...@@ -190,6 +200,32 @@ static void test_connection_cache( void )
setup_test( &info, winhttp_close_handle, __LINE__ ); setup_test( &info, winhttp_close_handle, __LINE__ );
WinHttpCloseHandle( req ); WinHttpCloseHandle( req );
setup_test( &info, winhttp_open_request, __LINE__ );
req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
ok(req != NULL, "failed to open a request %u\n", GetLastError());
ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
ok(ret, "failed to set context value %u\n", GetLastError());
setup_test( &info, winhttp_send_request, __LINE__ );
ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
ok(ret, "failed to send request %u\n", GetLastError());
setup_test( &info, winhttp_receive_response, __LINE__ );
ret = WinHttpReceiveResponse( req, NULL );
ok(ret, "failed to receive response %u\n", GetLastError());
size = sizeof(status);
ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
ok(ret, "failed unexpectedly %u\n", GetLastError());
ok(status == 200, "request failed unexpectedly %u\n", status);
setup_test( &info, winhttp_close_handle, __LINE__ );
WinHttpCloseHandle( req );
setup_test( &info, winhttp_close_handle, __LINE__ );
WinHttpCloseHandle( req );
WinHttpCloseHandle( con ); WinHttpCloseHandle( con );
WinHttpCloseHandle( ses ); WinHttpCloseHandle( ses );
...@@ -231,6 +267,29 @@ static void test_connection_cache( void ) ...@@ -231,6 +267,29 @@ static void test_connection_cache( void )
setup_test( &info, winhttp_close_handle, __LINE__ ); setup_test( &info, winhttp_close_handle, __LINE__ );
WinHttpCloseHandle( req ); WinHttpCloseHandle( req );
setup_test( &info, winhttp_open_request, __LINE__ );
req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 );
ok(req != NULL, "failed to open a request %u\n", GetLastError());
ret = WinHttpSetOption( req, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(struct info *) );
ok(ret, "failed to set context value %u\n", GetLastError());
setup_test( &info, winhttp_send_request, __LINE__ );
ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 );
ok(ret, "failed to send request %u\n", GetLastError());
setup_test( &info, winhttp_receive_response, __LINE__ );
ret = WinHttpReceiveResponse( req, NULL );
ok(ret, "failed to receive response %u\n", GetLastError());
size = sizeof(status);
ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL );
ok(ret, "failed unexpectedly %u\n", GetLastError());
ok(status == 200, "request failed unexpectedly %u\n", status);
setup_test( &info, winhttp_close_handle, __LINE__ );
WinHttpCloseHandle( req );
WinHttpCloseHandle( con ); WinHttpCloseHandle( con );
WinHttpCloseHandle( ses ); WinHttpCloseHandle( ses );
} }
......
...@@ -119,6 +119,7 @@ typedef struct ...@@ -119,6 +119,7 @@ typedef struct
INTERNET_PORT hostport; INTERNET_PORT hostport;
INTERNET_PORT serverport; INTERNET_PORT serverport;
struct sockaddr_storage sockaddr; struct sockaddr_storage sockaddr;
BOOL resolved;
} connect_t; } connect_t;
typedef struct typedef struct
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment