From ee68473fe5c244cc3ad3ed6ad8751652b9962c65 Mon Sep 17 00:00:00 2001 From: Piotr Caban Date: Tue, 29 Jun 2010 12:20:51 +0200 Subject: [PATCH] wininet: Reconnect if persistent connection was closed by server. --- dlls/wininet/http.c | 23 ++++++++++++++++++++--- dlls/wininet/netconnection.c | 6 +++++- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 200d03f5cd3..4b4bc5bbfd5 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -3454,6 +3454,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, do { DWORD len; + BOOL reusing_connection; char *ascii_req; loop_next = FALSE; @@ -3504,6 +3505,11 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, TRACE("Request header -> %s\n", debugstr_w(requestString) ); /* Send the request and store the results */ + if(NETCON_connected(&lpwhr->netConnection)) + reusing_connection = TRUE; + else + reusing_connection = FALSE; + if ((res = HTTP_OpenConnection(lpwhr)) != ERROR_SUCCESS) goto lend; @@ -3545,6 +3551,13 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *lpwhr, LPCWSTR lpszHeaders, goto lend; responseLen = HTTP_GetResponseHeaders(lpwhr, TRUE); + /* FIXME: We should know that connection is closed before sending + * headers. Otherwise wrong callbacks are executed */ + if(!responseLen && reusing_connection) { + TRACE("Connection closed by server, reconnecting\n"); + loop_next = TRUE; + continue; + } INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, @@ -4457,9 +4470,6 @@ static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) TRACE("-->\n"); - /* clear old response headers (eg. from a redirect response) */ - if (clear) HTTP_clear_response_headers( lpwhr ); - if (!NETCON_connected(&lpwhr->netConnection)) goto lend; @@ -4471,6 +4481,13 @@ static INT HTTP_GetResponseHeaders(http_request_t *lpwhr, BOOL clear) buflen = MAX_REPLY_LEN; if (!read_line(lpwhr, bufferA, &buflen)) goto lend; + + /* clear old response headers (eg. from a redirect response) */ + if (clear) { + HTTP_clear_response_headers( lpwhr ); + clear = FALSE; + } + rc += buflen; MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); /* check is this a status code line? */ diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c index 5aa647a7a49..abd7415bb60 100644 --- a/dlls/wininet/netconnection.c +++ b/dlls/wininet/netconnection.c @@ -770,6 +770,8 @@ DWORD NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int if (!connection->useSSL) { *recvd = recv(connection->socketFD, buf, len, flags); + if(!*recvd) + NETCON_close(connection); return *recvd == -1 ? sock_get_error(errno) : ERROR_SUCCESS; } else @@ -779,8 +781,10 @@ DWORD NETCON_recv(WININET_NETCONNECTION *connection, void *buf, size_t len, int /* Check if EOF was received */ if(!*recvd && (pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_ZERO_RETURN - || pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_SYSCALL)) + || pSSL_get_error(connection->ssl_s, *recvd)==SSL_ERROR_SYSCALL)) { + NETCON_close(connection); return ERROR_SUCCESS; + } return *recvd > 0 ? ERROR_SUCCESS : ERROR_INTERNET_CONNECTION_ABORTED; #else -- 2.11.4.GIT