Module: wine Branch: master Commit: 72273a07863ab330cf9aa628928e46fdb800cd5e URL: http://source.winehq.org/git/wine.git/?a=commit;h=72273a07863ab330cf9aa62892...
Author: Hans Leidekker hans@codeweavers.com Date: Fri Jan 13 15:15:04 2012 +0100
wininet: Implement the connect timeout.
---
dlls/wininet/http.c | 4 +++- dlls/wininet/internet.h | 4 +++- dlls/wininet/netconnection.c | 32 +++++++++++++++++++++++++++++++- 3 files changed, 37 insertions(+), 3 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c index 8fc01fe..e645d86 100644 --- a/dlls/wininet/http.c +++ b/dlls/wininet/http.c @@ -3048,6 +3048,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl; request->data_stream = &request->netconn_stream.data_stream; + request->connect_timeout = session->connect_timeout;
InitializeCriticalSection( &request->read_section ); request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section"); @@ -4597,7 +4598,7 @@ static DWORD open_http_connection(http_request_t *request, BOOL *reusing) server->addr_str, strlen(server->addr_str)+1);
- res = create_netconn(is_https, server, request->security_flags, &netconn); + res = create_netconn(is_https, server, request->security_flags, request->connect_timeout, &netconn); server_release(server); if(res != ERROR_SUCCESS) { ERR("create_netconn failed: %u\n", res); @@ -5541,6 +5542,7 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, session->password = heap_strdupW(lpszPassword); session->serverPort = serverPort; session->hostPort = serverPort; + session->connect_timeout = INFINITE;
/* Don't send a handle created callback if this handle was created with InternetOpenUrl */ if (!(session->hdr.dwInternalFlags & INET_OPENURL)) diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h index a7af629..41af08c 100644 --- a/dlls/wininet/internet.h +++ b/dlls/wininet/internet.h @@ -265,6 +265,7 @@ typedef struct LPWSTR password; INTERNET_PORT hostPort; /* the final destination port of the request */ INTERNET_PORT serverPort; /* the port of the server we directly connect to */ + DWORD connect_timeout; } http_session_t;
#define HDR_ISREQUEST 0x0001 @@ -305,6 +306,7 @@ typedef struct LPWSTR rawHeaders; netconn_t *netconn; DWORD security_flags; + DWORD connect_timeout; LPWSTR version; LPWSTR statusText; DWORD bytesToWrite; @@ -515,7 +517,7 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext, DWORD dwStatusInfoLength) DECLSPEC_HIDDEN; BOOL INTERNET_FindProxyForProtocol(LPCWSTR szProxy, LPCWSTR proto, WCHAR *foundProxy, DWORD *foundProxyLen) DECLSPEC_HIDDEN;
-DWORD create_netconn(BOOL,server_t*,DWORD,netconn_t**) DECLSPEC_HIDDEN; +DWORD create_netconn(BOOL, server_t *, DWORD, DWORD, netconn_t **) DECLSPEC_HIDDEN; void free_netconn(netconn_t*) DECLSPEC_HIDDEN; void NETCON_unload(void) DECLSPEC_HIDDEN; DWORD NETCON_secure_connect(netconn_t *connection, LPWSTR hostname) DECLSPEC_HIDDEN; diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c index bf93301..8273c73 100644 --- a/dlls/wininet/netconnection.c +++ b/dlls/wininet/netconnection.c @@ -497,7 +497,7 @@ static DWORD init_openssl(void) #endif }
-DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, netconn_t **ret) +DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, DWORD timeout, netconn_t **ret) { netconn_t *netconn; int result, flag; @@ -526,9 +526,39 @@ DWORD create_netconn(BOOL useSSL, server_t *server, DWORD security_flags, netcon assert(server->addr_len); result = netconn->socketFD = socket(server->addr.ss_family, SOCK_STREAM, 0); if(result != -1) { + flag = 1; + ioctlsocket(netconn->socketFD, FIONBIO, &flag); result = connect(netconn->socketFD, (struct sockaddr*)&server->addr, server->addr_len); if(result == -1) + { + if (sock_get_error(errno) == WSAEINPROGRESS) { + struct pollfd pfd; + int res; + + pfd.fd = netconn->socketFD; + pfd.events = POLLOUT; + res = poll(&pfd, 1, timeout); + if (!res) + { + closesocket(netconn->socketFD); + heap_free(netconn); + return ERROR_INTERNET_CANNOT_CONNECT; + } + else if (res > 0) + { + int err; + socklen_t len = sizeof(err); + if (!getsockopt(netconn->socketFD, SOL_SOCKET, SO_ERROR, &err, &len) && !err) + result = 0; + } + } + } + if(result == -1) closesocket(netconn->socketFD); + else { + flag = 0; + ioctlsocket(netconn->socketFD, FIONBIO, &flag); + } } if(result == -1) { heap_free(netconn);