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