Rob Shearman : wininet:
Use the Content-Length header to work out how much HTTP data there is
left to be read
Alexandre Julliard
julliard at wine.codeweavers.com
Thu Jan 4 15:09:29 CST 2007
Module: wine
Branch: master
Commit: ac1b527498a732f9c2a502af4278ad14c452d1a6
URL: http://source.winehq.org/git/wine.git/?a=commit;h=ac1b527498a732f9c2a502af4278ad14c452d1a6
Author: Rob Shearman <rob at codeweavers.com>
Date: Thu Jan 4 18:21:49 2007 +0000
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.
---
dlls/wininet/http.c | 33 +++++++++++++++++++++++----------
dlls/wininet/internet.c | 15 ++++++++++++---
dlls/wininet/internet.h | 2 ++
3 files changed, 37 insertions(+), 13 deletions(-)
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index 336f1fb..d7e1d33 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -605,6 +605,7 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hR
BOOL rc = FALSE;
LPWININETHTTPREQW lpwhr;
INT responseLen;
+ DWORD dwBufferSize;
TRACE("-->\n");
lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hRequest );
@@ -618,6 +619,8 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hR
lpwhr->hdr.dwFlags |= dwFlags;
lpwhr->hdr.dwContext = dwContext;
+ /* We appear to do nothing with lpBuffersOut.. is that correct? */
+
SendAsyncCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
@@ -631,18 +634,20 @@ BOOL WINAPI HttpEndRequestW(HINTERNET hR
/* process headers here. Is this right? */
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))
{
- DWORD dwCode,dwCodeLength=sizeof(DWORD),dwIndex=0;
- if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,&dwIndex) &&
+ DWORD dwCode,dwCodeLength=sizeof(DWORD);
+ if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) &&
(dwCode==302 || dwCode==301))
{
WCHAR szNewLocation[2048];
- DWORD dwBufferSize=2048;
- dwIndex=0;
- if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,&dwIndex))
+ dwBufferSize=2048;
+ if(HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,NULL))
{
static const WCHAR szGET[] = { 'G','E','T', 0 };
/* redirects are always GETs */
@@ -2255,6 +2260,7 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWINI
char *ascii_req;
loop_next = FALSE;
+ lpwhr->dwContentRead = 0;
if (TRACE_ON(wininet))
{
@@ -2311,6 +2317,8 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWINI
if (bEndRequest)
{
+ DWORD dwBufferSize;
+
INTERNET_SendCallback(&lpwhr->hdr, lpwhr->hdr.dwContext,
INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
@@ -2327,14 +2335,19 @@ BOOL WINAPI HTTP_HttpSendRequestW(LPWINI
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)
{
- DWORD dwCode,dwCodeLength=sizeof(DWORD),dwIndex=0;
+ DWORD dwCode,dwCodeLength=sizeof(DWORD);
WCHAR szNewLocation[2048];
- DWORD dwBufferSize=2048;
- if (HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,&dwIndex) &&
+ dwBufferSize=2048;
+ if (HTTP_HttpQueryInfoW(lpwhr,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,NULL) &&
(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_STATUS_REDIRECT, szNewLocation,
diff --git a/dlls/wininet/internet.c b/dlls/wininet/internet.c
index cef4526..a7568d4 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -1690,19 +1690,27 @@ static BOOL INTERNET_ReadFile(LPWININETH
{
BOOL retval = FALSE;
int nSocket = -1;
+ int bytes_read;
+ LPWININETHTTPREQW lpwhr;
/* FIXME: this should use NETCON functions! */
switch (lpwh->htype)
{
case WH_HHTTPREQ:
- if (!NETCON_recv(&((LPWININETHTTPREQW)lpwh)->netConnection, lpBuffer,
- dwNumOfBytesToRead, bWait ? MSG_WAITALL : 0, (int *)pdwNumOfBytesRead))
+ lpwhr = (LPWININETHTTPREQW)lpwh;
+ if (!NETCON_recv(&lpwhr->netConnection, lpBuffer,
+ min(dwNumOfBytesToRead, lpwhr->dwContentLength - lpwhr->dwContentRead),
+ bWait ? MSG_WAITALL : 0, &bytes_read))
{
*pdwNumOfBytesRead = 0;
retval = TRUE; /* Under windows, it seems to return 0 even if nothing was read... */
}
else
+ {
+ lpwhr->dwContentRead += bytes_read;
+ *pdwNumOfBytesRead = bytes_read;
retval = TRUE;
+ }
break;
case WH_HFILE:
@@ -3216,7 +3224,8 @@ BOOL WINAPI InternetQueryDataAvailable(
{
case WH_HHTTPREQ:
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);
retval = FALSE;
diff --git a/dlls/wininet/internet.h b/dlls/wininet/internet.h
index 1524139..4af22ea 100644
--- a/dlls/wininet/internet.h
+++ b/dlls/wininet/internet.h
@@ -197,6 +197,8 @@ typedef struct
WININET_NETCONNECTION netConnection;
LPWSTR lpszVersion;
LPWSTR lpszStatusText;
+ DWORD dwContentLength; /* total number of bytes to be read */
+ DWORD dwContentRead; /* bytes of the content read so far */
HTTPHEADERW *pCustHeaders;
DWORD nCustHeaders;
} WININETHTTPREQW, *LPWININETHTTPREQW;
More information about the wine-cvs
mailing list