winhttp(1/2): Implement connect timeout (try 2)
Juan Lang
juan.lang at gmail.com
Wed Jul 22 11:00:28 CDT 2009
Following Alexandre's suggestion, this uses ioctlsocket rather than
fcntl to set the socket to nonblocking mode.
--Juan
-------------- next part --------------
From 12462f797b0490ce9b6eb4ebb136af74e6c8e007 Mon Sep 17 00:00:00 2001
From: Juan Lang <juan.lang at gmail.com>
Date: Wed, 22 Jul 2009 08:59:01 -0700
Subject: [PATCH 1/2] Implement connect timeout
---
dlls/winhttp/net.c | 25 +++++++++++++++++++++++--
dlls/winhttp/request.c | 2 +-
dlls/winhttp/session.c | 6 +++++-
dlls/winhttp/winhttp_private.h | 3 ++-
4 files changed, 31 insertions(+), 5 deletions(-)
diff --git a/dlls/winhttp/net.c b/dlls/winhttp/net.c
index 6f2d5f5..38dd713 100644
--- a/dlls/winhttp/net.c
+++ b/dlls/winhttp/net.c
@@ -287,9 +287,30 @@ 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)
+ int res, state;
+
+ if (timeout > 0)
+ {
+ state = 1;
+ res = ioctlsocket( conn->socket, FIONBIO, &state );
+ }
+ res = connect( conn->socket, sockaddr, addr_len );
+ if (res == -1 && (errno == EINPROGRESS || errno == EAGAIN))
+ {
+ struct pollfd pfd;
+
+ pfd.fd = conn->socket;
+ pfd.events = POLLOUT;
+ res = poll( &pfd, 1, timeout );
+ }
+ if (timeout > 0)
+ {
+ state = 0;
+ res = ioctlsocket( conn->socket, FIONBIO, &state );
+ }
+ if (res == -1)
{
WARN("unable to connect to host (%s)\n", strerror(errno));
set_last_error( sock_get_error( errno ) );
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 * );
--
1.6.3.2
More information about the wine-patches
mailing list