- implemented support for https protocol
- fixes to the http protocol
diff --git a/dlls/wininet/http.c b/dlls/wininet/http.c
index df2a1eb..7cc2d38 100644
--- a/dlls/wininet/http.c
+++ b/dlls/wininet/http.c
@@ -3,9 +3,11 @@
*
* Copyright 1999 Corel Corporation
* Copyright 2002 CodeWeavers Inc.
+ * Copyright 2002 TransGaming Technologies Inc.
*
* Ulrich Czekalla
* Aric Stewart
+ * David Hammerton
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -111,7 +113,9 @@
BOOL bSuccess = FALSE;
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest;
- TRACE("\n");
+ TRACE("%p, %s, %li, %li\n", hHttpRequest, lpszHeader, dwHeaderLength,
+ dwModifier);
+
if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ)
{
@@ -121,6 +125,8 @@
if (!lpszHeader)
return TRUE;
+
+ TRACE("copying header: %s\n", lpszHeader);
buffer = HTTP_strdup(lpszHeader);
lpszStart = buffer;
@@ -140,6 +146,7 @@
*lpszEnd = '\0';
+ TRACE("interpreting header %s\n", debugstr_a(lpszStart));
if (HTTP_InterpretHttpHeader(lpszStart, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
bSuccess = HTTP_ProcessHeader(lpwhr, field, value, dwModifier | HTTP_ADDHDR_FLAG_REQ);
@@ -203,7 +210,10 @@
LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) hHttpSession;
LPWININETAPPINFOA hIC = NULL;
- TRACE("(%s, %s, %s, %s, %ld, %ld)\n", lpszVerb, lpszObjectName, lpszVersion, lpszReferrer, dwFlags, dwContext);
+ TRACE("(%p, %s, %s, %s, %s, %p, %08lx, %08lx)\n", hHttpSession,
+ debugstr_a(lpszVerb), lpszObjectName,
+ debugstr_a(lpszVersion), debugstr_a(lpszReferrer), lpszAcceptTypes,
+ dwFlags, dwContext);
if(lpszAcceptTypes!=NULL)
{
int i;
@@ -249,15 +259,20 @@
workRequest.DWCONTEXT = dwContext;
INTERNET_AsyncCall(&workRequest);
+ TRACE ("returning NULL\n");
return NULL;
}
else
{
- return HTTP_HttpOpenRequestA(hHttpSession, lpszVerb, lpszObjectName,
- lpszVersion, lpszReferrer, lpszAcceptTypes, dwFlags, dwContext);
+ HINTERNET rec = HTTP_HttpOpenRequestA(hHttpSession, lpszVerb, lpszObjectName,
+ lpszVersion, lpszReferrer, lpszAcceptTypes,
+ dwFlags, dwContext);
+ TRACE("returning %p\n", rec);
+ return rec;
}
}
+
/***********************************************************************
* HttpOpenRequestW (WININET.@)
*
@@ -267,27 +282,95 @@
* HINTERNET a HTTP request handle on success
* NULL on failure
*
+ * FIXME: This should be the other way around (A should call W)
*/
HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession,
LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion,
LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes,
DWORD dwFlags, DWORD dwContext)
{
- 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);
+ CHAR *szVerb = NULL, *szObjectName = NULL;
+ CHAR *szVersion = NULL, *szReferrer = NULL, **szAcceptTypes = NULL;
+ INT len;
+ INT acceptTypesCount;
+ HINTERNET rc = FALSE;
+ TRACE("(%p, %s, %s, %s, %s, %p, %08lx, %08lx)\n", hHttpSession,
+ debugstr_w(lpszVerb), debugstr_w(lpszObjectName),
+ debugstr_w(lpszVersion), debugstr_w(lpszReferrer), lpszAcceptTypes,
+ dwFlags, dwContext);
- if(lpszVerb!=NULL)
- WideCharToMultiByte(CP_ACP,0,lpszVerb,-1,szVerb,20,NULL,NULL);
- else
- szVerb[0]=0;
- if(lpszObjectName!=NULL)
- WideCharToMultiByte(CP_ACP,0,lpszObjectName,-1,szObjectName,INTERNET_MAX_PATH_LENGTH,NULL,NULL);
- else
- szObjectName[0]=0;
- TRACE("object name=%s\n",szObjectName);
- FIXME("lpszVersion, lpszReferrer and lpszAcceptTypes ignored\n");
- return HttpOpenRequestA(hHttpSession, szVerb[0]?szVerb:NULL, szObjectName, NULL, NULL, NULL, dwFlags, dwContext);
+ if (lpszVerb)
+ {
+ len = lstrlenW(lpszVerb)+1;
+ if (!(szVerb = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
+ goto end;
+ WideCharToMultiByte(CP_ACP, -1, lpszVerb, -1, szVerb, len, NULL, NULL);
+ }
+
+ if (lpszObjectName)
+ {
+ len = lstrlenW(lpszObjectName)+1;
+ if (!(szObjectName = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
+ goto end;
+ WideCharToMultiByte(CP_ACP, -1, lpszObjectName, -1, szObjectName, len, NULL, NULL);
+ }
+
+ if (lpszVersion)
+ {
+ len = lstrlenW(lpszVersion)+1;
+ if (!(szVersion = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
+ goto end;
+ WideCharToMultiByte(CP_ACP, -1, lpszVersion, -1, szVersion, len, NULL, NULL);
+ }
+
+ if (lpszReferrer)
+ {
+ len = lstrlenW(lpszReferrer)+1;
+ if (!(szReferrer = (CHAR *) HeapAlloc(GetProcessHeap(), 0, len * sizeof(CHAR))))
+ goto end;
+ WideCharToMultiByte(CP_ACP, -1, lpszReferrer, -1, szReferrer, len, NULL, NULL);
+ }
+
+ acceptTypesCount = 0;
+ if (lpszAcceptTypes)
+ {
+ while (lpszAcceptTypes[acceptTypesCount]) { acceptTypesCount++; } /* find out how many there are */
+ szAcceptTypes = HeapAlloc(GetProcessHeap(), 0, sizeof(CHAR *) * acceptTypesCount);
+ acceptTypesCount = 0;
+ while (lpszAcceptTypes[acceptTypesCount])
+ {
+ len = lstrlenW(lpszAcceptTypes[acceptTypesCount])+1;
+ if (!(szAcceptTypes[acceptTypesCount] = (CHAR *) HeapAlloc(GetProcessHeap(),
+ 0, len * sizeof(CHAR))))
+ goto end;
+ WideCharToMultiByte(CP_ACP, -1, lpszAcceptTypes[acceptTypesCount],
+ -1, szAcceptTypes[acceptTypesCount], len, NULL, NULL);
+ acceptTypesCount++;
+ }
+ }
+ else szAcceptTypes = 0;
+
+ rc = HttpOpenRequestA(hHttpSession, (LPCSTR)szVerb, (LPCSTR)szObjectName,
+ (LPCSTR)szVersion, (LPCSTR)szReferrer,
+ (LPCSTR *)szAcceptTypes, dwFlags, dwContext);
+
+end:
+ if (szAcceptTypes)
+ {
+ acceptTypesCount = 0;
+ while (szAcceptTypes[acceptTypesCount])
+ {
+ HeapFree(GetProcessHeap(), 0, szAcceptTypes[acceptTypesCount]);
+ acceptTypesCount++;
+ }
+ HeapFree(GetProcessHeap(), 0, szAcceptTypes);
+ }
+ if (szReferrer) HeapFree(GetProcessHeap(), 0, szReferrer);
+ if (szVersion) HeapFree(GetProcessHeap(), 0, szVersion);
+ if (szObjectName) HeapFree(GetProcessHeap(), 0, szObjectName);
+ if (szVerb) HeapFree(GetProcessHeap(), 0, szVerb);
+
+ return rc;
}
/***********************************************************************
@@ -308,6 +391,9 @@
LPWININETHTTPSESSIONA lpwhs = (LPWININETHTTPSESSIONA) hHttpSession;
LPWININETAPPINFOA hIC = NULL;
LPWININETHTTPREQA lpwhr;
+ LPSTR lpszCookies;
+ LPSTR lpszUrl = NULL;
+ DWORD nCookieSize;
TRACE("--> \n");
@@ -330,7 +416,7 @@
lpwhr->hdr.lpwhparent = hHttpSession;
lpwhr->hdr.dwFlags = dwFlags;
lpwhr->hdr.dwContext = dwContext;
- lpwhr->nSocketFD = -1;
+ NETCON_init(&lpwhr->netConnection, dwFlags & INTERNET_FLAG_SECURE);
if (NULL != lpszObjectName && strlen(lpszObjectName)) {
DWORD needed = 0;
@@ -348,11 +434,8 @@
}
}
- 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_REQ|HTTP_ADDREQ_FLAG_REPLACE|HTTP_ADDHDR_FLAG_ADD_IF_NEW);
+ HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpszReferrer, HTTP_ADDHDR_FLAG_COALESCE);
if(lpszAcceptTypes!=NULL)
{
@@ -366,7 +449,7 @@
else if (strlen(lpszVerb))
lpwhr->lpszVerb = HTTP_strdup(lpszVerb);
- if (NULL != lpszReferrer)
+ if (NULL != lpszReferrer && strlen(lpszReferrer))
{
char buf[MAXHOSTNAME];
URL_COMPONENTSA UrlComponents;
@@ -420,6 +503,36 @@
lpwhr->lpszHostName = HTTP_strdup(lpwhs->lpszServerName);
}
+ if (hIC->lpszAgent)
+ {
+ char *agent_header = HeapAlloc(GetProcessHeap(), 0, strlen(hIC->lpszAgent) + 1 + 14);
+ sprintf(agent_header, "User-Agent: %s\r\n", hIC->lpszAgent);
+ HttpAddRequestHeadersA((HINTERNET)lpwhr, agent_header, strlen(agent_header),
+ HTTP_ADDREQ_FLAG_ADD);
+ HeapFree(GetProcessHeap(), 0, agent_header);
+ }
+
+ lpszUrl = HeapAlloc(GetProcessHeap(), 0, strlen(lpwhr->lpszHostName) + 1 + 7);
+ sprintf(lpszUrl, "http://%s", lpwhr->lpszHostName);
+ if (InternetGetCookieA(lpszUrl, NULL, NULL, &nCookieSize))
+ {
+ int cnt = 0;
+
+ lpszCookies = HeapAlloc(GetProcessHeap(), 0, nCookieSize + 1 + 8);
+
+ cnt += sprintf(lpszCookies, "Cookie: ");
+ InternetGetCookieA(lpszUrl, NULL, lpszCookies + cnt, &nCookieSize);
+ cnt += nCookieSize - 1;
+ sprintf(lpszCookies + cnt, "\r\n");
+
+ HttpAddRequestHeadersA((HINTERNET)lpwhr, lpszCookies, strlen(lpszCookies),
+ HTTP_ADDREQ_FLAG_ADD);
+ HeapFree(GetProcessHeap(), 0, lpszCookies);
+ }
+ HeapFree(GetProcessHeap(), 0, lpszUrl);
+
+
+
if (hIC->lpfnStatusCB)
{
INTERNET_ASYNC_RESULT iar;
@@ -443,7 +556,6 @@
INTERNET_STATUS_RESOLVING_NAME,
lpwhs->lpszServerName,
strlen(lpwhs->lpszServerName)+1);
-
if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort,
&lpwhs->phostent, &lpwhs->socketAddress))
{
@@ -906,6 +1018,8 @@
LPWININETHTTPREQA lpwhr = (LPWININETHTTPREQA) hHttpRequest;
LPWININETHTTPSESSIONA lpwhs = NULL;
LPWININETAPPINFOA hIC = NULL;
+ BOOL loop_next = FALSE;
+ int CustHeaderIndex;
TRACE("--> 0x%08lx\n", (ULONG)hHttpRequest);
@@ -940,131 +1054,272 @@
goto lend;
}
- /* If we don't have a path we set it to root */
- if (NULL == lpwhr->lpszPath)
- lpwhr->lpszPath = HTTP_strdup("/");
-
- if(strncmp(lpwhr->lpszPath, "http://", sizeof("http://") -1) != 0
- && lpwhr->lpszPath[0] != '/') /* not an absolute path ?? --> fix it !! */
+ do
{
- char *fixurl = HeapAlloc(GetProcessHeap(), 0, strlen(lpwhr->lpszPath) + 2);
- *fixurl = '/';
- strcpy(fixurl + 1, lpwhr->lpszPath);
- HeapFree( GetProcessHeap(), 0, lpwhr->lpszPath );
- lpwhr->lpszPath = fixurl;
- }
+ TRACE("Going to url %s %s\n", debugstr_a(lpwhr->lpszHostName), debugstr_a(lpwhr->lpszPath));
+ loop_next = FALSE;
- /* Calculate length of request string */
- requestStringLen =
- strlen(lpwhr->lpszVerb) +
- strlen(lpwhr->lpszPath) +
- (lpwhr->lpszHostName ? (strlen(HTTPHOSTHEADER) + strlen(lpwhr->lpszHostName)) : 0) +
- strlen(HTTPHEADER) +
- 5; /* " \r\n\r\n" */
+ /* If we don't have a path we set it to root */
+ if (NULL == lpwhr->lpszPath)
+ lpwhr->lpszPath = HTTP_strdup("/");
- /* Add length of passed headers */
- if (lpszHeaders)
- {
- headerLength = -1 == dwHeaderLength ? strlen(lpszHeaders) : dwHeaderLength;
- requestStringLen += headerLength + 2; /* \r\n */
- }
+ if(strncmp(lpwhr->lpszPath, "http://", sizeof("http://") -1) != 0
+ && lpwhr->lpszPath[0] != '/') /* not an absolute path ?? --> fix it !! */
+ {
+ char *fixurl = HeapAlloc(GetProcessHeap(), 0, strlen(lpwhr->lpszPath) + 2);
+ *fixurl = '/';
+ strcpy(fixurl + 1, lpwhr->lpszPath);
+ HeapFree( GetProcessHeap(), 0, lpwhr->lpszPath );
+ lpwhr->lpszPath = fixurl;
+ }
- /* Calculate length of custom request headers */
- for (i = 0; i < lpwhr->nCustHeaders; i++)
- {
+ /* Calculate length of request string */
+ requestStringLen =
+ strlen(lpwhr->lpszVerb) +
+ strlen(lpwhr->lpszPath) +
+ strlen(HTTPHEADER) +
+ 5; /* " \r\n\r\n" */
+
+ /* Add length of passed headers */
+ if (lpszHeaders)
+ {
+ headerLength = -1 == dwHeaderLength ? strlen(lpszHeaders) : dwHeaderLength;
+ requestStringLen += headerLength + 2; /* \r\n */
+ }
+
+ /* Calculate length of custom request headers */
+ for (i = 0; i < lpwhr->nCustHeaders; i++)
+ {
if (lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST)
{
- requestStringLen += strlen(lpwhr->pCustHeaders[i].lpszField) +
- strlen(lpwhr->pCustHeaders[i].lpszValue) + 4; /*: \r\n */
+ requestStringLen += strlen(lpwhr->pCustHeaders[i].lpszField) +
+ strlen(lpwhr->pCustHeaders[i].lpszValue) + 4; /*: \r\n */
}
- }
+ }
- /* Calculate the length of standard request headers */
- for (i = 0; i <= HTTP_QUERY_MAX; i++)
- {
- if (lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST)
- {
- requestStringLen += strlen(lpwhr->StdHeaders[i].lpszField) +
- strlen(lpwhr->StdHeaders[i].lpszValue) + 4; /*: \r\n */
- }
- }
+ /* Calculate the length of standard request headers */
+ for (i = 0; i <= HTTP_QUERY_MAX; i++)
+ {
+ if (lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST)
+ {
+ requestStringLen += strlen(lpwhr->StdHeaders[i].lpszField) +
+ strlen(lpwhr->StdHeaders[i].lpszValue) + 4; /*: \r\n */
+ }
+ }
- /* Allocate string to hold entire request */
- requestString = HeapAlloc(GetProcessHeap(), 0, requestStringLen + 1);
- if (NULL == requestString)
- {
- INTERNET_SetLastError(ERROR_OUTOFMEMORY);
- goto lend;
- }
+ if (lpwhr->lpszHostName)
+ requestStringLen += (strlen(HTTPHOSTHEADER) + strlen(lpwhr->lpszHostName));
- /* Build request string */
- cnt = sprintf(requestString, "%s %s%s%s",
- lpwhr->lpszVerb,
- lpwhr->lpszPath,
- lpwhr->lpszHostName ? (HTTPHEADER HTTPHOSTHEADER) : HTTPHEADER,
- lpwhr->lpszHostName ? lpwhr->lpszHostName : "");
- /* Append standard request headers */
- for (i = 0; i <= HTTP_QUERY_MAX; i++)
- {
- if (lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST)
- {
- 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);
- }
- }
+ /* Allocate string to hold entire request */
+ requestString = HeapAlloc(GetProcessHeap(), 0, requestStringLen + 1);
+ if (NULL == requestString)
+ {
+ INTERNET_SetLastError(ERROR_OUTOFMEMORY);
+ goto lend;
+ }
- /* Append custom request heades */
- for (i = 0; i < lpwhr->nCustHeaders; i++)
- {
- if (lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST)
- {
- 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);
- }
- }
+ /* Build request string */
+ cnt = sprintf(requestString, "%s %s%s",
+ lpwhr->lpszVerb,
+ lpwhr->lpszPath,
+ HTTPHEADER);
- /* Append passed request headers */
- if (lpszHeaders)
- {
- strcpy(requestString + cnt, "\r\n");
- cnt += 2;
- strcpy(requestString + cnt, lpszHeaders);
- cnt += headerLength;
- }
+ /* Append standard request headers */
+ for (i = 0; i <= HTTP_QUERY_MAX; i++)
+ {
+ if (lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST)
+ {
+ 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);
+ }
+ }
- /* Set termination string for request */
- strcpy(requestString + cnt, "\r\n\r\n");
+ /* Append custom request heades */
+ for (i = 0; i < lpwhr->nCustHeaders; i++)
+ {
+ if (lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST)
+ {
+ 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);
+ }
+ }
- TRACE("(%s) len(%d)\n", requestString, requestStringLen);
- /* Send the request and store the results */
- if (!HTTP_OpenConnection(lpwhr))
- goto lend;
+ if (lpwhr->lpszHostName)
+ cnt += sprintf(requestString + cnt, "%s%s", HTTPHOSTHEADER, lpwhr->lpszHostName);
- SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
- INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
+ /* Append passed request headers */
+ if (lpszHeaders)
+ {
+ strcpy(requestString + cnt, "\r\n");
+ cnt += 2;
+ strcpy(requestString + cnt, lpszHeaders);
+ cnt += headerLength;
+ }
- cnt = send(lpwhr->nSocketFD, requestString, requestStringLen, 0);
+ /* Set termination string for request */
+ strcpy(requestString + cnt, "\r\n\r\n");
- SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
- INTERNET_STATUS_REQUEST_SENT,
- &requestStringLen,sizeof(DWORD));
+ TRACE("(%s) len(%d)\n", requestString, requestStringLen);
+ /* Send the request and store the results */
+ if (!HTTP_OpenConnection(lpwhr))
+ goto lend;
- SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
- INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
+ SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_SENDING_REQUEST, NULL, 0);
- if (cnt < 0)
- goto lend;
+ NETCON_send(&lpwhr->netConnection, requestString, requestStringLen,
+ 0, &cnt);
- responseLen = HTTP_GetResponseHeaders(lpwhr);
- if (responseLen)
+
+ SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_REQUEST_SENT,
+ &requestStringLen,sizeof(DWORD));
+
+ SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0);
+
+ if (cnt < 0)
+ goto lend;
+
+ responseLen = HTTP_GetResponseHeaders(lpwhr);
+ if (responseLen)
bSuccess = TRUE;
- SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
- INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen,
- sizeof(DWORD));
+ SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen,
+ sizeof(DWORD));
+
+ /* process headers here. Is this right? */
+ CustHeaderIndex = HTTP_GetCustomHeaderIndex(lpwhr, "Set-Cookie");
+ if (CustHeaderIndex >= 0)
+ {
+ LPHTTPHEADERA setCookieHeader;
+ int nPosStart = 0, nPosEnd = 0;
+
+ setCookieHeader = &lpwhr->pCustHeaders[CustHeaderIndex];
+
+ while (setCookieHeader->lpszValue[nPosEnd] != '\0')
+ {
+ LPSTR buf_cookie, cookie_name, cookie_data;
+ LPSTR buf_url;
+ LPSTR domain = NULL;
+ int nEqualPos = 0;
+ while (setCookieHeader->lpszValue[nPosEnd] != ';' && setCookieHeader->lpszValue[nPosEnd] != ',' &&
+ setCookieHeader->lpszValue[nPosEnd] != '\0')
+ {
+ nPosEnd++;
+ }
+ if (setCookieHeader->lpszValue[nPosEnd] == ';')
+ {
+ /* fixme: not case sensitive, strcasestr is gnu only */
+ int nDomainPosEnd = 0;
+ int nDomainPosStart = 0, nDomainLength = 0;
+ LPSTR lpszDomain = strstr(&setCookieHeader->lpszValue[nPosEnd], "domain=");
+ if (lpszDomain)
+ { /* they have specified their own domain, lets use it */
+ while (lpszDomain[nDomainPosEnd] != ';' && lpszDomain[nDomainPosEnd] != ',' &&
+ lpszDomain[nDomainPosEnd] != '\0')
+ {
+ nDomainPosEnd++;
+ }
+ nDomainPosStart = strlen("domain=");
+ nDomainLength = (nDomainPosEnd - nDomainPosStart) + 1;
+ domain = HeapAlloc(GetProcessHeap(), 0, nDomainLength + 1);
+ strncpy(domain, &lpszDomain[nDomainPosStart], nDomainLength);
+ domain[nDomainLength] = '\0';
+ }
+ }
+ if (setCookieHeader->lpszValue[nPosEnd] == '\0') break;
+ buf_cookie = HeapAlloc(GetProcessHeap(), 0, (nPosEnd - nPosStart) + 1);
+ strncpy(buf_cookie, &setCookieHeader->lpszValue[nPosStart], (nPosEnd - nPosStart));
+ buf_cookie[(nPosEnd - nPosStart)] = '\0';
+ TRACE("%s\n", buf_cookie);
+ while (buf_cookie[nEqualPos] != '=' && buf_cookie[nEqualPos] != '\0')
+ {
+ nEqualPos++;
+ }
+ if (buf_cookie[nEqualPos] == '\0' || buf_cookie[nEqualPos + 1] == '\0')
+ {
+ HeapFree(GetProcessHeap(), 0, buf_cookie);
+ break;
+ }
+
+ cookie_name = HeapAlloc(GetProcessHeap(), 0, nEqualPos + 1);
+ strncpy(cookie_name, buf_cookie, nEqualPos);
+ cookie_name[nEqualPos] = '\0';
+ cookie_data = &buf_cookie[nEqualPos + 1];
+
+
+ buf_url = HeapAlloc(GetProcessHeap(), 0, strlen((domain ? domain : lpwhr->lpszHostName)) + strlen(lpwhr->lpszPath) + 9);
+ sprintf(buf_url, "http://%s/", (domain ? domain : lpwhr->lpszHostName)); /* FIXME PATH!!! */
+ InternetSetCookieA(buf_url, cookie_name, cookie_data);
+
+ HeapFree(GetProcessHeap(), 0, buf_url);
+ HeapFree(GetProcessHeap(), 0, buf_cookie);
+ HeapFree(GetProcessHeap(), 0, cookie_name);
+ if (domain) HeapFree(GetProcessHeap(), 0, domain);
+ nPosStart = nPosEnd;
+ }
+ }
+
+ /* FIXME: is this right? I'm not sure if this should be here or elsewhere (the loop, too)
+ * FIXME: don't do this if they specify INTERNET_FLAG_NO_AUTO_REDIRECT */
+ if (lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue)
+ {
+ URL_COMPONENTSA urlComponents;
+ char protocol[32], hostName[MAXHOSTNAME], userName[1024];
+ char password[1024], path[2048], extra[1024];
+
+ TRACE("Got a Location header: Going around to a new location: %s",
+ debugstr_a(lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue));
+
+ 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(lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue,
+ strlen(lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue),
+ 0, &urlComponents))
+ goto lend;
+
+ if (urlComponents.nScheme != INTERNET_SCHEME_HTTP)
+ {
+ FIXME("cannot redirect to non HTTP page\n");
+ goto lend;
+ }
+
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath);
+ HeapAlloc(GetProcessHeap(), 0, strlen(path) + 1);
+ strcpy(lpwhr->lpszPath, path);
+
+ if (urlComponents.dwHostNameLength)
+ {
+ HeapFree(GetProcessHeap(), 0, lpwhr->lpszHostName);
+ HeapAlloc(GetProcessHeap(), 0, strlen(hostName) + 1);
+ strcpy(lpwhr->lpszHostName, hostName);
+ }
+
+ SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext,
+ INTERNET_STATUS_REDIRECT, NULL, 0);
+
+ HeapFree(GetProcessHeap(), 0, lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue);
+ lpwhr->StdHeaders[HTTP_QUERY_LOCATION].lpszValue = NULL;
+ loop_next = TRUE;
+ }
+ }
+ while (loop_next);
lend:
@@ -1192,7 +1447,7 @@
* windows
*/
-TRACE("<--\n");
+ TRACE("%p -->\n", hInternet);
return (HINTERNET)lpwhs;
}
@@ -1210,7 +1465,6 @@
BOOL HTTP_OpenConnection(LPWININETHTTPREQA lpwhr)
{
BOOL bSuccess = FALSE;
- INT result;
LPWININETHTTPSESSIONA lpwhs;
LPWININETAPPINFOA hIC = NULL;
@@ -1231,17 +1485,15 @@
&(lpwhs->socketAddress),
sizeof(struct sockaddr_in));
- lpwhr->nSocketFD = socket(lpwhs->phostent->h_addrtype,SOCK_STREAM,0);
- if (lpwhr->nSocketFD == -1)
+ if (!NETCON_create(&lpwhr->netConnection, lpwhs->phostent->h_addrtype,
+ SOCK_STREAM, 0))
{
WARN("Socket creation failed\n");
goto lend;
}
- result = connect(lpwhr->nSocketFD, (struct sockaddr *)&lpwhs->socketAddress,
- sizeof(lpwhs->socketAddress));
-
- if (result == -1)
+ if (!NETCON_connect(&lpwhr->netConnection, (struct sockaddr *)&lpwhs->socketAddress,
+ sizeof(lpwhs->socketAddress)))
{
WARN("Unable to connect to host (%s)\n", strerror(errno));
goto lend;
@@ -1281,19 +1533,20 @@
TRACE("-->\n");
- if (lpwhr->nSocketFD == -1)
+ if (!NETCON_connected(&lpwhr->netConnection))
goto lend;
/*
* HACK peek at the buffer
*/
- rc = recv(lpwhr->nSocketFD,buffer,buflen,MSG_PEEK);
+ NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc);
/*
* We should first receive 'HTTP/1.x nnn' where nnn is the status code.
*/
buflen = MAX_REPLY_LEN;
- if (!INTERNET_GetNextLine(lpwhr->nSocketFD, buffer, &buflen))
+ memset(buffer, 0, MAX_REPLY_LEN);
+ if (!NETCON_getNextLine(&lpwhr->netConnection, buffer, &buflen))
goto lend;
if (strncmp(buffer, "HTTP", 4) != 0)
@@ -1306,8 +1559,9 @@
do
{
buflen = MAX_REPLY_LEN;
- if (INTERNET_GetNextLine(lpwhr->nSocketFD, buffer, &buflen))
+ if (NETCON_getNextLine(&lpwhr->netConnection, buffer, &buflen))
{
+ TRACE("got line %s, now interpretting\n", debugstr_a(buffer));
if (!HTTP_InterpretHttpHeader(buffer, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN))
break;
@@ -1637,11 +1891,10 @@
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext,
INTERNET_STATUS_CLOSING_CONNECTION, 0, 0);
- if (lpwhr->nSocketFD != -1)
- {
- close(lpwhr->nSocketFD);
- lpwhr->nSocketFD = -1;
- }
+ if (NETCON_connected(&lpwhr->netConnection))
+ {
+ NETCON_close(&lpwhr->netConnection);
+ }
SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext,
INTERNET_STATUS_CONNECTION_CLOSED, 0, 0);
@@ -1662,7 +1915,7 @@
TRACE("\n");
- if (lpwhr->nSocketFD != -1)
+ if (NETCON_connected(&lpwhr->netConnection))
HTTP_CloseConnection(lpwhr);
lpwhs = (LPWININETHTTPSESSIONA) lpwhr->hdr.lpwhparent;
@@ -1709,7 +1962,7 @@
void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONA lpwhs)
{
LPWININETAPPINFOA hIC = NULL;
- TRACE("\n");
+ TRACE("%p\n", lpwhs);
hIC = (LPWININETAPPINFOA) lpwhs->hdr.lpwhparent;