Probably caused by some winehq.org HTTP server update, it now supports HTTP/2 and sends "Upgrade, Keep-Alive" connection strings (was "Keep-Alive" before).
-- v2: wininet: Parse multi-token Connection strings for Keep-Alive.
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/secur32/tests/schannel.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/dlls/secur32/tests/schannel.c b/dlls/secur32/tests/schannel.c index eecbc41415e..85f0f0a8560 100644 --- a/dlls/secur32/tests/schannel.c +++ b/dlls/secur32/tests/schannel.c @@ -1592,8 +1592,8 @@ static void test_application_protocol_negotiation(void) { ok(protocol.ProtoNegoStatus == SecApplicationProtocolNegotiationStatus_Success, "got %u\n", protocol.ProtoNegoStatus); ok(protocol.ProtoNegoExt == SecApplicationProtocolNegotiationExt_ALPN, "got %u\n", protocol.ProtoNegoExt); - ok(protocol.ProtocolIdSize == 8, "got %u\n", protocol.ProtocolIdSize); - ok(!memcmp(protocol.ProtocolId, "http/1.1", 8), "wrong protocol id\n"); + ok(protocol.ProtocolIdSize == 2, "got %u\n", protocol.ProtocolIdSize); + ok(!memcmp(protocol.ProtocolId, "h2", 2), "wrong protocol id\n"); }
DeleteSecurityContext(&context);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/urlmon/tests/protocol.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dlls/urlmon/tests/protocol.c b/dlls/urlmon/tests/protocol.c index 01e564b2cf7..2affa2ef12a 100644 --- a/dlls/urlmon/tests/protocol.c +++ b/dlls/urlmon/tests/protocol.c @@ -981,7 +981,7 @@ static void test_http_info(IInternetProtocol *protocol) if(tested_protocol != FTP_TEST) { ok(hres == S_OK, "QueryInfo failed: %08lx\n", hres);
- ok(!strcmp(buf, "Keep-Alive"), "buf = %s\n", buf); + ok(!strcmp(buf, "Keep-Alive") || !strcmp(buf, "Upgrade, Keep-Alive"), "buf = %s\n", buf); len = strlen(buf); ok(size == len, "size = %lu, expected %lu\n", size, len);
From: Rémi Bernon rbernon@codeweavers.com
--- dlls/wininet/http.c | 50 +++++++++++++++++++++++++++++---------------- 1 file changed, 32 insertions(+), 18 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 92417714fac..97b1e4e7d5f 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -1915,29 +1915,44 @@ static void http_release_netconn(http_request_t *req, BOOL reuse) INTERNET_STATUS_CONNECTION_CLOSED, 0, 0); }
+static BOOL has_token(const WCHAR *str, const WCHAR *token) +{ + const WCHAR *next; + + for (; *str; str = next + wcsspn(next, L" ,")) + { + next = str + wcscspn(str, L" ,"); + if (next - str != 10) continue; + if (wcsnicmp(str, token, 10)) continue; + return TRUE; + } + + return FALSE; +} + +static BOOL has_keep_alive(const WCHAR *version, const WCHAR *connection) +{ + return !wcsicmp(version, L"HTTP/1.1") ? !has_token(connection, L"Close") + : has_token(connection, L"Keep-Alive"); +} + static BOOL HTTP_KeepAlive(http_request_t *request) { WCHAR szVersion[10]; WCHAR szConnectionResponse[20]; DWORD dwBufferSize = sizeof(szVersion); - BOOL keepalive = FALSE;
/* as per RFC 2068, S8.1.2.1, if the client is HTTP/1.1 then assume that * the connection is keep-alive by default */ - if (HTTP_HttpQueryInfoW(request, HTTP_QUERY_VERSION, szVersion, &dwBufferSize, NULL) == ERROR_SUCCESS - && !wcsicmp(szVersion, L"HTTP/1.1")) - { - keepalive = TRUE; - } + if (HTTP_HttpQueryInfoW(request, HTTP_QUERY_VERSION, szVersion, &dwBufferSize, NULL) != ERROR_SUCCESS) + *szVersion = 0;
dwBufferSize = sizeof(szConnectionResponse); - if (HTTP_HttpQueryInfoW(request, HTTP_QUERY_PROXY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) == ERROR_SUCCESS - || HTTP_HttpQueryInfoW(request, HTTP_QUERY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) == ERROR_SUCCESS) - { - keepalive = !wcsicmp(szConnectionResponse, L"Keep-Alive"); - } + if (HTTP_HttpQueryInfoW(request, HTTP_QUERY_PROXY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) != ERROR_SUCCESS && + HTTP_HttpQueryInfoW(request, HTTP_QUERY_CONNECTION, szConnectionResponse, &dwBufferSize, NULL) != ERROR_SUCCESS) + *szConnectionResponse = 0;
- return keepalive; + return has_keep_alive(szVersion, szConnectionResponse); }
static void HTTPREQ_CloseConnection(object_header_t *hdr) @@ -4857,16 +4872,15 @@ static void HTTP_ProcessLastModified(http_request_t *request)
static void http_process_keep_alive(http_request_t *req) { + const WCHAR *connection = L""; int index;
EnterCriticalSection( &req->headers_section );
- if ((index = HTTP_GetCustomHeaderIndex(req, L"Connection", 0, FALSE)) != -1) - req->netconn->keep_alive = !wcsicmp(req->custHeaders[index].lpszValue, L"Keep-Alive"); - else if ((index = HTTP_GetCustomHeaderIndex(req, L"Proxy-Connection", 0, FALSE)) != -1) - req->netconn->keep_alive = !wcsicmp(req->custHeaders[index].lpszValue, L"Keep-Alive"); - else - req->netconn->keep_alive = !wcsicmp(req->version, L"HTTP/1.1"); + if ((index = HTTP_GetCustomHeaderIndex(req, L"Connection", 0, FALSE)) != -1 || + (index = HTTP_GetCustomHeaderIndex(req, L"Proxy-Connection", 0, FALSE)) != -1) + connection = req->custHeaders[index].lpszValue; + req->netconn->keep_alive = has_keep_alive(req->version, connection);
LeaveCriticalSection( &req->headers_section ); }
On Fri Nov 22 13:13:05 2024 +0000, Rémi Bernon wrote:
changed this line in [version 2 of the diff](/wine/wine/-/merge_requests/6882/diffs?diff_id=144827&start_sha=c29ccc391ba37b7f1b4b11646cc82d601749fdd6#5257c8cfe2c57bd3f642ff218718644d33ec40ef_1952_1951)
Updated to handle "Close" token. Adding more tests would take some time and probably some server-side changes, and I'm only trying to get rid of the annoying MR test failures.
On Fri Nov 22 13:15:06 2024 +0000, Rémi Bernon wrote:
Updated to handle "Close" token. Adding more tests would take some time and probably some server-side changes, and I'm only trying to get rid of the annoying MR test failures.
Hum, wininet failures are back, probably means it's not working as intended.