wininet: Add support for setting and retrieving the send/receive timeouts.
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index ca8cc60..3439924 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -2182,26 +2182,19 @@
return ERROR_SUCCESS;
}
case INTERNET_OPTION_CONNECT_TIMEOUT:
- if (size != sizeof(DWORD))
- return ERROR_INVALID_PARAMETER;
-
+ if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
req->connect_timeout = *(DWORD *)buffer;
return ERROR_SUCCESS;
case INTERNET_OPTION_SEND_TIMEOUT:
+ if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
+ req->send_timeout = *(DWORD *)buffer;
+ return ERROR_SUCCESS;
+
case INTERNET_OPTION_RECEIVE_TIMEOUT:
- TRACE("INTERNET_OPTION_SEND/RECEIVE_TIMEOUT\n");
-
- 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,
- *(DWORD*)buffer);
+ if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
+ req->receive_timeout = *(DWORD *)buffer;
+ return ERROR_SUCCESS;
case INTERNET_OPTION_USERNAME:
heap_free(req->session->userName);
@@ -3063,6 +3056,8 @@
request->netconn_stream.data_stream.vtbl = &netconn_stream_vtbl;
request->data_stream = &request->netconn_stream.data_stream;
request->connect_timeout = session->connect_timeout;
+ request->send_timeout = session->send_timeout;
+ request->receive_timeout = session->receive_timeout;
InitializeCriticalSection( &request->read_section );
request->read_section.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": http_request_t.read_section");
@@ -3970,6 +3965,7 @@
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 );
heap_free( ascii_req );
if (res != ERROR_SUCCESS)
@@ -4798,6 +4794,7 @@
INTERNET_SendCallback(&request->hdr, request->hdr.dwContext,
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);
heap_free( ascii_req );
if(res != ERROR_SUCCESS) {
@@ -5473,6 +5470,26 @@
*size = sizeof(DWORD);
*(DWORD *)buffer = ses->connect_timeout;
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);
@@ -5497,9 +5514,22 @@
}
case INTERNET_OPTION_CONNECT_TIMEOUT:
{
+ if (!buffer || size != sizeof(DWORD)) return ERROR_INVALID_PARAMETER;
ses->connect_timeout = *(DWORD *)buffer;
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;
}
@@ -5573,6 +5603,8 @@
session->serverPort = serverPort;
session->hostPort = serverPort;
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 */
if (!(session->hdr.dwInternalFlags & INET_OPENURL))
@@ -5645,6 +5677,7 @@
if(!request->netconn)
goto lend;
+ NETCON_set_timeout( request->netconn, FALSE, request->receive_timeout );
do {
static const WCHAR szHundred[] = {'1','0','0',0};
/*
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 41af08c..3af93db 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -266,6 +266,8 @@
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;
+ DWORD send_timeout;
+ DWORD receive_timeout;
} http_session_t;
#define HDR_ISREQUEST 0x0001
@@ -307,6 +309,8 @@
netconn_t *netconn;
DWORD security_flags;
DWORD connect_timeout;
+ DWORD send_timeout;
+ DWORD receive_timeout;
LPWSTR version;
LPWSTR statusText;
DWORD bytesToWrite;
@@ -529,7 +533,7 @@
BOOL NETCON_is_alive(netconn_t*) DECLSPEC_HIDDEN;
LPCVOID NETCON_GetCert(netconn_t *connection) 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;
extern void URLCacheContainers_CreateDefaults(void) DECLSPEC_HIDDEN;
diff --git a/dlls/wininet/netconnection.c b/dlls/wininet/netconnection.c
index 8273c73..870b317 100644
--- a/dlls/wininet/netconnection.c
+++ b/dlls/wininet/netconnection.c
@@ -927,24 +927,29 @@
#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;
struct timeval tv;
/* value is in milliseconds, convert to struct timeval */
- tv.tv_sec = value / 1000;
- tv.tv_usec = (value % 1000) * 1000;
-
+ if (value == INFINITE)
+ {
+ 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,
send ? SO_SNDTIMEO : SO_RCVTIMEO, (void*)&tv,
sizeof(tv));
-
if (result == -1)
{
WARN("setsockopt failed (%s)\n", strerror(errno));
return sock_get_error(errno);
}
-
return ERROR_SUCCESS;
}