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:
Rob Shearman 2007-01-04 18:23:17 +00:00 committed by Alexandre Julliard
parent f0163ae7d6
commit 272954bd81
3 changed files with 81 additions and 5 deletions

View File

@ -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)
* *

View File

@ -1684,9 +1684,9 @@ 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)
{ {
BOOL retval = FALSE; BOOL retval = FALSE;
int nSocket = -1; int nSocket = -1;
@ -1698,18 +1698,31 @@ 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;
retval = TRUE; if (!bytes_read)
retval = HTTP_FinishedReading(lpwhr);
else
retval = TRUE;
} }
break; break;

View File

@ -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,