Module: wine Branch: master Commit: 68039dcaff74876ea2eb9193b8b059c6b437d75f URL: http://source.winehq.org/git/wine.git/?a=commit;h=68039dcaff74876ea2eb9193b8...
Author: Juan Lang juan.lang@gmail.com Date: Thu Jul 23 09:11:32 2009 -0700
winhttp: Implement connect timeout.
---
dlls/winhttp/net.c | 41 ++++++++++++++++++++++++++++++++++----- dlls/winhttp/request.c | 2 +- dlls/winhttp/session.c | 6 ++++- dlls/winhttp/winhttp_private.h | 3 +- 4 files changed, 43 insertions(+), 9 deletions(-)
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c index 6f2d5f5..ed4d4b9 100644 --- a/dlls/winhttp/net.c +++ b/dlls/winhttp/net.c @@ -287,15 +287,44 @@ BOOL netconn_close( netconn_t *conn ) return TRUE; }
-BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned int addr_len ) +BOOL netconn_connect( netconn_t *conn, const struct sockaddr *sockaddr, unsigned int addr_len, int timeout ) { - if (connect( conn->socket, sockaddr, addr_len ) == -1) + BOOL ret = FALSE; + int res = 0, state; + + if (timeout > 0) { - WARN("unable to connect to host (%s)\n", strerror(errno)); - set_last_error( sock_get_error( errno ) ); - return FALSE; + state = 1; + ioctlsocket( conn->socket, FIONBIO, &state ); } - return TRUE; + if (connect( conn->socket, sockaddr, addr_len ) < 0) + { + res = sock_get_error( errno ); + if (res == WSAEWOULDBLOCK || res == WSAEINPROGRESS) + { + struct pollfd pfd; + + pfd.fd = conn->socket; + pfd.events = POLLOUT; + if (poll( &pfd, 1, timeout ) > 0) + ret = TRUE; + else + res = sock_get_error( errno ); + } + } + else + ret = TRUE; + if (timeout > 0) + { + state = 0; + ioctlsocket( conn->socket, FIONBIO, &state ); + } + if (!ret) + { + WARN("unable to connect to host (%d)\n", res); + set_last_error( res ); + } + return ret; }
BOOL netconn_secure_connect( netconn_t *conn ) diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c index 83d6117..0efada4 100644 --- a/dlls/winhttp/request.c +++ b/dlls/winhttp/request.c @@ -925,7 +925,7 @@ static BOOL open_connection( request_t *request ) } netconn_set_timeout( &request->netconn, TRUE, request->send_timeout ); netconn_set_timeout( &request->netconn, FALSE, request->recv_timeout ); - if (!netconn_connect( &request->netconn, (struct sockaddr *)&connect->sockaddr, slen )) + if (!netconn_connect( &request->netconn, (struct sockaddr *)&connect->sockaddr, slen, request->connect_timeout )) { netconn_close( &request->netconn ); heap_free( addressW ); diff --git a/dlls/winhttp/session.c b/dlls/winhttp/session.c index 27509e1..4c93123 100644 --- a/dlls/winhttp/session.c +++ b/dlls/winhttp/session.c @@ -33,6 +33,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
+#define DEFAULT_CONNECT_TIMEOUT 60000 #define DEFAULT_SEND_TIMEOUT 30000 #define DEFAULT_RECEIVE_TIMEOUT 30000
@@ -636,6 +637,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->connect_timeout = DEFAULT_CONNECT_TIMEOUT; request->send_timeout = DEFAULT_SEND_TIMEOUT; request->recv_timeout = DEFAULT_RECEIVE_TIMEOUT;
@@ -1167,7 +1169,7 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int return FALSE; }
- FIXME("resolve and connect timeout not supported\n"); + FIXME("resolve timeout not supported\n");
if (!(request = (request_t *)grab_object( handle ))) { @@ -1182,6 +1184,8 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int return FALSE; }
+ request->connect_timeout = connect; + if (send < 0) send = 0; request->send_timeout = send;
diff --git a/dlls/winhttp/winhttp_private.h b/dlls/winhttp/winhttp_private.h index 97c8f90..83df0c0 100644 --- a/dlls/winhttp/winhttp_private.h +++ b/dlls/winhttp/winhttp_private.h @@ -139,6 +139,7 @@ typedef struct LPWSTR version; LPWSTR raw_headers; netconn_t netconn; + int connect_timeout; int send_timeout; int recv_timeout; LPWSTR status_text; @@ -206,7 +207,7 @@ void send_callback( object_header_t *, DWORD, LPVOID, DWORD ); void close_connection( request_t * );
BOOL netconn_close( netconn_t * ); -BOOL netconn_connect( netconn_t *, const struct sockaddr *, unsigned int ); +BOOL netconn_connect( netconn_t *, const struct sockaddr *, unsigned int, int ); BOOL netconn_connected( netconn_t * ); BOOL netconn_create( netconn_t *, int, int, int ); BOOL netconn_get_next_line( netconn_t *, char *, DWORD * );