winhttp: Resolve the server name only on the first request.
Hans Leidekker
hans at codeweavers.com
Thu Nov 24 04:31:56 CST 2011
---
dlls/winhttp/request.c | 29 ++++++++++++-----
dlls/winhttp/session.c | 3 ++
dlls/winhttp/tests/notification.c | 59 +++++++++++++++++++++++++++++++++++++
3 files changed, 82 insertions(+), 9 deletions(-)
diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index 257fc97..daec731 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -917,23 +917,32 @@ static BOOL open_connection( request_t *request )
WCHAR *addressW;
INTERNET_PORT port;
socklen_t slen;
+ struct sockaddr *saddr;
+ BOOL resolved = FALSE;
+ DWORD len;
if (netconn_connected( &request->netconn )) return TRUE;
connect = request->connect;
port = connect->serverport ? connect->serverport : (request->hdr.flags & WINHTTP_FLAG_SECURE ? 443 : 80);
+ saddr = (struct sockaddr *)&connect->sockaddr;
+ slen = sizeof(connect->sockaddr);
- send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME, connect->servername, strlenW(connect->servername) + 1 );
+ if (connect->sockaddr.ss_family == 0xffff)
+ {
+ len = strlenW( connect->servername ) + 1;
+ send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME, connect->servername, len );
- slen = sizeof(connect->sockaddr);
- if (!netconn_resolve( connect->servername, port, (struct sockaddr *)&connect->sockaddr, &slen, request->resolve_timeout )) return FALSE;
+ if (!netconn_resolve( connect->servername, port, saddr, &slen, request->resolve_timeout )) return FALSE;
+ resolved = TRUE;
+ }
switch (connect->sockaddr.ss_family)
{
case AF_INET:
- addr = &((struct sockaddr_in *)&connect->sockaddr)->sin_addr;
+ addr = &((struct sockaddr_in *)saddr)->sin_addr;
break;
case AF_INET6:
- addr = &((struct sockaddr_in6 *)&connect->sockaddr)->sin6_addr;
+ addr = &((struct sockaddr_in6 *)saddr)->sin6_addr;
break;
default:
WARN("unsupported address family %d\n", connect->sockaddr.ss_family);
@@ -941,9 +950,11 @@ static BOOL open_connection( request_t *request )
}
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 (resolved)
+ {
+ len = strlenW( addressW ) + 1;
+ send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_NAME_RESOLVED, addressW, len );
+ }
TRACE("connecting to %s:%u\n", address, port);
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER, addressW, 0 );
@@ -955,7 +966,7 @@ static BOOL open_connection( request_t *request )
}
netconn_set_timeout( &request->netconn, TRUE, request->send_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 );
heap_free( addressW );
diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c
index f33508e..41d84e4 100644
--- a/dlls/winhttp/session.c
+++ b/dlls/winhttp/session.c
@@ -423,6 +423,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT
session->proxy_server, colon - session->proxy_server - 1 ))
{
heap_free( connect->servername );
+ connect->sockaddr.ss_family = 0xffff;
if (!(connect->servername = heap_alloc(
(colon - session->proxy_server + 1) * sizeof(WCHAR) )))
{
@@ -444,6 +445,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT
session->proxy_server ))
{
heap_free( connect->servername );
+ connect->sockaddr.ss_family = 0xffff;
if (!(connect->servername = strdupW( session->proxy_server )))
{
ret = FALSE;
@@ -456,6 +458,7 @@ BOOL set_server_for_hostname( connect_t *connect, LPCWSTR server, INTERNET_PORT
else if (server)
{
heap_free( connect->servername );
+ connect->sockaddr.ss_family = 0xffff;
if (!(connect->servername = strdupW( server )))
{
ret = FALSE;
diff --git a/dlls/winhttp/tests/notification.c b/dlls/winhttp/tests/notification.c
index 7ceede7..84a3569 100644
--- a/dlls/winhttp/tests/notification.c
+++ b/dlls/winhttp/tests/notification.c
@@ -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_CONNECTION_CLOSED, 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 }
};
@@ -190,6 +200,32 @@ static void test_connection_cache( void )
setup_test( &info, winhttp_close_handle, __LINE__ );
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( ses );
@@ -231,6 +267,29 @@ static void test_connection_cache( void )
setup_test( &info, winhttp_close_handle, __LINE__ );
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( ses );
}
--
1.7.5.4
More information about the wine-patches
mailing list