wininet: Use the Content-Length header to work out how much HTTP data there is left to be read

and don't try to read any more than what is available.
This commit is contained in:
Rob Shearman 2007-01-04 18:21:49 +00:00 committed by Alexandre Julliard
parent cf43b16036
commit ac1b527498
3 changed files with 37 additions and 13 deletions

View File

@ -605,6 +605,7 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest,
BOOL rc = FALSE; BOOL rc = FALSE;
LPWININETHTTPREQW lpwhr; LPWININETHTTPREQW lpwhr;
INT responseLen; INT responseLen;
DWORD dwBufferSize;
TRACE("-->\n"); TRACE("-->\n");
lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest ); lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest );
@ -618,6 +619,8 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest,
lpwhr->hdr.dwFlags |= dwFlags; lpwhr->hdr.dwFlags |= dwFlags;
lpwhr->hdr.dwContext = dwContext; lpwhr->hdr.dwContext = dwContext;
/* We appear to do nothing with lpBuffersOut.. is that correct? */
SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
@ -631,18 +634,20 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hRequest,
/* process headers here. Is this right? */ /* process headers here. Is this right? */
HTTP_ProcessHeaders(lpwhr); HTTP_ProcessHeaders(lpwhr);
/* We appear to do nothing with the buffer.. is that correct? */ dwBufferSize = sizeof(lpwhr->dwContentLength);
if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
&lpwhr->dwContentLength,&dwBufferSize,NULL))
lpwhr->dwContentLength = -1;
if(!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT)) if(!(lpwhr->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT))
{ {
DWORD dwCode,dwCodeLength=sizeof(DWORD),dwIndex=0; DWORD dwCode,dwCodeLength=sizeof(DWORD);
if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,&dwIndex) && if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) &&
(dwCode==302 || dwCode==301)) (dwCode==302 || dwCode==301))
{ {
WCHAR szNewLocation[2048]; WCHAR szNewLocation[2048];
DWORD dwBufferSize=2048; dwBufferSize=2048;
dwIndex=0; if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,&dwIndex))
{ {
static const WCHAR szGET[] = { 'G','E','T', 0 }; static const WCHAR szGET[] = { 'G','E','T', 0 };
/* redirects are always GETs */ /* redirects are always GETs */
@ -2255,6 +2260,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
char *ascii_req; char *ascii_req;
loop_next = FALSE; loop_next = FALSE;
lpwhr->dwContentRead = 0;
if (TRACE_ON(wininet)) if (TRACE_ON(wininet))
{ {
@ -2311,6 +2317,8 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
if (bEndRequest) if (bEndRequest)
{ {
DWORD dwBufferSize;
INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
@ -2327,14 +2335,19 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWININETHTTPREQW lpwhr, LPCWSTR lpszHeaders,
HTTP_ProcessHeaders(lpwhr); HTTP_ProcessHeaders(lpwhr);
dwBufferSize = sizeof(lpwhr->dwContentLength);
if (!HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_CONTENT_LENGTH,
&lpwhr->dwContentLength,&dwBufferSize,NULL))
lpwhr->dwContentLength = -1;
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),dwIndex=0; DWORD dwCode,dwCodeLength=sizeof(DWORD);
WCHAR szNewLocation[2048]; WCHAR szNewLocation[2048];
DWORD dwBufferSize=2048; dwBufferSize=2048;
if (HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,&dwIndex) && if (HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) &&
(dwCode==HTTP_STATUS_REDIRECT || dwCode==HTTP_STATUS_MOVED) && (dwCode==HTTP_STATUS_REDIRECT || dwCode==HTTP_STATUS_MOVED) &&
HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,&dwIndex)) HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
{ {
INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext, INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_REDIRECT, szNewLocation, INTERNET_STATUS_REDIRECT, szNewLocation,

View File

@ -1690,19 +1690,27 @@ static BOOL INTERNET_ReadFile(LPWININETHANDLEHEADER lpwh, LPVOID lpBuffer,
{ {
BOOL retval = FALSE; BOOL retval = FALSE;
int nSocket = -1; int nSocket = -1;
int bytes_read;
LPWININETHTTPREQW lpwhr;
/* FIXME: this should use NETCON functions! */ /* FIXME: this should use NETCON functions! */
switch (lpwh->htype) switch (lpwh->htype)
{ {
case WH_HHTTPREQ: case WH_HHTTPREQ:
if (!NETCON_recv(&((LPWININETHTTPREQW)lpwh)->netConnection, lpBuffer, lpwhr = (LPWININETHTTPREQW)lpwh;
dwNumOfBytesToRead, bWait ? MSG_WAITALL : 0, (int *)pdwNumOfBytesRead)) if (!NETCON_recv(&lpwhr->netConnection, lpBuffer,
min(dwNumOfBytesToRead, lpwhr->dwContentLength - lpwhr->dwContentRead),
bWait ? MSG_WAITALL : 0, &bytes_read))
{ {
*pdwNumOfBytesRead = 0; *pdwNumOfBytesRead = 0;
retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */ retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */
} }
else else
{
lpwhr->dwContentRead += bytes_read;
*pdwNumOfBytesRead = bytes_read;
retval = TRUE; retval = TRUE;
}
break; break;
case WH_HFILE: case WH_HFILE:
@ -3216,7 +3224,8 @@ BOOL WINAPI InternetQueryDataAvailable( HINTERNET hFile,
{ {
case WH_HHTTPREQ: case WH_HHTTPREQ:
if (!NETCON_recv(&lpwhr->netConnection, buffer, if (!NETCON_recv(&lpwhr->netConnection, buffer,
4048, MSG_PEEK, (int *)lpdwNumberOfBytesAvailble)) min(sizeof(buffer), lpwhr->dwContentLength - lpwhr->dwContentRead),
MSG_PEEK, (int *)lpdwNumberOfBytesAvailble))
{ {
SetLastError(ERROR_NO_MORE_FILES); SetLastError(ERROR_NO_MORE_FILES);
retval = FALSE; retval = FALSE;

View File

@ -197,6 +197,8 @@ typedef struct
WININET_NETCONNECTION netConnection; WININET_NETCONNECTION netConnection;
LPWSTR lpszVersion; LPWSTR lpszVersion;
LPWSTR lpszStatusText; LPWSTR lpszStatusText;
DWORD dwContentLength; /* total number of bytes to be read */
DWORD dwContentRead; /* bytes of the content read so far */
HTTPHEADERW *pCustHeaders; HTTPHEADERW *pCustHeaders;
DWORD nCustHeaders; DWORD nCustHeaders;
} WININETHTTPREQW, *LPWININETHTTPREQW; } WININETHTTPREQW, *LPWININETHTTPREQW;