winhttp: Add support for resolve timeouts.
authorHans Leidekker <hans@codeweavers.com>
Mon, 22 Feb 2010 11:27:30 +0000 (12:27 +0100)
committerAlexandre Julliard <julliard@winehq.org>
Mon, 22 Feb 2010 12:15:56 +0000 (13:15 +0100)
dlls/winhttp/net.c
dlls/winhttp/request.c
dlls/winhttp/session.c
dlls/winhttp/tests/winhttp.c
dlls/winhttp/winhttp_private.h

index dd8b56c65021ecb20a580fc68970e08b9bd7d6c9..455ee55580a04ca32cdd39cb3002aab60424007a 100644 (file)
@@ -867,7 +867,7 @@ DWORD netconn_set_timeout( netconn_t *netconn, BOOL send, int value )
     return ERROR_SUCCESS;
 }
 
-BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len )
+static DWORD resolve_hostname( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len )
 {
     char *hostname;
 #ifdef HAVE_GETADDRINFO
@@ -878,7 +878,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
     struct sockaddr_in *sin = (struct sockaddr_in *)sa;
 #endif
 
-    if (!(hostname = strdupWA( hostnameW ))) return FALSE;
+    if (!(hostname = strdupWA( hostnameW ))) return ERROR_OUTOFMEMORY;
 
 #ifdef HAVE_GETADDRINFO
     memset( &hints, 0, sizeof(struct addrinfo) );
@@ -897,7 +897,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
         {
             TRACE("failed to get address of %s (%s)\n", debugstr_w(hostnameW), gai_strerror(ret));
             heap_free( hostname );
-            return FALSE;
+            return ERROR_WINHTTP_NAME_NOT_RESOLVED;
         }
     }
     heap_free( hostname );
@@ -905,7 +905,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
     {
         WARN("address too small\n");
         freeaddrinfo( res );
-        return FALSE;
+        return ERROR_WINHTTP_NAME_NOT_RESOLVED;
     }
     *sa_len = res->ai_addrlen;
     memcpy( sa, res->ai_addr, res->ai_addrlen );
@@ -921,7 +921,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
     }
 
     freeaddrinfo( res );
-    return TRUE;
+    return ERROR_SUCCESS;
 #else
     EnterCriticalSection( &cs_gethostbyname );
 
@@ -931,13 +931,13 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
     {
         TRACE("failed to get address of %s (%d)\n", debugstr_w(hostnameW), h_errno);
         LeaveCriticalSection( &cs_gethostbyname );
-        return FALSE;
+        return ERROR_WINHTTP_NAME_NOT_RESOLVED;
     }
     if (*sa_len < sizeof(struct sockaddr_in))
     {
         WARN("address too small\n");
         LeaveCriticalSection( &cs_gethostbyname );
-        return FALSE;
+        return ERROR_WINHTTP_NAME_NOT_RESOLVED;
     }
     *sa_len = sizeof(struct sockaddr_in);
     memset( sa, 0, sizeof(struct sockaddr_in) );
@@ -946,10 +946,57 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
     sin->sin_port = htons( port );
 
     LeaveCriticalSection( &cs_gethostbyname );
-    return TRUE;
+    return ERROR_SUCCESS;
 #endif
 }
 
+struct resolve_args
+{
+    WCHAR           *hostname;
+    INTERNET_PORT    port;
+    struct sockaddr *sa;
+    socklen_t       *sa_len;
+};
+
+static DWORD CALLBACK resolve_proc( LPVOID arg )
+{
+    struct resolve_args *ra = arg;
+    return resolve_hostname( ra->hostname, ra->port, ra->sa, ra->sa_len );
+}
+
+BOOL netconn_resolve( WCHAR *hostname, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len, int timeout )
+{
+    DWORD ret;
+
+    if (timeout)
+    {
+        DWORD status;
+        HANDLE thread;
+        struct resolve_args ra;
+
+        ra.hostname = hostname;
+        ra.port     = port;
+        ra.sa       = sa;
+        ra.sa_len   = sa_len;
+
+        thread = CreateThread( NULL, 0, resolve_proc, &ra, 0, NULL );
+        if (!thread) return FALSE;
+
+        status = WaitForSingleObject( thread, timeout );
+        if (status == WAIT_OBJECT_0) GetExitCodeThread( thread, &ret );
+        else ret = ERROR_WINHTTP_TIMEOUT;
+        CloseHandle( thread );
+    }
+    else ret = resolve_hostname( hostname, port, sa, sa_len );
+
+    if (ret)
+    {
+        set_last_error( ret );
+        return FALSE;
+    }
+    return TRUE;
+}
+
 const void *netconn_get_certificate( netconn_t *conn )
 {
 #ifdef SONAME_LIBSSL
index 8bb825cb1d0b6bda8dab660e6a0a8248308719bd..65d9e558ad108d9844abf9399d52adb7735cd116 100644 (file)
@@ -911,7 +911,7 @@ static BOOL open_connection( request_t *request )
     send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME, connect->servername, strlenW(connect->servername) + 1 );
 
     slen = sizeof(connect->sockaddr);
-    if (!netconn_resolve( connect->servername, port, (struct sockaddr *)&connect->sockaddr, &slen )) return FALSE;
+    if (!netconn_resolve( connect->servername, port, (struct sockaddr *)&connect->sockaddr, &slen, request->resolve_timeout )) return FALSE;
     switch (connect->sockaddr.ss_family)
     {
     case AF_INET:
index 499321617b3afa362b05bbfdb2737c1ceebee3d7..cd5ebed65e996591ff130ee67c7003199bf2d17b 100644 (file)
@@ -33,6 +33,7 @@
 
 WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
 
+#define DEFAULT_RESOLVE_TIMEOUT     0
 #define DEFAULT_CONNECT_TIMEOUT     20000
 #define DEFAULT_SEND_TIMEOUT        30000
 #define DEFAULT_RECEIVE_TIMEOUT     30000
@@ -108,6 +109,10 @@ static BOOL session_query_option( object_header_t *hdr, DWORD option, LPVOID buf
         *buflen = sizeof(DWORD);
         return TRUE;
     }
+    case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        *(DWORD *)buffer = session->resolve_timeout;
+        *buflen = sizeof(DWORD);
+        return TRUE;
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
         *(DWORD *)buffer = session->connect_timeout;
         *buflen = sizeof(DWORD);
@@ -158,6 +163,9 @@ static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
     case WINHTTP_OPTION_DISABLE_FEATURE:
         set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE );
         return FALSE;
+    case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        session->resolve_timeout = *(DWORD *)buffer;
+        return TRUE;
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
         session->connect_timeout = *(DWORD *)buffer;
         return TRUE;
@@ -198,6 +206,7 @@ HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWST
     session->hdr.flags = flags;
     session->hdr.refs = 1;
     session->hdr.redirect_policy = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP;
+    session->resolve_timeout = DEFAULT_RESOLVE_TIMEOUT;
     session->connect_timeout = DEFAULT_CONNECT_TIMEOUT;
     session->send_timeout = DEFAULT_SEND_TIMEOUT;
     session->recv_timeout = DEFAULT_RECEIVE_TIMEOUT;
@@ -276,6 +285,10 @@ static BOOL connect_query_option( object_header_t *hdr, DWORD option, LPVOID buf
         *buflen = sizeof(HINTERNET);
         return TRUE;
     }
+    case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        *(DWORD *)buffer = connect->session->resolve_timeout;
+        *buflen = sizeof(DWORD);
+        return TRUE;
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
         *(DWORD *)buffer = connect->session->connect_timeout;
         *buflen = sizeof(DWORD);
@@ -586,6 +599,10 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
         *buflen = sizeof(DWORD);
         return TRUE;
     }
+    case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        *(DWORD *)buffer = request->resolve_timeout;
+        *buflen = sizeof(DWORD);
+        return TRUE;
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
         *(DWORD *)buffer = request->connect_timeout;
         *buflen = sizeof(DWORD);
@@ -667,6 +684,9 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
         FIXME("WINHTTP_OPTION_SECURITY_FLAGS unimplemented (%08x)\n",
               *(DWORD *)buffer);
         return TRUE;
+    case WINHTTP_OPTION_RESOLVE_TIMEOUT:
+        request->resolve_timeout = *(DWORD *)buffer;
+        return TRUE;
     case WINHTTP_OPTION_CONNECT_TIMEOUT:
         request->connect_timeout = *(DWORD *)buffer;
         return TRUE;
@@ -732,6 +752,7 @@ HINTERNET WINAPI WinHttpOpenRequest( HINTERNET hconnect, LPCWSTR verb, LPCWSTR o
     list_add_head( &connect->hdr.children, &request->hdr.entry );
 
     if (!netconn_init( &request->netconn, request->hdr.flags & WINHTTP_FLAG_SECURE )) goto end;
+    request->resolve_timeout = connect->session->resolve_timeout;
     request->connect_timeout = connect->session->connect_timeout;
     request->send_timeout = connect->session->send_timeout;
     request->recv_timeout = connect->session->recv_timeout;
@@ -1266,9 +1287,6 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
         return FALSE;
     }
 
-    if (resolve > 0)
-        FIXME("resolve timeout (%d) not supported\n", resolve);
-
     if (!(hdr = grab_object( handle )))
     {
         set_last_error( ERROR_INVALID_HANDLE );
@@ -1281,6 +1299,9 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
             request = (request_t *)hdr;
             request->connect_timeout = connect;
 
+            if (resolve < 0) resolve = 0;
+            request->resolve_timeout = resolve;
+
             if (send < 0) send = 0;
             request->send_timeout = send;
 
@@ -1300,6 +1321,9 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
             session = (session_t *)hdr;
             session->connect_timeout = connect;
 
+            if (resolve < 0) resolve = 0;
+            session->resolve_timeout = resolve;
+
             if (send < 0) send = 0;
             session->send_timeout = send;
 
index 3824f83f9b99e6c5744e79e114706f1301e76707..94346e258ecf1bf0c649e1a7688bfc82cb24ec77 100644 (file)
@@ -1074,6 +1074,13 @@ static void test_Timeouts (void)
     ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef);
     ok(ret, "%u\n", GetLastError());
 
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xdeadbeef;
     size  = sizeof(DWORD);
@@ -1095,6 +1102,18 @@ static void test_Timeouts (void)
     ok(ret, "%u\n", GetLastError());
     ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
 
+    SetLastError(0xdeadbeef);
+    value = 0;
+    ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(ret, "%u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0, "Expected 0, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0;
     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1131,6 +1150,18 @@ static void test_Timeouts (void)
     ok(ret, "%u\n", GetLastError());
     ok(value == 0, "Expected 0, got %u\n", value);
 
+    SetLastError(0xdeadbeef);
+    value = 0xbeefdead;
+    ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(ret, "%u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xbeefdead;
     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1171,6 +1202,13 @@ static void test_Timeouts (void)
     ok(con != NULL, "failed to open a connection %u\n", GetLastError());
 
     /* Timeout values should match the last one set for session */
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xdeadbeef;
     size  = sizeof(DWORD);
@@ -1222,6 +1260,12 @@ static void test_Timeouts (void)
     ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
 
+    SetLastError(0xdeadbeef);
+    value = 0;
+    ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE,
+       "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
+
     SetLastError(0xdeadbeef);
     value = 0;
     ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1241,6 +1285,18 @@ static void test_Timeouts (void)
        "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
 
     /* Changing timeout values for session should affect the values for connection */
+    SetLastError(0xdeadbeef);
+    value = 0xdead;
+    ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(ret, "%u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xdead;
     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1281,6 +1337,13 @@ static void test_Timeouts (void)
     ok(req != NULL, "failed to open a request %u\n", GetLastError());
 
     /* Timeout values should match the last one set for session */
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xdeadbeef;
     size  = sizeof(DWORD);
@@ -1334,6 +1397,13 @@ static void test_Timeouts (void)
     ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123);
     ok(ret, "%u\n", GetLastError());
 
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xdeadbeef;
     size  = sizeof(DWORD);
@@ -1355,6 +1425,18 @@ static void test_Timeouts (void)
     ok(ret, "%u\n", GetLastError());
     ok(value == 0x0123, "Expected 0x0123, got %u\n", value);
 
+    SetLastError(0xdeadbeef);
+    value = 0;
+    ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(ret, "%u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0, "Expected 0, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0;
     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1391,6 +1473,18 @@ static void test_Timeouts (void)
     ok(ret, "%u\n", GetLastError());
     ok(value == 0, "Expected 0, got %u\n", value);
 
+    SetLastError(0xdeadbeef);
+    value = 0xbeefdead;
+    ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(ret, "%u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xbeefdead;
     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1430,6 +1524,18 @@ static void test_Timeouts (void)
     /* Changing timeout values for session should not affect the values for a request,
      * neither should the other way around.
      */
+    SetLastError(0xdeadbeef);
+    value = 0xbeefdead;
+    ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(ret, "%u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xbeefdead;
     ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1466,6 +1572,18 @@ static void test_Timeouts (void)
     ok(ret, "%u\n", GetLastError());
     ok(value == 0xdead, "Expected 0xdead, got %u\n", value);
 
+    SetLastError(0xdeadbeef);
+    value = 0xbeef;
+    ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value));
+    ok(ret, "%u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    value = 0xdeadbeef;
+    size  = sizeof(DWORD);
+    ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size);
+    ok(ret, "%u\n", GetLastError());
+    ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value);
+
     SetLastError(0xdeadbeef);
     value = 0xbeef;
     ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value));
@@ -1507,6 +1625,58 @@ static void test_Timeouts (void)
     WinHttpCloseHandle(ses);
 }
 
+static void test_resolve_timeout(void)
+{
+    static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
+    static const WCHAR srevaewedoc[] = {'s','r','e','v','a','e','w','e','d','o','c','.','m','o','c',0};
+
+    HANDLE ses, con, req;
+    DWORD timeout;
+    BOOL ret;
+
+    ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
+    ok(ses != NULL, "failed to open session %u\n", GetLastError());
+
+    timeout = 10000;
+    ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
+    ok(ret, "failed to set resolve timeout %u\n", GetLastError());
+
+    con = WinHttpConnect(ses, srevaewedoc, 0, 0);
+    ok(con != NULL, "failed to open a connection %u\n", GetLastError());
+
+    req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
+    ok(req != NULL, "failed to open a request %u\n", GetLastError());
+
+    SetLastError(0xdeadbeef);
+    ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
+    ok(!ret, "sent request\n");
+    ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED, "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", ret);
+
+    WinHttpCloseHandle(req);
+    WinHttpCloseHandle(con);
+    WinHttpCloseHandle(ses);
+
+    ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
+    ok(ses != NULL, "failed to open session %u\n", GetLastError());
+
+    timeout = 10000;
+    ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout));
+    ok(ret, "failed to set resolve timeout %u\n", GetLastError());
+
+    con = WinHttpConnect(ses, codeweavers, 0, 0);
+    ok(con != NULL, "failed to open a connection %u\n", GetLastError());
+
+    req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
+    ok(req != NULL, "failed to open a request %u\n", GetLastError());
+
+    ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
+    ok(ret, "failed to send request\n");
+
+    WinHttpCloseHandle(req);
+    WinHttpCloseHandle(con);
+    WinHttpCloseHandle(ses);
+}
+
 START_TEST (winhttp)
 {
     test_OpenRequest();
@@ -1520,4 +1690,5 @@ START_TEST (winhttp)
     test_set_default_proxy_config();
     test_empty_headers_param();
     test_Timeouts();
+    test_resolve_timeout();
 }
index 1054a42951e9f6df98b70de3df5e7f8ab906f76e..abf5f8a85cad8ee392bb16e00a6cc6e4ebb81836 100644 (file)
@@ -96,6 +96,7 @@ typedef struct
     object_header_t hdr;
     LPWSTR agent;
     DWORD access;
+    int resolve_timeout;
     int connect_timeout;
     int send_timeout;
     int recv_timeout;
@@ -145,6 +146,7 @@ typedef struct
     LPWSTR version;
     LPWSTR raw_headers;
     netconn_t netconn;
+    int resolve_timeout;
     int connect_timeout;
     int send_timeout;
     int recv_timeout;
@@ -221,7 +223,7 @@ BOOL netconn_init( netconn_t *, BOOL );
 void netconn_unload( void );
 BOOL netconn_query_data_available( netconn_t *, DWORD * );
 BOOL netconn_recv( netconn_t *, void *, size_t, int, int * );
-BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr *, socklen_t * );
+BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr *, socklen_t *, int );
 BOOL netconn_secure_connect( netconn_t *, WCHAR * );
 BOOL netconn_send( netconn_t *, const void *, size_t, int, int * );
 DWORD netconn_set_timeout( netconn_t *, BOOL, int );