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

wininet: Add support for setting and retrieving the send/receive timeouts.

parent 848cd8a2
...@@ -2182,26 +2182,19 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer, ...@@ -2182,26 +2182,19 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer,
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
case INTERNET_OPTION_CONNECT_TIMEOUT: case INTERNET_OPTION_CONNECT_TIMEOUT:
if (size != sizeof(DWORD)) if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
return ERROR_INVALID_PARAMETER;
req->connect_timeout = *(DWORD *)buffer; req->connect_timeout = *(DWORD *)buffer;
return ERROR_SUCCESS; return ERROR_SUCCESS;
case INTERNET_OPTION_SEND_TIMEOUT: case INTERNET_OPTION_SEND_TIMEOUT:
case INTERNET_OPTION_RECEIVE_TIMEOUT: if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
TRACE("INTERNET_OPTION_SEND/RECEIVE_TIMEOUT\n"); req->send_timeout = *(DWORD *)buffer;
return ERROR_SUCCESS;
if (size != sizeof(DWORD))
return ERROR_INVALID_PARAMETER;
if(!req->netconn) {
FIXME("unsupported without active connection\n");
return ERROR_SUCCESS;
}
return NETCON_set_timeout(req->netconn, option == INTERNET_OPTION_SEND_TIMEOUT, case INTERNET_OPTION_RECEIVE_TIMEOUT:
*(DWORD*)buffer); if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
req->receive_timeout = *(DWORD *)buffer;
return ERROR_SUCCESS;
case INTERNET_OPTION_USERNAME: case INTERNET_OPTION_USERNAME:
heap_free(req->session->userName); heap_free(req->session->userName);
...@@ -3063,6 +3056,8 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session, ...@@ -3063,6 +3056,8 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl; request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl;
request->data_stream = &request->netconn_stream.data_stream; request->data_stream = &request->netconn_stream.data_stream;
request->connect_timeout = session->connect_timeout; request->connect_timeout = session->connect_timeout;
request->send_timeout = session->send_timeout;
request->receive_timeout = session->receive_timeout;
InitializeCriticalSection( &request->read_section ); InitializeCriticalSection( &request->read_section );
request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section"); request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section");
...@@ -3970,6 +3965,7 @@ static DWORD HTTP_SecureProxyConnect(http_request_t *request) ...@@ -3970,6 +3965,7 @@ static DWORD HTTP_SecureProxyConnect(http_request_t *request)
TRACE("full request -> %s\n", debugstr_an( ascii_req, len ) ); TRACE("full request -> %s\n", debugstr_an( ascii_req, len ) );
NETCON_set_timeout( request->netconn, TRUE, request->send_timeout );
res = NETCON_send( request->netconn, ascii_req, len, 0, &cnt ); res = NETCON_send( request->netconn, ascii_req, len, 0, &cnt );
heap_free( ascii_req ); heap_free( ascii_req );
if (res != ERROR_SUCCESS) if (res != ERROR_SUCCESS)
...@@ -4798,6 +4794,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders, ...@@ -4798,6 +4794,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext, INTERNET_SendCallback(&request->hdr, request->hdr.dwContext,
INTERNET_STATUS_SENDING_REQUEST, NULL, 0); INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
NETCON_set_timeout( request->netconn, TRUE, request->send_timeout );
res = NETCON_send(request->netconn, ascii_req, len, 0, &cnt); res = NETCON_send(request->netconn, ascii_req, len, 0, &cnt);
heap_free( ascii_req ); heap_free( ascii_req );
if(res != ERROR_SUCCESS) { if(res != ERROR_SUCCESS) {
...@@ -5473,6 +5470,26 @@ static DWORD HTTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *b ...@@ -5473,6 +5470,26 @@ static DWORD HTTPSESSION_QueryOption(object_header_t *hdr, DWORD option, void *b
*size = sizeof(DWORD); *size = sizeof(DWORD);
*(DWORD *)buffer = ses->connect_timeout; *(DWORD *)buffer = ses->connect_timeout;
return ERROR_SUCCESS; return ERROR_SUCCESS;
case INTERNET_OPTION_SEND_TIMEOUT:
TRACE("INTERNET_OPTION_SEND_TIMEOUT\n");
if (*size < sizeof(DWORD))
return ERROR_INSUFFICIENT_BUFFER;
*size = sizeof(DWORD);
*(DWORD *)buffer = ses->send_timeout;
return ERROR_SUCCESS;
case INTERNET_OPTION_RECEIVE_TIMEOUT:
TRACE("INTERNET_OPTION_RECEIVE_TIMEOUT\n");
if (*size < sizeof(DWORD))
return ERROR_INSUFFICIENT_BUFFER;
*size = sizeof(DWORD);
*(DWORD *)buffer = ses->receive_timeout;
return ERROR_SUCCESS;
} }
return INET_QueryOption(hdr, option, buffer, size, unicode); return INET_QueryOption(hdr, option, buffer, size, unicode);
...@@ -5497,9 +5514,22 @@ static DWORD HTTPSESSION_SetOption(object_header_t *hdr, DWORD option, void *buf ...@@ -5497,9 +5514,22 @@ static DWORD HTTPSESSION_SetOption(object_header_t *hdr, DWORD option, void *buf
} }
case INTERNET_OPTION_CONNECT_TIMEOUT: case INTERNET_OPTION_CONNECT_TIMEOUT:
{ {
if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
ses->connect_timeout = *(DWORD *)buffer; ses->connect_timeout = *(DWORD *)buffer;
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
case INTERNET_OPTION_SEND_TIMEOUT:
{
if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
ses->send_timeout = *(DWORD *)buffer;
return ERROR_SUCCESS;
}
case INTERNET_OPTION_RECEIVE_TIMEOUT:
{
if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
ses->receive_timeout = *(DWORD *)buffer;
return ERROR_SUCCESS;
}
default: break; default: break;
} }
...@@ -5573,6 +5603,8 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName, ...@@ -5573,6 +5603,8 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
session->serverPort = serverPort; session->serverPort = serverPort;
session->hostPort = serverPort; session->hostPort = serverPort;
session->connect_timeout = INFINITE; session->connect_timeout = INFINITE;
session->send_timeout = INFINITE;
session->receive_timeout = INFINITE;
/* Don't send a handle created callback if this handle was created with InternetOpenUrl */ /* Don't send a handle created callback if this handle was created with InternetOpenUrl */
if (!(session->hdr.dwInternalFlags & INET_OPENURL)) if (!(session->hdr.dwInternalFlags & INET_OPENURL))
...@@ -5645,6 +5677,7 @@ static INT HTTP_GetResponseHeaders(http_request_t *request, BOOL clear) ...@@ -5645,6 +5677,7 @@ static INT HTTP_GetResponseHeaders(http_request_t *request, BOOL clear)
if(!request->netconn) if(!request->netconn)
goto lend; goto lend;
NETCON_set_timeout( request->netconn, FALSE, request->receive_timeout );
do { do {
static const WCHAR szHundred[] = {'1','0','0',0}; static const WCHAR szHundred[] = {'1','0','0',0};
/* /*
......
...@@ -266,6 +266,8 @@ typedef struct ...@@ -266,6 +266,8 @@ typedef struct
INTERNET_PORT hostPort; /* the final destination port of the request */ INTERNET_PORT hostPort; /* the final destination port of the request */
INTERNET_PORT serverPort; /* the port of the server we directly connect to */ INTERNET_PORT serverPort; /* the port of the server we directly connect to */
DWORD connect_timeout; DWORD connect_timeout;
DWORD send_timeout;
DWORD receive_timeout;
} http_session_t; } http_session_t;
#define HDR_ISREQUEST 0x0001 #define HDR_ISREQUEST 0x0001
...@@ -307,6 +309,8 @@ typedef struct ...@@ -307,6 +309,8 @@ typedef struct
netconn_t *netconn; netconn_t *netconn;
DWORD security_flags; DWORD security_flags;
DWORD connect_timeout; DWORD connect_timeout;
DWORD send_timeout;
DWORD receive_timeout;
LPWSTR version; LPWSTR version;
LPWSTR statusText; LPWSTR statusText;
DWORD bytesToWrite; DWORD bytesToWrite;
...@@ -529,7 +533,7 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) DECLSP ...@@ -529,7 +533,7 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available) DECLSP
BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN; BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN;
LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN; LPCVOID NETCON_GetCert(netconn_t *connection) DECLSPEC_HIDDEN;
int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN; int NETCON_GetCipherStrength(netconn_t*) DECLSPEC_HIDDEN;
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, int value) DECLSPEC_HIDDEN; DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value) DECLSPEC_HIDDEN;
int sock_get_error(int) DECLSPEC_HIDDEN; int sock_get_error(int) DECLSPEC_HIDDEN;
extern void URLCacheContainers_CreateDefaults(void) DECLSPEC_HIDDEN; extern void URLCacheContainers_CreateDefaults(void) DECLSPEC_HIDDEN;
......
...@@ -927,24 +927,29 @@ int NETCON_GetCipherStrength(netconn_t *connection) ...@@ -927,24 +927,29 @@ int NETCON_GetCipherStrength(netconn_t *connection)
#endif #endif
} }
DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, int value) DWORD NETCON_set_timeout(netconn_t *connection, BOOL send, DWORD value)
{ {
int result; int result;
struct timeval tv; struct timeval tv;
/* value is in milliseconds, convert to struct timeval */ /* value is in milliseconds, convert to struct timeval */
tv.tv_sec = value / 1000; if (value == INFINITE)
tv.tv_usec = (value % 1000) * 1000; {
tv.tv_sec = 0;
tv.tv_usec = 0;
}
else
{
tv.tv_sec = value / 1000;
tv.tv_usec = (value % 1000) * 1000;
}
result = setsockopt(connection->socketFD, SOL_SOCKET, result = setsockopt(connection->socketFD, SOL_SOCKET,
send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv, send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv,
sizeof(tv)); sizeof(tv));
if (result == -1) if (result == -1)
{ {
WARN("setsockopt failed (%s)\n", strerror(errno)); WARN("setsockopt failed (%s)\n", strerror(errno));
return sock_get_error(errno); return sock_get_error(errno);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }
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