[PATCH 3/3] winhttp: Also select for error in netconn_create().

Paul Gofman pgofman at codeweavers.com
Mon Mar 14 05:27:06 CDT 2022


Signed-off-by: Paul Gofman <pgofman at codeweavers.com>
---
     Avoid waiting full timeout in case connection has failed earlier.

 dlls/winhttp/net.c           | 14 +++++++++----
 dlls/winhttp/tests/winhttp.c | 38 +++++++++++++++++++++++++++++++++++-
 2 files changed, 47 insertions(+), 5 deletions(-)

diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c
index 5e4c55fad6a..2fc48476513 100644
--- a/dlls/winhttp/net.c
+++ b/dlls/winhttp/net.c
@@ -228,13 +228,19 @@ DWORD netconn_create( struct hostdata *host, const struct sockaddr_storage *sock
         ret = WSAGetLastError();
         if (ret == WSAEWOULDBLOCK || ret == WSAEINPROGRESS)
         {
-            FD_SET set;
             TIMEVAL timeval = { timeout / 1000, (timeout % 1000) * 1000 };
+            FD_SET set_read, set_error;
             int res;
 
-            FD_ZERO( &set );
-            FD_SET( conn->socket, &set );
-            if ((res = select( conn->socket + 1, NULL, &set, NULL, &timeval )) > 0) ret = ERROR_SUCCESS;
+            FD_ZERO( &set_read );
+            FD_SET( conn->socket, &set_read );
+            FD_ZERO( &set_error );
+            FD_SET( conn->socket, &set_error );
+            if ((res = select( conn->socket + 1, NULL, &set_read, &set_error, &timeval )) > 0)
+            {
+                if (FD_ISSET(conn->socket, &set_read)) ret = ERROR_SUCCESS;
+                else                                   assert( FD_ISSET(conn->socket, &set_error) );
+            }
             else if (!res) ret = ERROR_WINHTTP_TIMEOUT;
         }
     }
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c
index 9dc8ece3069..0365eef1ca7 100644
--- a/dlls/winhttp/tests/winhttp.c
+++ b/dlls/winhttp/tests/winhttp.c
@@ -389,7 +389,7 @@ static void test_WinHttpSendRequest (void)
         WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
     ok(session != NULL, "WinHttpOpen failed to open session.\n");
 
-    connection = WinHttpConnect (session, L"test.winehq.org", INTERNET_DEFAULT_HTTP_PORT, 0);
+    connection = WinHttpConnect (session, L"127.0.0.1", INTERNET_DEFAULT_HTTP_PORT, 0);
     ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %lu\n", GetLastError());
 
     request = WinHttpOpenRequest(connection, L"POST", L"tests/post.php", NULL, WINHTTP_NO_REFERER,
@@ -482,6 +482,41 @@ static void test_WinHttpSendRequest (void)
     ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
 }
 
+static void test_connect_error(void)
+{
+    static const WCHAR content_type[] = L"Content-Type: application/x-www-form-urlencoded";
+    DWORD header_len, optional_len, total_len, err, t1, t2;
+    HINTERNET session, request, connection;
+    static char post_data[] = "mode=Test";
+    BOOL ret;
+
+    header_len = ~0u;
+    total_len = optional_len = sizeof(post_data);
+
+    session = WinHttpOpen(L"winetest", WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
+            WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
+    ok(!!session, "WinHttpOpen failed to open session.\n");
+
+    connection = WinHttpConnect (session, L"127.0.0.1", 12345, 0);
+    ok(!!connection, "WinHttpConnect failed to open a connection, error %lu.\n", GetLastError());
+
+    request = WinHttpOpenRequest(connection, L"POST", L"tests/post.php", NULL, WINHTTP_NO_REFERER,
+            WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
+    ok(!!request, "WinHttpOpenrequest failed to open a request, error: %lu\n", GetLastError());
+
+    t1 = GetTickCount();
+    ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, 0);
+    t2 = GetTickCount();
+    err = GetLastError();
+    ok(!ret, "WinHttpSendRequest() succeeded.\n");
+    ok(err == ERROR_WINHTTP_CANNOT_CONNECT, "Got unexpected err %lu.\n", err);
+    ok(t2 - t1 < 5000, "Unexpected connect failure delay %lums.\n", t2 - t1);
+
+    WinHttpCloseHandle(request);
+    WinHttpCloseHandle(connection);
+    WinHttpCloseHandle(session);
+}
+
 static void test_WinHttpTimeFromSystemTime(void)
 {
     BOOL ret;
@@ -5557,6 +5592,7 @@ START_TEST (winhttp)
 
     test_WinHttpOpenRequest();
     test_WinHttpSendRequest();
+    test_connect_error();
     test_WinHttpTimeFromSystemTime();
     test_WinHttpTimeToSystemTime();
     test_WinHttpAddHeaders();
-- 
2.35.1




More information about the wine-devel mailing list