Wininet improvements

Alberto Massari alby at exln.com
Thu Dec 5 13:43:31 CST 2002


Changelog:
 - when sending a request using HttpOpenRequest/HttpSendRequest, send the
   User-Agent header; fixed the Accept and the Referer header handling to
   really work
 - fixed bug in the HTTP_ProcessHeader: when a second value was supposed to be
   added to an existing one, the buffer was reduced to be 1 char long instead 
   of being expanded, due to the precedence rules of the operator '?'
 - added support for opening URLs that redirect to a different place

Alberto


Index: http.c
===================================================================
RCS file: /home/wine/wine/dlls/wininet/http.c,v
retrieving revision 1.31
diff -u -r1.31 http.c
--- http.c	13 Nov 2002 04:08:26 -0000	1.31
+++ http.c	5 Dec 2002 19:32:37 -0000
@@ -58,8 +58,9 @@
 #define MAX_FIELD_LEN 256
 
 
-#define HTTP_REFERER	"Referer"
-#define HTTP_ACCEPT		"Accept"
+#define HTTP_REFERER    "Referer"
+#define HTTP_ACCEPT     "Accept"
+#define HTTP_USERAGENT  "User-Agent"
 
 #define HTTP_ADDHDR_FLAG_ADD				0x20000000
 #define HTTP_ADDHDR_FLAG_ADD_IF_NEW			0x10000000
@@ -200,7 +201,13 @@
     LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) hHttpSession;
     LPWININETAPPINFOA hIC = NULL;
 
-    TRACE("\n");
+    TRACE("(%s, %s, %s, %s, %ld, %ld)\n", lpszVerb, lpszObjectName, lpszVersion, lpszReferrer, dwFlags, dwContext);
+    if(lpszAcceptTypes!=NULL)
+    {
+        int i;
+        for(i=0;lpszAcceptTypes[i]!=NULL;i++)
+            TRACE("\taccept type: %s\n",lpszAcceptTypes[i]);
+    }    
 
     if (NULL == lpwhs ||  lpwhs->hdr.htype != WH_HHTTPSESSION)
     {
@@ -266,6 +273,8 @@
 {
     char szVerb[20],
          szObjectName[INTERNET_MAX_PATH_LENGTH];
+    TRACE("(%s, %s, %s, %s, %ld, %ld)\n", debugstr_w(lpszVerb), debugstr_w(lpszObjectName), debugstr_w(lpszVersion), debugstr_w(lpszReferrer), dwFlags, dwContext);
+
     if(lpszVerb!=NULL)
         WideCharToMultiByte(CP_ACP,0,lpszVerb,-1,szVerb,20,NULL,NULL);
     else
@@ -276,7 +285,7 @@
         szObjectName[0]=0;
     TRACE("object name=%s\n",szObjectName);
     FIXME("lpszVersion, lpszReferrer and lpszAcceptTypes ignored\n");
-    return HttpOpenRequestA(hHttpSession, szVerb, szObjectName, NULL, NULL, NULL, dwFlags, dwContext);
+    return HttpOpenRequestA(hHttpSession, szVerb[0]?szVerb:NULL, szObjectName, NULL, NULL, NULL, dwFlags, dwContext);
 }
 
 /***********************************************************************
@@ -337,12 +346,18 @@
         }
     }
 
+    if (NULL != hIC->lpszAgent && strlen(hIC->lpszAgent))
+        HTTP_ProcessHeader(lpwhr, HTTP_USERAGENT, hIC->lpszAgent, HTTP_ADDHDR_FLAG_REQ|HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDHDR_FLAG_ADD_IF_NEW);
+
     if (NULL != lpszReferrer && strlen(lpszReferrer))
-        HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpszReferrer, HTTP_ADDHDR_FLAG_COALESCE);
+        HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpszReferrer, HTTP_ADDHDR_FLAG_REQ|HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDHDR_FLAG_ADD_IF_NEW);
 
-    /* FIXME */
-    if (NULL != lpszAcceptTypes && strlen(*lpszAcceptTypes))
-        HTTP_ProcessHeader(lpwhr, HTTP_ACCEPT, *lpszAcceptTypes, HTTP_ADDHDR_FLAG_COALESCE);
+    if(lpszAcceptTypes!=NULL)
+    {
+        int i;
+        for(i=0;lpszAcceptTypes[i]!=NULL;i++)
+            HTTP_ProcessHeader(lpwhr, HTTP_ACCEPT, lpszAcceptTypes[i], HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA|HTTP_ADDHDR_FLAG_REQ|HTTP_ADDHDR_FLAG_ADD_IF_NEW);
+    }
 
     if (NULL == lpszVerb)
         lpwhr->lpszVerb = HTTP_strdup("GET");
@@ -695,9 +710,9 @@
 
         INTERNET_AsyncCall(&workRequest);
         /*
-         * This is from windows. I do not know what the name is
+         * This is from windows.
          */
-        SetLastError(0x3e5);
+        SetLastError(ERROR_IO_PENDING);
         return 0;
     }
     else
@@ -737,6 +752,103 @@
 }
 
 /***********************************************************************
+ *           HandleRedirect (internal)
+ */
+
+BOOL HandleRedirect(LPWININETHTTPREQA lpwhr, LPCSTR lpszUrl, LPCSTR lpszHeaders,
+                    DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength)
+{
+    LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) lpwhr->hdr.lpwhparent;
+    LPWININETAPPINFOA hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent;
+    char path[2048];
+    if(lpszUrl[0]=='/')
+    {
+        /* if it's an absolute path, keep the same session info */
+        strcpy(path,lpszUrl);
+    }
+    else
+    {
+        URL_COMPONENTSA urlComponents;
+        char protocol[32], hostName[MAXHOSTNAME], userName[1024];
+        char password[1024], extra[1024];
+        urlComponents.dwStructSize = sizeof(URL_COMPONENTSA);
+        urlComponents.lpszScheme = protocol;
+        urlComponents.dwSchemeLength = 32;
+        urlComponents.lpszHostName = hostName;
+        urlComponents.dwHostNameLength = MAXHOSTNAME;
+        urlComponents.lpszUserName = userName;
+        urlComponents.dwUserNameLength = 1024;
+        urlComponents.lpszPassword = password;
+        urlComponents.dwPasswordLength = 1024;
+        urlComponents.lpszUrlPath = path;
+        urlComponents.dwUrlPathLength = 2048;
+        urlComponents.lpszExtraInfo = extra;
+        urlComponents.dwExtraInfoLength = 1024;
+        if(!InternetCrackUrlA(lpszUrl, strlen(lpszUrl), 0, &urlComponents))
+            return FALSE;
+        
+        if (urlComponents.nPort == INTERNET_INVALID_PORT_NUMBER)
+            urlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT;
+
+        /* consider the current host as the referef */
+        if (NULL != lpwhs->lpszServerName && strlen(lpwhs->lpszServerName))
+            HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpwhs->lpszServerName, HTTP_ADDHDR_FLAG_REQ|HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDHDR_FLAG_ADD_IF_NEW);
+        
+        if (NULL != lpwhs->lpszServerName)
+            HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName);
+        lpwhs->lpszServerName = HTTP_strdup(hostName);
+        if (NULL != lpwhs->lpszUserName)
+            HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName);
+        lpwhs->lpszUserName = HTTP_strdup(userName);
+        lpwhs->nServerPort = urlComponents.nPort;
+
+        if (NULL != lpwhr->lpszHostName)
+            HeapFree(GetProcessHeap(), 0, lpwhr->lpszHostName);
+        lpwhr->lpszHostName=HTTP_strdup(hostName);
+
+        SendAsyncCallback(hIC, lpwhs, lpwhr->hdr.dwContext,
+                      INTERNET_STATUS_RESOLVING_NAME,
+                      lpwhs->lpszServerName,
+                      strlen(lpwhs->lpszServerName)+1);
+
+        if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort,
+                    &lpwhs->phostent, &lpwhs->socketAddress))
+        {
+            INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED);
+            return FALSE;
+        }
+
+        SendAsyncCallback(hIC, lpwhs, lpwhr->hdr.dwContext,
+                      INTERNET_STATUS_NAME_RESOLVED,
+                      &(lpwhs->socketAddress),
+                      sizeof(struct sockaddr_in));
+
+    }
+
+    if(lpwhr->lpszPath)
+        HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
+    lpwhr->lpszPath=NULL;
+    if (strlen(path))
+    {
+        DWORD needed = 0;
+        HRESULT rc;
+        rc = UrlEscapeA(path, NULL, &needed, URL_ESCAPE_SPACES_ONLY);
+        if (rc != E_POINTER)
+            needed = strlen(path)+1;
+        lpwhr->lpszPath = HeapAlloc(GetProcessHeap(), 0, needed);
+        rc = UrlEscapeA(path, lpwhr->lpszPath, &needed,
+                        URL_ESCAPE_SPACES_ONLY);
+        if (rc)
+        {
+            ERR("Unable to escape string!(%s) (%ld)\n",path,rc);
+            strcpy(lpwhr->lpszPath,path);
+        }
+    }
+
+    return HttpSendRequestA((HINTERNET)lpwhr, lpszHeaders, dwHeaderLength, lpOptional, dwOptionalLength);
+}
+
+/***********************************************************************
  *           HTTP_HttpSendRequestA (internal)
  *
  * Sends the specified request to the HTTP server
@@ -863,6 +975,7 @@
        {
            cnt += sprintf(requestString + cnt, "\r\n%s: %s",
                lpwhr->StdHeaders[i].lpszField, lpwhr->StdHeaders[i].lpszValue);
+           TRACE("Adding header %s (%s)\n",lpwhr->StdHeaders[i].lpszField,lpwhr->StdHeaders[i].lpszValue);
        }
     }
 
@@ -873,6 +986,7 @@
        {
            cnt += sprintf(requestString + cnt, "\r\n%s: %s",
                lpwhr->pCustHeaders[i].lpszField, lpwhr->pCustHeaders[i].lpszValue);
+           TRACE("Adding custom header %s (%s)\n",lpwhr->pCustHeaders[i].lpszField,lpwhr->pCustHeaders[i].lpszValue);
        }
     }
 
@@ -921,6 +1035,27 @@
     if (requestString)
         HeapFree(GetProcessHeap(), 0, requestString);
 
+    /* TODO: send notification for P3P header */
+    
+    if(!(hIC->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && bSuccess)
+    {
+        DWORD dwCode,dwCodeLength=sizeof(DWORD),dwIndex=0;
+        if(HttpQueryInfoA(hHttpRequest,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,&dwIndex) &&
+            (dwCode==302 || dwCode==301))
+        {
+            char szNewLocation[2048];
+            DWORD dwBufferSize=2048;
+            dwIndex=0;
+            if(HttpQueryInfoA(hHttpRequest,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,&dwIndex))
+            {
+                SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
+                      INTERNET_STATUS_REDIRECT, szNewLocation,
+                      dwBufferSize);
+                return HandleRedirect(lpwhr, szNewLocation, lpszHeaders,
+                                      dwHeaderLength, lpOptional, dwOptionalLength);
+            }
+        }
+    }
 
     if (hIC->lpfnStatusCB)
     {
@@ -1292,7 +1427,7 @@
     BOOL bSuccess = FALSE;
     INT index;
 
-    TRACE("--> %s:%s - 0x%08x\n", field, value, (unsigned int)dwModifier);
+    TRACE("--> %s: %s - 0x%08x\n", field, value, (unsigned int)dwModifier);
 
     /* Adjust modifier flags */
     if (dwModifier & COALESCEFLASG)
@@ -1387,6 +1522,7 @@
                 }
                 else
                 {
+                    WARN("HeapReAlloc (%d bytes) failed\n",len+1);
                     INTERNET_SetLastError(ERROR_OUTOFMEMORY);
                 }
             }
@@ -1410,7 +1546,7 @@
                 lphttpHdr->wFlags |= HDR_COMMADELIMITED;
             }
 
-            len = origlen + valuelen + (ch > 0) ? 1 : 0;
+            len = origlen + valuelen + ((ch > 0) ? 1 : 0);
 
             lpsztmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,  lphttpHdr->lpszValue, len+1);
             if (lpsztmp)
@@ -1428,11 +1564,12 @@
             }
             else
             {
+                WARN("HeapReAlloc (%d bytes) failed\n",len+1);
                 INTERNET_SetLastError(ERROR_OUTOFMEMORY);
             }
         }
     }
-    TRACE("<--\n");
+    TRACE("<-- %d\n",bSuccess);
     return bSuccess;
 }
 





More information about the wine-patches mailing list