[PATCH 4/7] 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.

Robert Shearman rob at codeweavers.com
Thu Jan 4 12:21:49 CST 2007


---
  dlls/wininet/http.c     |   33 +++++++++++++++++++++++----------
  dlls/wininet/internet.c |   15 ++++++++++++---
  dlls/wininet/internet.h |    2 ++
  3 files changed, 37 insertions(+), 13 deletions(-)
-------------- next part --------------
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 6a155c5..b41c714 100644
--- a/dlls/wininet/internet.c
+++ b/dlls/wininet/internet.c
@@ -1716,19 +1716,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:
@@ -3362,7 +3370,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 4015ee0..d409ebf 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-patches mailing list