wininet: Change the HTTP code to not assume that the connection will be closed at the end of every request.
This commit is contained in:
parent
f0163ae7d6
commit
272954bd81
|
@ -6,6 +6,7 @@
|
||||||
* Copyright 2002 TransGaming Technologies Inc.
|
* Copyright 2002 TransGaming Technologies Inc.
|
||||||
* Copyright 2004 Mike McCormack for CodeWeavers
|
* Copyright 2004 Mike McCormack for CodeWeavers
|
||||||
* Copyright 2005 Aric Stewart for CodeWeavers
|
* Copyright 2005 Aric Stewart for CodeWeavers
|
||||||
|
* Copyright 2006 Robert Shearman for CodeWeavers
|
||||||
*
|
*
|
||||||
* Ulrich Czekalla
|
* Ulrich Czekalla
|
||||||
* David Hammerton
|
* David Hammerton
|
||||||
|
@ -69,6 +70,7 @@ static const WCHAR g_szUserAgent[] = {'U','s','e','r','-','A','g','e','n','t',0}
|
||||||
static const WCHAR szHost[] = { 'H','o','s','t',0 };
|
static const WCHAR szHost[] = { 'H','o','s','t',0 };
|
||||||
static const WCHAR szProxy_Authorization[] = { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 };
|
static const WCHAR szProxy_Authorization[] = { 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 };
|
||||||
static const WCHAR szStatus[] = { 'S','t','a','t','u','s',0 };
|
static const WCHAR szStatus[] = { 'S','t','a','t','u','s',0 };
|
||||||
|
static const WCHAR szKeepAlive[] = {'K','e','e','p','-','A','l','i','v','e',0};
|
||||||
|
|
||||||
#define MAXHOSTNAME 100
|
#define MAXHOSTNAME 100
|
||||||
#define MAX_FIELD_VALUE_LEN 256
|
#define MAX_FIELD_VALUE_LEN 256
|
||||||
|
@ -525,6 +527,20 @@ BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest,
|
||||||
return r;
|
return r;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* read any content returned by the server so that the connection can be
|
||||||
|
* resued */
|
||||||
|
static void HTTP_DrainContent(LPWININETHTTPREQW lpwhr)
|
||||||
|
{
|
||||||
|
DWORD bytes_read;
|
||||||
|
do
|
||||||
|
{
|
||||||
|
char buffer[2048];
|
||||||
|
if (!INTERNET_ReadFile(&lpwhr->hdr, buffer, sizeof(buffer), &bytes_read,
|
||||||
|
TRUE, FALSE))
|
||||||
|
return;
|
||||||
|
} while (bytes_read);
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* HttpEndRequestA (WININET.@)
|
* HttpEndRequestA (WININET.@)
|
||||||
*
|
*
|
||||||
|
@ -639,6 +655,9 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest,
|
||||||
&lpwhr->dwContentLength,&dwBufferSize,NULL))
|
&lpwhr->dwContentLength,&dwBufferSize,NULL))
|
||||||
lpwhr->dwContentLength = -1;
|
lpwhr->dwContentLength = -1;
|
||||||
|
|
||||||
|
if (lpwhr->dwContentLength == 0)
|
||||||
|
HTTP_FinishedReading(lpwhr);
|
||||||
|
|
||||||
if(!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT))
|
if(!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT))
|
||||||
{
|
{
|
||||||
DWORD dwCode,dwCodeLength=sizeof(DWORD);
|
DWORD dwCode,dwCodeLength=sizeof(DWORD);
|
||||||
|
@ -653,6 +672,7 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest,
|
||||||
/* redirects are always GETs */
|
/* redirects are always GETs */
|
||||||
HeapFree(GetProcessHeap(),0,lpwhr->lpszVerb);
|
HeapFree(GetProcessHeap(),0,lpwhr->lpszVerb);
|
||||||
lpwhr->lpszVerb = WININET_strdupW(szGET);
|
lpwhr->lpszVerb = WININET_strdupW(szGET);
|
||||||
|
HTTP_DrainContent(lpwhr);
|
||||||
rc = HTTP_HandleRedirect(lpwhr, szNewLocation);
|
rc = HTTP_HandleRedirect(lpwhr, szNewLocation);
|
||||||
if (rc)
|
if (rc)
|
||||||
rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE);
|
rc = HTTP_HttpSendRequestW(lpwhr, NULL, 0, NULL, 0, 0, TRUE);
|
||||||
|
@ -2260,6 +2280,10 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
|
||||||
char *ascii_req;
|
char *ascii_req;
|
||||||
|
|
||||||
loop_next = FALSE;
|
loop_next = FALSE;
|
||||||
|
|
||||||
|
/* like native, just in case the caller forgot to call InternetReadFile
|
||||||
|
* for all the data */
|
||||||
|
HTTP_DrainContent(lpwhr);
|
||||||
lpwhr->dwContentRead = 0;
|
lpwhr->dwContentRead = 0;
|
||||||
|
|
||||||
if (TRACE_ON(wininet))
|
if (TRACE_ON(wininet))
|
||||||
|
@ -2340,6 +2364,9 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
|
||||||
&lpwhr->dwContentLength,&dwBufferSize,NULL))
|
&lpwhr->dwContentLength,&dwBufferSize,NULL))
|
||||||
lpwhr->dwContentLength = -1;
|
lpwhr->dwContentLength = -1;
|
||||||
|
|
||||||
|
if (lpwhr->dwContentLength == 0)
|
||||||
|
HTTP_FinishedReading(lpwhr);
|
||||||
|
|
||||||
if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && bSuccess)
|
if (!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && bSuccess)
|
||||||
{
|
{
|
||||||
DWORD dwCode,dwCodeLength=sizeof(DWORD);
|
DWORD dwCode,dwCodeLength=sizeof(DWORD);
|
||||||
|
@ -2349,6 +2376,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
|
||||||
(dwCode==HTTP_STATUS_REDIRECT || dwCode==HTTP_STATUS_MOVED) &&
|
(dwCode==HTTP_STATUS_REDIRECT || dwCode==HTTP_STATUS_MOVED) &&
|
||||||
HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
|
HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
|
||||||
{
|
{
|
||||||
|
HTTP_DrainContent(lpwhr);
|
||||||
INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
|
INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
|
||||||
INTERNET_STATUS_REDIRECT, szNewLocation,
|
INTERNET_STATUS_REDIRECT, szNewLocation,
|
||||||
dwBufferSize);
|
dwBufferSize);
|
||||||
|
@ -2505,6 +2533,12 @@ static BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr)
|
||||||
goto lend;
|
goto lend;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (NETCON_connected(&lpwhr->netConnection))
|
||||||
|
{
|
||||||
|
bSuccess = TRUE;
|
||||||
|
goto lend;
|
||||||
|
}
|
||||||
|
|
||||||
lpwhs = lpwhr->lpHttpSession;
|
lpwhs = lpwhr->lpHttpSession;
|
||||||
|
|
||||||
hIC = lpwhs->lpAppInfo;
|
hIC = lpwhs->lpAppInfo;
|
||||||
|
@ -2941,6 +2975,31 @@ static VOID HTTP_CloseConnection(LPWININETHTTPREQW lpwhr)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/***********************************************************************
|
||||||
|
* HTTP_FinishedReading (internal)
|
||||||
|
*
|
||||||
|
* Called when all content from server has been read by client.
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
BOOL HTTP_FinishedReading(LPWININETHTTPREQW lpwhr)
|
||||||
|
{
|
||||||
|
WCHAR szConnectionResponse[20];
|
||||||
|
DWORD dwBufferSize = sizeof(szConnectionResponse)/sizeof(szConnectionResponse[0]);
|
||||||
|
|
||||||
|
TRACE("\n");
|
||||||
|
|
||||||
|
if (!HTTP_HttpQueryInfoW(lpwhr, HTTP_QUERY_CONNECTION, szConnectionResponse,
|
||||||
|
&dwBufferSize, NULL) ||
|
||||||
|
strcmpiW(szConnectionResponse, szKeepAlive))
|
||||||
|
{
|
||||||
|
HTTP_CloseConnection(lpwhr);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* FIXME: store data in the URL cache here */
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* HTTP_CloseHTTPRequestHandle (internal)
|
* HTTP_CloseHTTPRequestHandle (internal)
|
||||||
*
|
*
|
||||||
|
|
|
@ -1684,7 +1684,7 @@ BOOL WINAPI InternetWriteFile(HINTERNET hFile, LPCVOID lpBuffer ,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
|
BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
|
||||||
DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead,
|
DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead,
|
||||||
BOOL bWait, BOOL bSendCompletionStatus)
|
BOOL bWait, BOOL bSendCompletionStatus)
|
||||||
{
|
{
|
||||||
|
@ -1698,17 +1698,30 @@ static BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
|
||||||
{
|
{
|
||||||
case WH_HHTTPREQ:
|
case WH_HHTTPREQ:
|
||||||
lpwhr = (LPWININETHTTPREQW)lpwh;
|
lpwhr = (LPWININETHTTPREQW)lpwh;
|
||||||
|
|
||||||
if (!NETCON_recv(&lpwhr->netConnection, lpBuffer,
|
if (!NETCON_recv(&lpwhr->netConnection, lpBuffer,
|
||||||
min(dwNumOfBytesToRead, lpwhr->dwContentLength - lpwhr->dwContentRead),
|
min(dwNumOfBytesToRead, lpwhr->dwContentLength - lpwhr->dwContentRead),
|
||||||
bWait ? MSG_WAITALL : 0, &bytes_read))
|
bWait ? MSG_WAITALL : 0, &bytes_read))
|
||||||
{
|
{
|
||||||
|
|
||||||
|
if (((lpwhr->dwContentLength != -1) &&
|
||||||
|
(lpwhr->dwContentRead != lpwhr->dwContentLength)))
|
||||||
|
ERR("not all data received %d/%d\n", lpwhr->dwContentRead,
|
||||||
|
lpwhr->dwContentLength);
|
||||||
|
|
||||||
|
/* always returns TRUE, even if the network layer returns an
|
||||||
|
* error */
|
||||||
*pdwNumOfBytesRead = 0;
|
*pdwNumOfBytesRead = 0;
|
||||||
retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */
|
HTTP_FinishedReading(lpwhr);
|
||||||
|
retval = TRUE;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
lpwhr->dwContentRead += bytes_read;
|
lpwhr->dwContentRead += bytes_read;
|
||||||
*pdwNumOfBytesRead = bytes_read;
|
*pdwNumOfBytesRead = bytes_read;
|
||||||
|
if (!bytes_read)
|
||||||
|
retval = HTTP_FinishedReading(lpwhr);
|
||||||
|
else
|
||||||
retval = TRUE;
|
retval = TRUE;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
|
@ -404,6 +404,9 @@ DWORD INTERNET_GetLastError(void);
|
||||||
BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest);
|
BOOL INTERNET_AsyncCall(LPWORKREQUEST lpWorkRequest);
|
||||||
LPSTR INTERNET_GetResponseBuffer(void);
|
LPSTR INTERNET_GetResponseBuffer(void);
|
||||||
LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen);
|
LPSTR INTERNET_GetNextLine(INT nSocket, LPDWORD dwLen);
|
||||||
|
BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
|
||||||
|
DWORD dwNumOfBytesToRead, LPDWORD pdwNumOfBytesRead,
|
||||||
|
BOOL bWait, BOOL bSendCompletionStatus);
|
||||||
|
|
||||||
BOOLAPI FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
|
BOOLAPI FTP_FtpPutFileW(LPWININETFTPSESSIONW lpwfs, LPCWSTR lpszLocalFile,
|
||||||
LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD dwContext);
|
LPCWSTR lpszNewRemoteFile, DWORD dwFlags, DWORD dwContext);
|
||||||
|
@ -431,6 +434,7 @@ INTERNETAPI HINTERNET WINAPI HTTP_HttpOpenRequestW(LPWININETHTTPSESSIONW lpwhs,
|
||||||
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
|
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
|
||||||
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
|
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
|
||||||
DWORD dwFlags, DWORD dwContext);
|
DWORD dwFlags, DWORD dwContext);
|
||||||
|
BOOL HTTP_FinishedReading(LPWININETHTTPREQW lpwhr);
|
||||||
|
|
||||||
VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD dwContext,
|
VOID SendAsyncCallback(LPWININETHANDLEHEADER hdr, DWORD dwContext,
|
||||||
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
|
DWORD dwInternetStatus, LPVOID lpvStatusInfo,
|
||||||
|
|
Loading…
Reference in New Issue