Commit b467efb5 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

winhttp: Add support for resolve timeouts.

parent b7696db1
......@@ -867,7 +867,7 @@ DWORD netconn_set_timeout( netconn_t *netconn, BOOL send, int value )
return ERROR_SUCCESS;
}
BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len )
static DWORD resolve_hostname( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len )
{
char *hostname;
#ifdef HAVE_GETADDRINFO
......@@ -878,7 +878,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
struct sockaddr_in *sin = (struct sockaddr_in *)sa;
#endif
if (!(hostname = strdupWA( hostnameW ))) return FALSE;
if (!(hostname = strdupWA( hostnameW ))) return ERROR_OUTOFMEMORY;
#ifdef HAVE_GETADDRINFO
memset( &hints, 0, sizeof(struct addrinfo) );
......@@ -897,7 +897,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
{
TRACE("failed to get address of %s (%s)\n", debugstr_w(hostnameW), gai_strerror(ret));
heap_free( hostname );
return FALSE;
return ERROR_WINHTTP_NAME_NOT_RESOLVED;
}
}
heap_free( hostname );
......@@ -905,7 +905,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
{
WARN("address too small\n");
freeaddrinfo( res );
return FALSE;
return ERROR_WINHTTP_NAME_NOT_RESOLVED;
}
*sa_len = res->ai_addrlen;
memcpy( sa, res->ai_addr, res->ai_addrlen );
......@@ -921,7 +921,7 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
}
freeaddrinfo( res );
return TRUE;
return ERROR_SUCCESS;
#else
EnterCriticalSection( &cs_gethostbyname );
......@@ -931,13 +931,13 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
{
TRACE("failed to get address of %s (%d)\n", debugstr_w(hostnameW), h_errno);
LeaveCriticalSection( &cs_gethostbyname );
return FALSE;
return ERROR_WINHTTP_NAME_NOT_RESOLVED;
}
if (*sa_len < sizeof(struct sockaddr_in))
{
WARN("address too small\n");
LeaveCriticalSection( &cs_gethostbyname );
return FALSE;
return ERROR_WINHTTP_NAME_NOT_RESOLVED;
}
*sa_len = sizeof(struct sockaddr_in);
memset( sa, 0, sizeof(struct sockaddr_in) );
......@@ -946,10 +946,57 @@ BOOL netconn_resolve( WCHAR *hostnameW, INTERNET_PORT port, struct sockaddr *sa,
sin->sin_port = htons( port );
LeaveCriticalSection( &cs_gethostbyname );
return TRUE;
return ERROR_SUCCESS;
#endif
}
struct resolve_args
{
WCHAR *hostname;
INTERNET_PORT port;
struct sockaddr *sa;
socklen_t *sa_len;
};
static DWORD CALLBACK resolve_proc( LPVOID arg )
{
struct resolve_args *ra = arg;
return resolve_hostname( ra->hostname, ra->port, ra->sa, ra->sa_len );
}
BOOL netconn_resolve( WCHAR *hostname, INTERNET_PORT port, struct sockaddr *sa, socklen_t *sa_len, int timeout )
{
DWORD ret;
if (timeout)
{
DWORD status;
HANDLE thread;
struct resolve_args ra;
ra.hostname = hostname;
ra.port = port;
ra.sa = sa;
ra.sa_len = sa_len;
thread = CreateThread( NULL, 0, resolve_proc, &ra, 0, NULL );
if (!thread) return FALSE;
status = WaitForSingleObject( thread, timeout );
if (status == WAIT_OBJECT_0) GetExitCodeThread( thread, &ret );
else ret = ERROR_WINHTTP_TIMEOUT;
CloseHandle( thread );
}
else ret = resolve_hostname( hostname, port, sa, sa_len );
if (ret)
{
set_last_error( ret );
return FALSE;
}
return TRUE;
}
const void *netconn_get_certificate( netconn_t *conn )
{
#ifdef SONAME_LIBSSL
......
......@@ -911,7 +911,7 @@ static BOOL open_connection( request_t *request )
send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_RESOLVING_NAME, connect->servername, strlenW(connect->servername) + 1 );
slen = sizeof(connect->sockaddr);
if (!netconn_resolve( connect->servername, port, (struct sockaddr *)&connect->sockaddr, &slen )) return FALSE;
if (!netconn_resolve( connect->servername, port, (struct sockaddr *)&connect->sockaddr, &slen, request->resolve_timeout )) return FALSE;
switch (connect->sockaddr.ss_family)
{
case AF_INET:
......
......@@ -33,6 +33,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
#define DEFAULT_RESOLVE_TIMEOUT 0
#define DEFAULT_CONNECT_TIMEOUT 20000
#define DEFAULT_SEND_TIMEOUT 30000
#define DEFAULT_RECEIVE_TIMEOUT 30000
......@@ -108,6 +109,10 @@ static BOOL session_query_option( object_header_t *hdr, DWORD option, LPVOID buf
*buflen = sizeof(DWORD);
return TRUE;
}
case WINHTTP_OPTION_RESOLVE_TIMEOUT:
*(DWORD *)buffer = session->resolve_timeout;
*buflen = sizeof(DWORD);
return TRUE;
case WINHTTP_OPTION_CONNECT_TIMEOUT:
*(DWORD *)buffer = session->connect_timeout;
*buflen = sizeof(DWORD);
......@@ -158,6 +163,9 @@ static BOOL session_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
case WINHTTP_OPTION_DISABLE_FEATURE:
set_last_error( ERROR_WINHTTP_INCORRECT_HANDLE_TYPE );
return FALSE;
case WINHTTP_OPTION_RESOLVE_TIMEOUT:
session->resolve_timeout = *(DWORD *)buffer;
return TRUE;
case WINHTTP_OPTION_CONNECT_TIMEOUT:
session->connect_timeout = *(DWORD *)buffer;
return TRUE;
......@@ -198,6 +206,7 @@ HINTERNET WINAPI WinHttpOpen( LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWST
session->hdr.flags = flags;
session->hdr.refs = 1;
session->hdr.redirect_policy = WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP;
session->resolve_timeout = DEFAULT_RESOLVE_TIMEOUT;
session->connect_timeout = DEFAULT_CONNECT_TIMEOUT;
session->send_timeout = DEFAULT_SEND_TIMEOUT;
session->recv_timeout = DEFAULT_RECEIVE_TIMEOUT;
......@@ -276,6 +285,10 @@ static BOOL connect_query_option( object_header_t *hdr, DWORD option, LPVOID buf
*buflen = sizeof(HINTERNET);
return TRUE;
}
case WINHTTP_OPTION_RESOLVE_TIMEOUT:
*(DWORD *)buffer = connect->session->resolve_timeout;
*buflen = sizeof(DWORD);
return TRUE;
case WINHTTP_OPTION_CONNECT_TIMEOUT:
*(DWORD *)buffer = connect->session->connect_timeout;
*buflen = sizeof(DWORD);
......@@ -586,6 +599,10 @@ static BOOL request_query_option( object_header_t *hdr, DWORD option, LPVOID buf
*buflen = sizeof(DWORD);
return TRUE;
}
case WINHTTP_OPTION_RESOLVE_TIMEOUT:
*(DWORD *)buffer = request->resolve_timeout;
*buflen = sizeof(DWORD);
return TRUE;
case WINHTTP_OPTION_CONNECT_TIMEOUT:
*(DWORD *)buffer = request->connect_timeout;
*buflen = sizeof(DWORD);
......@@ -667,6 +684,9 @@ static BOOL request_set_option( object_header_t *hdr, DWORD option, LPVOID buffe
FIXME("WINHTTP_OPTION_SECURITY_FLAGS unimplemented (%08x)\n",
*(DWORD *)buffer);
return TRUE;
case WINHTTP_OPTION_RESOLVE_TIMEOUT:
request->resolve_timeout = *(DWORD *)buffer;
return TRUE;
case WINHTTP_OPTION_CONNECT_TIMEOUT:
request->connect_timeout = *(DWORD *)buffer;
return TRUE;
......@@ -732,6 +752,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->resolve_timeout = connect->session->resolve_timeout;
request->connect_timeout = connect->session->connect_timeout;
request->send_timeout = connect->session->send_timeout;
request->recv_timeout = connect->session->recv_timeout;
......@@ -1266,9 +1287,6 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
return FALSE;
}
if (resolve > 0)
FIXME("resolve timeout (%d) not supported\n", resolve);
if (!(hdr = grab_object( handle )))
{
set_last_error( ERROR_INVALID_HANDLE );
......@@ -1281,6 +1299,9 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
request = (request_t *)hdr;
request->connect_timeout = connect;
if (resolve < 0) resolve = 0;
request->resolve_timeout = resolve;
if (send < 0) send = 0;
request->send_timeout = send;
......@@ -1300,6 +1321,9 @@ BOOL WINAPI WinHttpSetTimeouts( HINTERNET handle, int resolve, int connect, int
session = (session_t *)hdr;
session->connect_timeout = connect;
if (resolve < 0) resolve = 0;
session->resolve_timeout = resolve;
if (send < 0) send = 0;
session->send_timeout = send;
......
......@@ -96,6 +96,7 @@ typedef struct
object_header_t hdr;
LPWSTR agent;
DWORD access;
int resolve_timeout;
int connect_timeout;
int send_timeout;
int recv_timeout;
......@@ -145,6 +146,7 @@ typedef struct
LPWSTR version;
LPWSTR raw_headers;
netconn_t netconn;
int resolve_timeout;
int connect_timeout;
int send_timeout;
int recv_timeout;
......@@ -221,7 +223,7 @@ BOOL netconn_init( netconn_t *, BOOL );
void netconn_unload( void );
BOOL netconn_query_data_available( netconn_t *, DWORD * );
BOOL netconn_recv( netconn_t *, void *, size_t, int, int * );
BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr *, socklen_t * );
BOOL netconn_resolve( WCHAR *, INTERNET_PORT, struct sockaddr *, socklen_t *, int );
BOOL netconn_secure_connect( netconn_t *, WCHAR * );
BOOL netconn_send( netconn_t *, const void *, size_t, int, int * );
DWORD netconn_set_timeout( netconn_t *, BOOL, int );
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment