Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1 | /* |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2 | * Wininet - Http Implementation |
| 3 | * |
| 4 | * Copyright 1999 Corel Corporation |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 5 | * Copyright 2002 CodeWeavers Inc. |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 6 | * Copyright 2002 TransGaming Technologies Inc. |
Francois Gouget | ad5ff7c | 2004-02-09 22:07:42 +0000 | [diff] [blame] | 7 | * Copyright 2004 Mike McCormack for CodeWeavers |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 8 | * |
| 9 | * Ulrich Czekalla |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 10 | * Aric Stewart |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 11 | * David Hammerton |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 12 | * |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 13 | * This library is free software; you can redistribute it and/or |
| 14 | * modify it under the terms of the GNU Lesser General Public |
| 15 | * License as published by the Free Software Foundation; either |
| 16 | * version 2.1 of the License, or (at your option) any later version. |
| 17 | * |
| 18 | * This library is distributed in the hope that it will be useful, |
| 19 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 21 | * Lesser General Public License for more details. |
| 22 | * |
| 23 | * You should have received a copy of the GNU Lesser General Public |
| 24 | * License along with this library; if not, write to the Free Software |
| 25 | * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 26 | */ |
| 27 | |
Patrik Stridvall | 4710be2 | 2000-06-23 15:47:14 +0000 | [diff] [blame] | 28 | #include "config.h" |
| 29 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 30 | #include <sys/types.h> |
Patrik Stridvall | 4710be2 | 2000-06-23 15:47:14 +0000 | [diff] [blame] | 31 | #ifdef HAVE_SYS_SOCKET_H |
| 32 | # include <sys/socket.h> |
| 33 | #endif |
Alexandre Julliard | e37c6e1 | 2003-09-05 23:08:26 +0000 | [diff] [blame] | 34 | #include <stdarg.h> |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 35 | #include <stdio.h> |
| 36 | #include <stdlib.h> |
Patrik Stridvall | d016f81 | 2002-08-17 00:43:16 +0000 | [diff] [blame] | 37 | #ifdef HAVE_UNISTD_H |
| 38 | # include <unistd.h> |
| 39 | #endif |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 40 | #include <errno.h> |
Jon Griffiths | 4ab1558 | 2001-01-22 02:17:29 +0000 | [diff] [blame] | 41 | #include <string.h> |
Chris Morgan | b9807b4 | 2001-02-15 21:24:07 +0000 | [diff] [blame] | 42 | #include <time.h> |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 43 | |
Guy Albertelli | aafec98 | 2001-11-06 22:31:19 +0000 | [diff] [blame] | 44 | #include "windef.h" |
| 45 | #include "winbase.h" |
| 46 | #include "wininet.h" |
| 47 | #include "winreg.h" |
| 48 | #include "winerror.h" |
Jon Griffiths | 603f20f | 2001-12-11 00:30:17 +0000 | [diff] [blame] | 49 | #define NO_SHLWAPI_STREAM |
Guy Albertelli | aafec98 | 2001-11-06 22:31:19 +0000 | [diff] [blame] | 50 | #include "shlwapi.h" |
| 51 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 52 | #include "internet.h" |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 53 | #include "wine/debug.h" |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 54 | #include "wine/unicode.h" |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 55 | |
Alexandre Julliard | 0799c1a | 2002-03-09 23:29:33 +0000 | [diff] [blame] | 56 | WINE_DEFAULT_DEBUG_CHANNEL(wininet); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 57 | |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 58 | static const WCHAR g_szHttp[] = {' ','H','T','T','P','/','1','.','0',0 }; |
| 59 | static const WCHAR g_szHost[] = {'\r','\n','H','o','s','t',':',' ',0 }; |
| 60 | static const WCHAR g_szReferer[] = {'R','e','f','e','r','e','r',0}; |
| 61 | static const WCHAR g_szAccept[] = {'A','c','c','e','p','t',0}; |
| 62 | static const WCHAR g_szUserAgent[] = {'U','s','e','r','-','A','g','e','n','t',0}; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 63 | |
| 64 | |
| 65 | #define HTTPHEADER g_szHttp |
| 66 | #define HTTPHOSTHEADER g_szHost |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 67 | #define MAXHOSTNAME 100 |
| 68 | #define MAX_FIELD_VALUE_LEN 256 |
| 69 | #define MAX_FIELD_LEN 256 |
| 70 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 71 | #define HTTP_REFERER g_szReferer |
| 72 | #define HTTP_ACCEPT g_szAccept |
| 73 | #define HTTP_USERAGENT g_szUserAgent |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 74 | |
| 75 | #define HTTP_ADDHDR_FLAG_ADD 0x20000000 |
| 76 | #define HTTP_ADDHDR_FLAG_ADD_IF_NEW 0x10000000 |
| 77 | #define HTTP_ADDHDR_FLAG_COALESCE 0x40000000 |
| 78 | #define HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA 0x40000000 |
| 79 | #define HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON 0x01000000 |
| 80 | #define HTTP_ADDHDR_FLAG_REPLACE 0x80000000 |
| 81 | #define HTTP_ADDHDR_FLAG_REQ 0x02000000 |
| 82 | |
| 83 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 84 | BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr); |
| 85 | int HTTP_WriteDataToStream(LPWININETHTTPREQW lpwhr, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 86 | void *Buffer, int BytesToWrite); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 87 | int HTTP_ReadDataFromStream(LPWININETHTTPREQW lpwhr, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 88 | void *Buffer, int BytesToRead); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 89 | BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr); |
| 90 | BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier); |
| 91 | void HTTP_CloseConnection(LPWININETHTTPREQW lpwhr); |
| 92 | BOOL HTTP_InterpretHttpHeader(LPWSTR buffer, LPWSTR field, INT fieldlen, LPWSTR value, INT valuelen); |
| 93 | INT HTTP_GetStdHeaderIndex(LPCWSTR lpszField); |
| 94 | BOOL HTTP_InsertCustomHeader(LPWININETHTTPREQW lpwhr, LPHTTPHEADERW lpHdr); |
| 95 | INT HTTP_GetCustomHeaderIndex(LPWININETHTTPREQW lpwhr, LPCWSTR lpszField); |
| 96 | BOOL HTTP_DeleteCustomHeader(LPWININETHTTPREQW lpwhr, INT index); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 97 | |
| 98 | /*********************************************************************** |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 99 | * HttpAddRequestHeadersW (WININET.@) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 100 | * |
| 101 | * Adds one or more HTTP header to the request handler |
| 102 | * |
| 103 | * RETURNS |
| 104 | * TRUE on success |
| 105 | * FALSE on failure |
| 106 | * |
| 107 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 108 | BOOL WINAPI HttpAddRequestHeadersW(HINTERNET hHttpRequest, |
| 109 | LPCWSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 110 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 111 | LPWSTR lpszStart; |
| 112 | LPWSTR lpszEnd; |
| 113 | LPWSTR buffer; |
| 114 | WCHAR value[MAX_FIELD_VALUE_LEN], field[MAX_FIELD_LEN]; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 115 | BOOL bSuccess = FALSE; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 116 | LPWININETHTTPREQW lpwhr; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 117 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 118 | TRACE("%p, %s, %li, %li\n", hHttpRequest, debugstr_w(lpszHeader), dwHeaderLength, |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 119 | dwModifier); |
| 120 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 121 | lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest ); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 122 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 123 | if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) |
| 124 | { |
| 125 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
| 126 | return FALSE; |
| 127 | } |
| 128 | |
Uwe Bonnes | 1cd00da | 2003-02-25 03:57:59 +0000 | [diff] [blame] | 129 | if (!lpszHeader) |
| 130 | return TRUE; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 131 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 132 | TRACE("copying header: %s\n", debugstr_w(lpszHeader)); |
| 133 | buffer = WININET_strdupW(lpszHeader); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 134 | lpszStart = buffer; |
| 135 | |
| 136 | do |
| 137 | { |
| 138 | lpszEnd = lpszStart; |
| 139 | |
| 140 | while (*lpszEnd != '\0') |
| 141 | { |
| 142 | if (*lpszEnd == '\r' && *(lpszEnd + 1) == '\n') |
| 143 | break; |
| 144 | lpszEnd++; |
| 145 | } |
| 146 | |
| 147 | if (*lpszEnd == '\0') |
| 148 | break; |
| 149 | |
| 150 | *lpszEnd = '\0'; |
| 151 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 152 | TRACE("interpreting header %s\n", debugstr_w(lpszStart)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 153 | if (HTTP_InterpretHttpHeader(lpszStart, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN)) |
| 154 | bSuccess = HTTP_ProcessHeader(lpwhr, field, value, dwModifier | HTTP_ADDHDR_FLAG_REQ); |
| 155 | |
| 156 | lpszStart = lpszEnd + 2; /* Jump over \0\n */ |
| 157 | |
| 158 | } while (bSuccess); |
| 159 | |
| 160 | HeapFree(GetProcessHeap(), 0, buffer); |
| 161 | return bSuccess; |
| 162 | } |
| 163 | |
Chris Morgan | a8b3216 | 2002-09-27 22:05:23 +0000 | [diff] [blame] | 164 | /*********************************************************************** |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 165 | * HttpAddRequestHeadersA (WININET.@) |
| 166 | * |
| 167 | * Adds one or more HTTP header to the request handler |
| 168 | * |
| 169 | * RETURNS |
| 170 | * TRUE on success |
| 171 | * FALSE on failure |
| 172 | * |
| 173 | */ |
| 174 | BOOL WINAPI HttpAddRequestHeadersA(HINTERNET hHttpRequest, |
| 175 | LPCSTR lpszHeader, DWORD dwHeaderLength, DWORD dwModifier) |
| 176 | { |
| 177 | DWORD len; |
| 178 | LPWSTR hdr; |
| 179 | BOOL r; |
| 180 | |
| 181 | TRACE("%p, %s, %li, %li\n", hHttpRequest, debugstr_a(lpszHeader), dwHeaderLength, |
| 182 | dwModifier); |
| 183 | |
| 184 | len = MultiByteToWideChar( CP_ACP, 0, lpszHeader, dwHeaderLength, NULL, 0 ); |
| 185 | hdr = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); |
| 186 | MultiByteToWideChar( CP_ACP, 0, lpszHeader, dwHeaderLength, hdr, len ); |
| 187 | if( dwHeaderLength != -1 ) |
| 188 | dwHeaderLength = len; |
| 189 | |
| 190 | r = HttpAddRequestHeadersW( hHttpRequest, hdr, dwHeaderLength, dwModifier ); |
| 191 | |
| 192 | HeapFree( GetProcessHeap(), 0, hdr ); |
| 193 | |
| 194 | return r; |
| 195 | } |
| 196 | |
| 197 | /*********************************************************************** |
Chris Morgan | a8b3216 | 2002-09-27 22:05:23 +0000 | [diff] [blame] | 198 | * HttpEndRequestA (WININET.@) |
| 199 | * |
| 200 | * Ends an HTTP request that was started by HttpSendRequestEx |
| 201 | * |
| 202 | * RETURNS |
| 203 | * TRUE if successful |
| 204 | * FALSE on failure |
| 205 | * |
| 206 | */ |
| 207 | BOOL WINAPI HttpEndRequestA(HINTERNET hRequest, LPINTERNET_BUFFERSA lpBuffersOut, |
| 208 | DWORD dwFlags, DWORD dwContext) |
| 209 | { |
| 210 | FIXME("stub\n"); |
| 211 | return FALSE; |
| 212 | } |
| 213 | |
| 214 | /*********************************************************************** |
| 215 | * HttpEndRequestW (WININET.@) |
| 216 | * |
| 217 | * Ends an HTTP request that was started by HttpSendRequestEx |
| 218 | * |
| 219 | * RETURNS |
| 220 | * TRUE if successful |
| 221 | * FALSE on failure |
| 222 | * |
| 223 | */ |
| 224 | BOOL WINAPI HttpEndRequestW(HINTERNET hRequest, LPINTERNET_BUFFERSW lpBuffersOut, |
| 225 | DWORD dwFlags, DWORD dwContext) |
| 226 | { |
| 227 | FIXME("stub\n"); |
| 228 | return FALSE; |
| 229 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 230 | |
| 231 | /*********************************************************************** |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 232 | * HttpOpenRequestW (WININET.@) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 233 | * |
| 234 | * Open a HTTP request handle |
| 235 | * |
| 236 | * RETURNS |
| 237 | * HINTERNET a HTTP request handle on success |
| 238 | * NULL on failure |
| 239 | * |
| 240 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 241 | HINTERNET WINAPI HttpOpenRequestW(HINTERNET hHttpSession, |
| 242 | LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, |
| 243 | LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 244 | DWORD dwFlags, DWORD dwContext) |
| 245 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 246 | LPWININETHTTPSESSIONW lpwhs; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 247 | LPWININETAPPINFOW hIC = NULL; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 248 | HINTERNET handle = NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 249 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 250 | TRACE("(%p, %s, %s, %s, %s, %p, %08lx, %08lx)\n", hHttpSession, |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 251 | debugstr_w(lpszVerb), debugstr_w(lpszObjectName), |
| 252 | debugstr_w(lpszVersion), debugstr_w(lpszReferrer), lpszAcceptTypes, |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 253 | dwFlags, dwContext); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 254 | if(lpszAcceptTypes!=NULL) |
| 255 | { |
| 256 | int i; |
| 257 | for(i=0;lpszAcceptTypes[i]!=NULL;i++) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 258 | TRACE("\taccept type: %s\n",debugstr_w(lpszAcceptTypes[i])); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 259 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 260 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 261 | lpwhs = (LPWININETHTTPSESSIONW) WININET_GetObject( hHttpSession ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 262 | if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) |
| 263 | { |
| 264 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 265 | return NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 266 | } |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 267 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 268 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 269 | /* |
| 270 | * My tests seem to show that the windows version does not |
| 271 | * become asynchronous until after this point. And anyhow |
| 272 | * if this call was asynchronous then how would you get the |
| 273 | * necessary HINTERNET pointer returned by this function. |
| 274 | * |
| 275 | * I am leaving this here just in case I am wrong |
| 276 | * |
| 277 | * if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) |
| 278 | */ |
| 279 | if (0) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 280 | { |
| 281 | WORKREQUEST workRequest; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 282 | struct WORKREQ_HTTPOPENREQUESTW *req; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 283 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 284 | workRequest.asyncall = HTTPOPENREQUESTW; |
Mike McCormack | b8921a2 | 2003-09-25 20:25:22 +0000 | [diff] [blame] | 285 | workRequest.handle = hHttpSession; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 286 | req = &workRequest.u.HttpOpenRequestW; |
| 287 | req->lpszVerb = WININET_strdupW(lpszVerb); |
| 288 | req->lpszObjectName = WININET_strdupW(lpszObjectName); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 289 | if (lpszVersion) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 290 | req->lpszVersion = WININET_strdupW(lpszVersion); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 291 | else |
Mike McCormack | b8921a2 | 2003-09-25 20:25:22 +0000 | [diff] [blame] | 292 | req->lpszVersion = 0; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 293 | if (lpszReferrer) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 294 | req->lpszReferrer = WININET_strdupW(lpszReferrer); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 295 | else |
Mike McCormack | b8921a2 | 2003-09-25 20:25:22 +0000 | [diff] [blame] | 296 | req->lpszReferrer = 0; |
| 297 | req->lpszAcceptTypes = lpszAcceptTypes; |
| 298 | req->dwFlags = dwFlags; |
| 299 | req->dwContext = dwContext; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 300 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 301 | INTERNET_AsyncCall(&workRequest); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 302 | } |
| 303 | else |
| 304 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 305 | handle = HTTP_HttpOpenRequestW(hHttpSession, lpszVerb, lpszObjectName, |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 306 | lpszVersion, lpszReferrer, lpszAcceptTypes, |
| 307 | dwFlags, dwContext); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 308 | } |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 309 | TRACE("returning %p\n", handle); |
| 310 | return handle; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 311 | } |
| 312 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 313 | |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 314 | /*********************************************************************** |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 315 | * HttpOpenRequestA (WININET.@) |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 316 | * |
| 317 | * Open a HTTP request handle |
| 318 | * |
| 319 | * RETURNS |
| 320 | * HINTERNET a HTTP request handle on success |
| 321 | * NULL on failure |
| 322 | * |
| 323 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 324 | HINTERNET WINAPI HttpOpenRequestA(HINTERNET hHttpSession, |
| 325 | LPCSTR lpszVerb, LPCSTR lpszObjectName, LPCSTR lpszVersion, |
| 326 | LPCSTR lpszReferrer , LPCSTR *lpszAcceptTypes, |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 327 | DWORD dwFlags, DWORD dwContext) |
| 328 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 329 | LPWSTR szVerb = NULL, szObjectName = NULL; |
| 330 | LPWSTR szVersion = NULL, szReferrer = NULL, *szAcceptTypes = NULL; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 331 | INT len; |
| 332 | INT acceptTypesCount; |
| 333 | HINTERNET rc = FALSE; |
| 334 | TRACE("(%p, %s, %s, %s, %s, %p, %08lx, %08lx)\n", hHttpSession, |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 335 | debugstr_a(lpszVerb), debugstr_a(lpszObjectName), |
| 336 | debugstr_a(lpszVersion), debugstr_a(lpszReferrer), lpszAcceptTypes, |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 337 | dwFlags, dwContext); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 338 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 339 | if (lpszVerb) |
| 340 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 341 | len = MultiByteToWideChar(CP_ACP, 0, lpszVerb, -1, NULL, 0 ); |
| 342 | szVerb = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR) ); |
Mike McCormack | 43629c9 | 2003-08-15 03:47:30 +0000 | [diff] [blame] | 343 | if ( !szVerb ) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 344 | goto end; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 345 | MultiByteToWideChar(CP_ACP, 0, lpszVerb, -1, szVerb, len); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 346 | } |
| 347 | |
| 348 | if (lpszObjectName) |
| 349 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 350 | len = MultiByteToWideChar(CP_ACP, 0, lpszObjectName, -1, NULL, 0 ); |
| 351 | szObjectName = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR) ); |
Mike McCormack | 43629c9 | 2003-08-15 03:47:30 +0000 | [diff] [blame] | 352 | if ( !szObjectName ) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 353 | goto end; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 354 | MultiByteToWideChar(CP_ACP, 0, lpszObjectName, -1, szObjectName, len ); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 355 | } |
| 356 | |
| 357 | if (lpszVersion) |
| 358 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 359 | len = MultiByteToWideChar(CP_ACP, 0, lpszVersion, -1, NULL, 0 ); |
| 360 | szVersion = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); |
Mike McCormack | 43629c9 | 2003-08-15 03:47:30 +0000 | [diff] [blame] | 361 | if ( !szVersion ) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 362 | goto end; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 363 | MultiByteToWideChar(CP_ACP, 0, lpszVersion, -1, szVersion, len ); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 364 | } |
| 365 | |
| 366 | if (lpszReferrer) |
| 367 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 368 | len = MultiByteToWideChar(CP_ACP, 0, lpszReferrer, -1, NULL, 0 ); |
| 369 | szReferrer = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); |
Mike McCormack | 43629c9 | 2003-08-15 03:47:30 +0000 | [diff] [blame] | 370 | if ( !szReferrer ) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 371 | goto end; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 372 | MultiByteToWideChar(CP_ACP, 0, lpszReferrer, -1, szReferrer, len ); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 373 | } |
| 374 | |
| 375 | acceptTypesCount = 0; |
| 376 | if (lpszAcceptTypes) |
| 377 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 378 | /* find out how many there are */ |
| 379 | while (lpszAcceptTypes[acceptTypesCount]) |
| 380 | acceptTypesCount++; |
| 381 | szAcceptTypes = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR *) * (acceptTypesCount+1)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 382 | acceptTypesCount = 0; |
| 383 | while (lpszAcceptTypes[acceptTypesCount]) |
| 384 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 385 | len = MultiByteToWideChar(CP_ACP, 0, lpszAcceptTypes[acceptTypesCount], |
| 386 | -1, NULL, 0 ); |
| 387 | szAcceptTypes[acceptTypesCount] = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR)); |
Mike McCormack | 43629c9 | 2003-08-15 03:47:30 +0000 | [diff] [blame] | 388 | if (!szAcceptTypes[acceptTypesCount] ) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 389 | goto end; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 390 | MultiByteToWideChar(CP_ACP, 0, lpszAcceptTypes[acceptTypesCount], |
| 391 | -1, szAcceptTypes[acceptTypesCount], len ); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 392 | acceptTypesCount++; |
| 393 | } |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 394 | szAcceptTypes[acceptTypesCount] = NULL; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 395 | } |
| 396 | else szAcceptTypes = 0; |
| 397 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 398 | rc = HttpOpenRequestW(hHttpSession, szVerb, szObjectName, |
| 399 | szVersion, szReferrer, |
| 400 | (LPCWSTR*)szAcceptTypes, dwFlags, dwContext); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 401 | |
| 402 | end: |
| 403 | if (szAcceptTypes) |
| 404 | { |
| 405 | acceptTypesCount = 0; |
| 406 | while (szAcceptTypes[acceptTypesCount]) |
| 407 | { |
| 408 | HeapFree(GetProcessHeap(), 0, szAcceptTypes[acceptTypesCount]); |
| 409 | acceptTypesCount++; |
| 410 | } |
| 411 | HeapFree(GetProcessHeap(), 0, szAcceptTypes); |
| 412 | } |
| 413 | if (szReferrer) HeapFree(GetProcessHeap(), 0, szReferrer); |
| 414 | if (szVersion) HeapFree(GetProcessHeap(), 0, szVersion); |
| 415 | if (szObjectName) HeapFree(GetProcessHeap(), 0, szObjectName); |
| 416 | if (szVerb) HeapFree(GetProcessHeap(), 0, szVerb); |
| 417 | |
| 418 | return rc; |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 419 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 420 | |
| 421 | /*********************************************************************** |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 422 | * HTTP_Base64 |
| 423 | */ |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 424 | static UINT HTTP_Base64( LPCWSTR bin, LPWSTR base64 ) |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 425 | { |
| 426 | UINT n = 0, x; |
| 427 | static LPSTR HTTP_Base64Enc = |
| 428 | "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; |
| 429 | |
| 430 | while( bin[0] ) |
| 431 | { |
| 432 | /* first 6 bits, all from bin[0] */ |
| 433 | base64[n++] = HTTP_Base64Enc[(bin[0] & 0xfc) >> 2]; |
| 434 | x = (bin[0] & 3) << 4; |
| 435 | |
| 436 | /* next 6 bits, 2 from bin[0] and 4 from bin[1] */ |
| 437 | if( !bin[1] ) |
| 438 | { |
| 439 | base64[n++] = HTTP_Base64Enc[x]; |
| 440 | base64[n++] = '='; |
| 441 | base64[n++] = '='; |
| 442 | break; |
| 443 | } |
| 444 | base64[n++] = HTTP_Base64Enc[ x | ( (bin[1]&0xf0) >> 4 ) ]; |
| 445 | x = ( bin[1] & 0x0f ) << 2; |
| 446 | |
| 447 | /* next 6 bits 4 from bin[1] and 2 from bin[2] */ |
| 448 | if( !bin[2] ) |
| 449 | { |
| 450 | base64[n++] = HTTP_Base64Enc[x]; |
| 451 | base64[n++] = '='; |
| 452 | break; |
| 453 | } |
| 454 | base64[n++] = HTTP_Base64Enc[ x | ( (bin[2]&0xc0 ) >> 6 ) ]; |
| 455 | |
| 456 | /* last 6 bits, all from bin [2] */ |
| 457 | base64[n++] = HTTP_Base64Enc[ bin[2] & 0x3f ]; |
| 458 | bin += 3; |
| 459 | } |
| 460 | base64[n] = 0; |
| 461 | return n; |
| 462 | } |
| 463 | |
| 464 | /*********************************************************************** |
| 465 | * HTTP_EncodeBasicAuth |
| 466 | * |
| 467 | * Encode the basic authentication string for HTTP 1.1 |
| 468 | */ |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 469 | static LPWSTR HTTP_EncodeBasicAuth( LPCWSTR username, LPCWSTR password) |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 470 | { |
| 471 | UINT len; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 472 | LPWSTR in, out; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 473 | static const WCHAR szBasic[] = {'B','a','s','i','c',' ',0}; |
| 474 | static const WCHAR szColon[] = {':',0}; |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 475 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 476 | len = lstrlenW( username ) + 1 + lstrlenW ( password ) + 1; |
| 477 | in = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 478 | if( !in ) |
| 479 | return NULL; |
| 480 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 481 | len = lstrlenW(szBasic) + |
| 482 | (lstrlenW( username ) + 1 + lstrlenW ( password ))*2 + 1 + 1; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 483 | out = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 484 | if( out ) |
| 485 | { |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 486 | lstrcpyW( in, username ); |
| 487 | lstrcatW( in, szColon ); |
| 488 | lstrcatW( in, password ); |
| 489 | lstrcpyW( out, szBasic ); |
| 490 | HTTP_Base64( in, &out[strlenW(out)] ); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 491 | } |
| 492 | HeapFree( GetProcessHeap(), 0, in ); |
| 493 | |
| 494 | return out; |
| 495 | } |
| 496 | |
| 497 | /*********************************************************************** |
| 498 | * HTTP_InsertProxyAuthorization |
| 499 | * |
| 500 | * Insert the basic authorization field in the request header |
| 501 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 502 | BOOL HTTP_InsertProxyAuthorization( LPWININETHTTPREQW lpwhr, |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 503 | LPCWSTR username, LPCWSTR password ) |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 504 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 505 | HTTPHEADERW hdr; |
| 506 | INT index; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 507 | static const WCHAR szProxyAuthorization[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 508 | 'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0 }; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 509 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 510 | hdr.lpszValue = HTTP_EncodeBasicAuth( username, password ); |
Alexandre Julliard | 286fe0a | 2004-04-13 00:19:58 +0000 | [diff] [blame] | 511 | hdr.lpszField = (WCHAR *)szProxyAuthorization; |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 512 | hdr.wFlags = HDR_ISREQUEST; |
| 513 | hdr.wCount = 0; |
| 514 | if( !hdr.lpszValue ) |
| 515 | return FALSE; |
| 516 | |
| 517 | TRACE("Inserting %s = %s\n", |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 518 | debugstr_w( hdr.lpszField ), debugstr_w( hdr.lpszValue ) ); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 519 | |
| 520 | /* remove the old proxy authorization header */ |
| 521 | index = HTTP_GetCustomHeaderIndex( lpwhr, hdr.lpszField ); |
| 522 | if( index >=0 ) |
| 523 | HTTP_DeleteCustomHeader( lpwhr, index ); |
| 524 | |
| 525 | HTTP_InsertCustomHeader(lpwhr, &hdr); |
| 526 | HeapFree( GetProcessHeap(), 0, hdr.lpszValue ); |
| 527 | |
| 528 | return TRUE; |
| 529 | } |
| 530 | |
| 531 | /*********************************************************************** |
| 532 | * HTTP_DealWithProxy |
| 533 | */ |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 534 | static BOOL HTTP_DealWithProxy( LPWININETAPPINFOW hIC, |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 535 | LPWININETHTTPSESSIONW lpwhs, LPWININETHTTPREQW lpwhr) |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 536 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 537 | WCHAR buf[MAXHOSTNAME]; |
| 538 | WCHAR proxy[MAXHOSTNAME + 15]; /* 15 == "http://" + sizeof(port#) + ":/\0" */ |
| 539 | WCHAR* url, szNul[] = { 0 }; |
| 540 | URL_COMPONENTSW UrlComponents; |
Mike McCormack | 3462299 | 2004-04-12 23:13:53 +0000 | [diff] [blame] | 541 | const WCHAR szHttp[] = { 'h','t','t','p',':','/','/',0 }, szSlash[] = { '/',0 } ; |
| 542 | const WCHAR szFormat1[] = { 'h','t','t','p',':','/','/','%','s',':','%','d',0 }; |
| 543 | const WCHAR szFormat2[] = { 'h','t','t','p',':','/','/','%','s',':','%','d',0 }; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 544 | int len; |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 545 | |
| 546 | memset( &UrlComponents, 0, sizeof UrlComponents ); |
| 547 | UrlComponents.dwStructSize = sizeof UrlComponents; |
| 548 | UrlComponents.lpszHostName = buf; |
| 549 | UrlComponents.dwHostNameLength = MAXHOSTNAME; |
| 550 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 551 | if( CSTR_EQUAL != CompareStringW(LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, |
| 552 | buf,strlenW(szHttp),szHttp,strlenW(szHttp)) ) |
| 553 | sprintfW(proxy, szFormat1, hIC->lpszProxy); |
Uwe Bonnes | 599c452 | 2003-12-15 19:47:31 +0000 | [diff] [blame] | 554 | else |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 555 | strcpyW(proxy,buf); |
| 556 | if( !InternetCrackUrlW(proxy, 0, 0, &UrlComponents) ) |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 557 | return FALSE; |
| 558 | if( UrlComponents.dwHostNameLength == 0 ) |
| 559 | return FALSE; |
| 560 | |
| 561 | if( !lpwhr->lpszPath ) |
| 562 | lpwhr->lpszPath = szNul; |
| 563 | TRACE("server='%s' path='%s'\n", |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 564 | debugstr_w(lpwhs->lpszServerName), debugstr_w(lpwhr->lpszPath)); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 565 | /* for constant 15 see above */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 566 | len = strlenW(lpwhs->lpszServerName) + strlenW(lpwhr->lpszPath) + 15; |
| 567 | url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 568 | |
| 569 | if(UrlComponents.nPort == INTERNET_INVALID_PORT_NUMBER) |
| 570 | UrlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT; |
| 571 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 572 | sprintfW(url, szFormat2, lpwhs->lpszServerName, lpwhs->nServerPort); |
| 573 | |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 574 | if( lpwhr->lpszPath[0] != '/' ) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 575 | strcatW( url, szSlash ); |
| 576 | strcatW(url, lpwhr->lpszPath); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 577 | if(lpwhr->lpszPath != szNul) |
| 578 | HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath); |
| 579 | lpwhr->lpszPath = url; |
| 580 | /* FIXME: Do I have to free lpwhs->lpszServerName here ? */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 581 | lpwhs->lpszServerName = WININET_strdupW(UrlComponents.lpszHostName); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 582 | lpwhs->nServerPort = UrlComponents.nPort; |
| 583 | |
| 584 | return TRUE; |
| 585 | } |
| 586 | |
| 587 | /*********************************************************************** |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 588 | * HTTP_HttpOpenRequestW (internal) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 589 | * |
| 590 | * Open a HTTP request handle |
| 591 | * |
| 592 | * RETURNS |
| 593 | * HINTERNET a HTTP request handle on success |
| 594 | * NULL on failure |
| 595 | * |
| 596 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 597 | HINTERNET WINAPI HTTP_HttpOpenRequestW(HINTERNET hHttpSession, |
| 598 | LPCWSTR lpszVerb, LPCWSTR lpszObjectName, LPCWSTR lpszVersion, |
| 599 | LPCWSTR lpszReferrer , LPCWSTR *lpszAcceptTypes, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 600 | DWORD dwFlags, DWORD dwContext) |
| 601 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 602 | LPWININETHTTPSESSIONW lpwhs; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 603 | LPWININETAPPINFOW hIC = NULL; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 604 | LPWININETHTTPREQW lpwhr; |
| 605 | LPWSTR lpszCookies; |
| 606 | LPWSTR lpszUrl = NULL; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 607 | DWORD nCookieSize; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 608 | HINTERNET handle; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 609 | static const WCHAR szUrlForm[] = {'h','t','t','p',':','/','/','%','s',0}; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 610 | DWORD len; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 611 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 612 | TRACE("--> \n"); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 613 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 614 | lpwhs = (LPWININETHTTPSESSIONW) WININET_GetObject( hHttpSession ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 615 | if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) |
| 616 | { |
| 617 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 618 | return NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 619 | } |
| 620 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 621 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 622 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 623 | lpwhr = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPREQW)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 624 | if (NULL == lpwhr) |
| 625 | { |
| 626 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 627 | return NULL; |
| 628 | } |
| 629 | handle = WININET_AllocHandle( &lpwhr->hdr ); |
| 630 | if (NULL == handle) |
| 631 | { |
| 632 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
| 633 | HeapFree( GetProcessHeap(), 0, lpwhr ); |
| 634 | return NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 635 | } |
| 636 | |
| 637 | lpwhr->hdr.htype = WH_HHTTPREQ; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 638 | lpwhr->hdr.lpwhparent = &lpwhs->hdr; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 639 | lpwhr->hdr.dwFlags = dwFlags; |
| 640 | lpwhr->hdr.dwContext = dwContext; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 641 | NETCON_init(&lpwhr->netConnection, dwFlags & INTERNET_FLAG_SECURE); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 642 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 643 | if (NULL != lpszObjectName && strlenW(lpszObjectName)) { |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 644 | HRESULT rc; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 645 | |
| 646 | len = 0; |
| 647 | rc = UrlEscapeW(lpszObjectName, NULL, &len, URL_ESCAPE_SPACES_ONLY); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 648 | if (rc != E_POINTER) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 649 | len = strlenW(lpszObjectName)+1; |
| 650 | lpwhr->lpszPath = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); |
| 651 | rc = UrlEscapeW(lpszObjectName, lpwhr->lpszPath, &len, |
Huw D M Davies | 0aebee9 | 2001-01-21 21:09:00 +0000 | [diff] [blame] | 652 | URL_ESCAPE_SPACES_ONLY); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 653 | if (rc) |
| 654 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 655 | ERR("Unable to escape string!(%s) (%ld)\n",debugstr_w(lpszObjectName),rc); |
| 656 | strcpyW(lpwhr->lpszPath,lpszObjectName); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 657 | } |
Huw D M Davies | 0aebee9 | 2001-01-21 21:09:00 +0000 | [diff] [blame] | 658 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 659 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 660 | if (NULL != lpszReferrer && strlenW(lpszReferrer)) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 661 | HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpszReferrer, HTTP_ADDHDR_FLAG_COALESCE); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 662 | |
| 663 | if(lpszAcceptTypes!=NULL) |
| 664 | { |
| 665 | int i; |
| 666 | for(i=0;lpszAcceptTypes[i]!=NULL;i++) |
| 667 | HTTP_ProcessHeader(lpwhr, HTTP_ACCEPT, lpszAcceptTypes[i], HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA|HTTP_ADDHDR_FLAG_REQ|HTTP_ADDHDR_FLAG_ADD_IF_NEW); |
| 668 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 669 | |
| 670 | if (NULL == lpszVerb) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 671 | { |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 672 | static const WCHAR szGet[] = {'G','E','T',0}; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 673 | lpwhr->lpszVerb = WININET_strdupW(szGet); |
| 674 | } |
| 675 | else if (strlenW(lpszVerb)) |
| 676 | lpwhr->lpszVerb = WININET_strdupW(lpszVerb); |
| 677 | |
| 678 | if (NULL != lpszReferrer && strlenW(lpszReferrer)) |
| 679 | { |
| 680 | WCHAR buf[MAXHOSTNAME]; |
| 681 | URL_COMPONENTSW UrlComponents; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 682 | |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 683 | memset( &UrlComponents, 0, sizeof UrlComponents ); |
| 684 | UrlComponents.dwStructSize = sizeof UrlComponents; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 685 | UrlComponents.lpszHostName = buf; |
| 686 | UrlComponents.dwHostNameLength = MAXHOSTNAME; |
| 687 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 688 | InternetCrackUrlW(lpszReferrer, 0, 0, &UrlComponents); |
| 689 | if (strlenW(UrlComponents.lpszHostName)) |
| 690 | lpwhr->lpszHostName = WININET_strdupW(UrlComponents.lpszHostName); |
Andreas Mohr | 3496556 | 2000-08-26 20:31:48 +0000 | [diff] [blame] | 691 | } else { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 692 | lpwhr->lpszHostName = WININET_strdupW(lpwhs->lpszServerName); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 693 | } |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 694 | if (NULL != hIC->lpszProxy && hIC->lpszProxy[0] != 0) |
| 695 | HTTP_DealWithProxy( hIC, lpwhs, lpwhr ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 696 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 697 | if (hIC->lpszAgent) |
| 698 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 699 | WCHAR *agent_header; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 700 | static const WCHAR user_agent[] = {'U','s','e','r','-','A','g','e','n','t',':',' ','%','s','\r','\n',0 }; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 701 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 702 | len = strlenW(hIC->lpszAgent) + strlenW(user_agent); |
| 703 | agent_header = HeapAlloc( GetProcessHeap(), 0, len*sizeof(WCHAR) ); |
| 704 | sprintfW(agent_header, user_agent, hIC->lpszAgent ); |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 705 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 706 | HttpAddRequestHeadersW(handle, agent_header, strlenW(agent_header), |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 707 | HTTP_ADDREQ_FLAG_ADD); |
| 708 | HeapFree(GetProcessHeap(), 0, agent_header); |
| 709 | } |
| 710 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 711 | len = strlenW(lpwhr->lpszHostName) + strlenW(szUrlForm); |
| 712 | lpszUrl = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); |
| 713 | sprintfW( lpszUrl, szUrlForm, lpwhr->lpszHostName ); |
| 714 | |
| 715 | if (InternetGetCookieW(lpszUrl, NULL, NULL, &nCookieSize)) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 716 | { |
| 717 | int cnt = 0; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 718 | static const WCHAR szCookie[] = {'C','o','o','k','i','e',':',' ',0}; |
| 719 | static const WCHAR szcrlf[] = {'\r','\n',0}; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 720 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 721 | lpszCookies = HeapAlloc(GetProcessHeap(), 0, (nCookieSize + 1 + 8)*sizeof(WCHAR)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 722 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 723 | cnt += sprintfW(lpszCookies, szCookie); |
| 724 | InternetGetCookieW(lpszUrl, NULL, lpszCookies + cnt, &nCookieSize); |
| 725 | strcatW(lpszCookies, szcrlf); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 726 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 727 | HttpAddRequestHeadersW(handle, lpszCookies, strlenW(lpszCookies), |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 728 | HTTP_ADDREQ_FLAG_ADD); |
| 729 | HeapFree(GetProcessHeap(), 0, lpszCookies); |
| 730 | } |
| 731 | HeapFree(GetProcessHeap(), 0, lpszUrl); |
| 732 | |
| 733 | |
| 734 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 735 | if (hIC->lpfnStatusCB) |
| 736 | { |
| 737 | INTERNET_ASYNC_RESULT iar; |
| 738 | |
Lionel Ulmer | a29b4c7 | 2004-02-09 20:55:58 +0000 | [diff] [blame] | 739 | iar.dwResult = (DWORD)handle; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 740 | iar.dwError = ERROR_SUCCESS; |
| 741 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 742 | SendAsyncCallback(hIC, hHttpSession, dwContext, |
| 743 | INTERNET_STATUS_HANDLE_CREATED, &iar, |
| 744 | sizeof(INTERNET_ASYNC_RESULT)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 745 | } |
| 746 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 747 | /* |
| 748 | * A STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on windows |
| 749 | */ |
| 750 | |
| 751 | /* |
| 752 | * According to my tests. The name is not resolved until a request is Opened |
| 753 | */ |
| 754 | SendAsyncCallback(hIC, hHttpSession, dwContext, |
| 755 | INTERNET_STATUS_RESOLVING_NAME, |
| 756 | lpwhs->lpszServerName, |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 757 | strlenW(lpwhs->lpszServerName)+1); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 758 | if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort, |
| 759 | &lpwhs->phostent, &lpwhs->socketAddress)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 760 | { |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 761 | INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 762 | return NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 763 | } |
| 764 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 765 | SendAsyncCallback(hIC, hHttpSession, lpwhr->hdr.dwContext, |
| 766 | INTERNET_STATUS_NAME_RESOLVED, |
| 767 | &(lpwhs->socketAddress), |
| 768 | sizeof(struct sockaddr_in)); |
| 769 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 770 | TRACE("<-- %p\n", handle); |
| 771 | return handle; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 772 | } |
| 773 | |
| 774 | |
| 775 | /*********************************************************************** |
Mike McCormack | 1baf39f | 2004-03-30 20:37:49 +0000 | [diff] [blame] | 776 | * HttpQueryInfoW (WININET.@) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 777 | * |
| 778 | * Queries for information about an HTTP request |
| 779 | * |
| 780 | * RETURNS |
| 781 | * TRUE on success |
| 782 | * FALSE on failure |
| 783 | * |
| 784 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 785 | BOOL WINAPI HttpQueryInfoW(HINTERNET hHttpRequest, DWORD dwInfoLevel, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 786 | LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex) |
| 787 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 788 | LPHTTPHEADERW lphttpHdr = NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 789 | BOOL bSuccess = FALSE; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 790 | LPWININETHTTPREQW lpwhr; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 791 | static const WCHAR szFmt[] = { '%','s',':',' ','%','s','%','s',0 }; |
| 792 | static const WCHAR szcrlf[] = { '\r','\n',0 }; |
| 793 | static const WCHAR sznul[] = { 0 }; |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 794 | |
Lionel Ulmer | 1d5e6b6 | 2004-02-09 22:01:49 +0000 | [diff] [blame] | 795 | if (TRACE_ON(wininet)) { |
| 796 | #define FE(x) { x, #x } |
| 797 | static const wininet_flag_info query_flags[] = { |
| 798 | FE(HTTP_QUERY_MIME_VERSION), |
| 799 | FE(HTTP_QUERY_CONTENT_TYPE), |
| 800 | FE(HTTP_QUERY_CONTENT_TRANSFER_ENCODING), |
| 801 | FE(HTTP_QUERY_CONTENT_ID), |
| 802 | FE(HTTP_QUERY_CONTENT_DESCRIPTION), |
| 803 | FE(HTTP_QUERY_CONTENT_LENGTH), |
| 804 | FE(HTTP_QUERY_CONTENT_LANGUAGE), |
| 805 | FE(HTTP_QUERY_ALLOW), |
| 806 | FE(HTTP_QUERY_PUBLIC), |
| 807 | FE(HTTP_QUERY_DATE), |
| 808 | FE(HTTP_QUERY_EXPIRES), |
| 809 | FE(HTTP_QUERY_LAST_MODIFIED), |
| 810 | FE(HTTP_QUERY_MESSAGE_ID), |
| 811 | FE(HTTP_QUERY_URI), |
| 812 | FE(HTTP_QUERY_DERIVED_FROM), |
| 813 | FE(HTTP_QUERY_COST), |
| 814 | FE(HTTP_QUERY_LINK), |
| 815 | FE(HTTP_QUERY_PRAGMA), |
| 816 | FE(HTTP_QUERY_VERSION), |
| 817 | FE(HTTP_QUERY_STATUS_CODE), |
| 818 | FE(HTTP_QUERY_STATUS_TEXT), |
| 819 | FE(HTTP_QUERY_RAW_HEADERS), |
| 820 | FE(HTTP_QUERY_RAW_HEADERS_CRLF), |
| 821 | FE(HTTP_QUERY_CONNECTION), |
| 822 | FE(HTTP_QUERY_ACCEPT), |
| 823 | FE(HTTP_QUERY_ACCEPT_CHARSET), |
| 824 | FE(HTTP_QUERY_ACCEPT_ENCODING), |
| 825 | FE(HTTP_QUERY_ACCEPT_LANGUAGE), |
| 826 | FE(HTTP_QUERY_AUTHORIZATION), |
| 827 | FE(HTTP_QUERY_CONTENT_ENCODING), |
| 828 | FE(HTTP_QUERY_FORWARDED), |
| 829 | FE(HTTP_QUERY_FROM), |
| 830 | FE(HTTP_QUERY_IF_MODIFIED_SINCE), |
| 831 | FE(HTTP_QUERY_LOCATION), |
| 832 | FE(HTTP_QUERY_ORIG_URI), |
| 833 | FE(HTTP_QUERY_REFERER), |
| 834 | FE(HTTP_QUERY_RETRY_AFTER), |
| 835 | FE(HTTP_QUERY_SERVER), |
| 836 | FE(HTTP_QUERY_TITLE), |
| 837 | FE(HTTP_QUERY_USER_AGENT), |
| 838 | FE(HTTP_QUERY_WWW_AUTHENTICATE), |
| 839 | FE(HTTP_QUERY_PROXY_AUTHENTICATE), |
| 840 | FE(HTTP_QUERY_ACCEPT_RANGES), |
| 841 | FE(HTTP_QUERY_SET_COOKIE), |
| 842 | FE(HTTP_QUERY_COOKIE), |
| 843 | FE(HTTP_QUERY_REQUEST_METHOD), |
| 844 | FE(HTTP_QUERY_REFRESH), |
| 845 | FE(HTTP_QUERY_CONTENT_DISPOSITION), |
| 846 | FE(HTTP_QUERY_AGE), |
| 847 | FE(HTTP_QUERY_CACHE_CONTROL), |
| 848 | FE(HTTP_QUERY_CONTENT_BASE), |
| 849 | FE(HTTP_QUERY_CONTENT_LOCATION), |
| 850 | FE(HTTP_QUERY_CONTENT_MD5), |
| 851 | FE(HTTP_QUERY_CONTENT_RANGE), |
| 852 | FE(HTTP_QUERY_ETAG), |
| 853 | FE(HTTP_QUERY_HOST), |
| 854 | FE(HTTP_QUERY_IF_MATCH), |
| 855 | FE(HTTP_QUERY_IF_NONE_MATCH), |
| 856 | FE(HTTP_QUERY_IF_RANGE), |
| 857 | FE(HTTP_QUERY_IF_UNMODIFIED_SINCE), |
| 858 | FE(HTTP_QUERY_MAX_FORWARDS), |
| 859 | FE(HTTP_QUERY_PROXY_AUTHORIZATION), |
| 860 | FE(HTTP_QUERY_RANGE), |
| 861 | FE(HTTP_QUERY_TRANSFER_ENCODING), |
| 862 | FE(HTTP_QUERY_UPGRADE), |
| 863 | FE(HTTP_QUERY_VARY), |
| 864 | FE(HTTP_QUERY_VIA), |
| 865 | FE(HTTP_QUERY_WARNING), |
| 866 | FE(HTTP_QUERY_CUSTOM) |
| 867 | }; |
| 868 | static const wininet_flag_info modifier_flags[] = { |
| 869 | FE(HTTP_QUERY_FLAG_REQUEST_HEADERS), |
| 870 | FE(HTTP_QUERY_FLAG_SYSTEMTIME), |
| 871 | FE(HTTP_QUERY_FLAG_NUMBER), |
| 872 | FE(HTTP_QUERY_FLAG_COALESCE) |
| 873 | }; |
| 874 | #undef FE |
| 875 | DWORD info_mod = dwInfoLevel & HTTP_QUERY_MODIFIER_FLAGS_MASK; |
| 876 | DWORD info = dwInfoLevel & HTTP_QUERY_HEADER_MASK; |
| 877 | int i; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 878 | |
Lionel Ulmer | 1d5e6b6 | 2004-02-09 22:01:49 +0000 | [diff] [blame] | 879 | TRACE("(%p, 0x%08lx)--> %ld\n", hHttpRequest, dwInfoLevel, dwInfoLevel); |
| 880 | TRACE(" Attribute:"); |
| 881 | for (i = 0; i < (sizeof(query_flags) / sizeof(query_flags[0])); i++) { |
| 882 | if (query_flags[i].val == info) { |
| 883 | DPRINTF(" %s", query_flags[i].name); |
| 884 | break; |
| 885 | } |
| 886 | } |
| 887 | if (i == (sizeof(query_flags) / sizeof(query_flags[0]))) { |
| 888 | DPRINTF(" Unknown (%08lx)", info); |
| 889 | } |
| 890 | |
| 891 | DPRINTF(" Modifier:"); |
| 892 | for (i = 0; i < (sizeof(modifier_flags) / sizeof(modifier_flags[0])); i++) { |
| 893 | if (modifier_flags[i].val & info_mod) { |
| 894 | DPRINTF(" %s", modifier_flags[i].name); |
| 895 | info_mod &= ~ modifier_flags[i].val; |
| 896 | } |
| 897 | } |
| 898 | |
| 899 | if (info_mod) { |
| 900 | DPRINTF(" Unknown (%08lx)", info_mod); |
| 901 | } |
| 902 | DPRINTF("\n"); |
| 903 | } |
| 904 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 905 | lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 906 | if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) |
| 907 | { |
| 908 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
Lionel Ulmer | 1d5e6b6 | 2004-02-09 22:01:49 +0000 | [diff] [blame] | 909 | goto lend; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 910 | } |
| 911 | |
| 912 | /* Find requested header structure */ |
| 913 | if ((dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK) == HTTP_QUERY_CUSTOM) |
| 914 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 915 | INT index = HTTP_GetCustomHeaderIndex(lpwhr, (LPWSTR)lpBuffer); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 916 | |
| 917 | if (index < 0) |
| 918 | goto lend; |
| 919 | |
| 920 | lphttpHdr = &lpwhr->pCustHeaders[index]; |
| 921 | } |
| 922 | else |
| 923 | { |
| 924 | INT index = dwInfoLevel & ~HTTP_QUERY_MODIFIER_FLAGS_MASK; |
| 925 | |
| 926 | if (index == HTTP_QUERY_RAW_HEADERS_CRLF || index == HTTP_QUERY_RAW_HEADERS) |
| 927 | { |
| 928 | INT i, delim, size = 0, cnt = 0; |
| 929 | |
| 930 | delim = index == HTTP_QUERY_RAW_HEADERS_CRLF ? 2 : 1; |
| 931 | |
| 932 | /* Calculate length of custom reuqest headers */ |
| 933 | for (i = 0; i < lpwhr->nCustHeaders; i++) |
| 934 | { |
| 935 | if ((~lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST) && lpwhr->pCustHeaders[i].lpszField && |
| 936 | lpwhr->pCustHeaders[i].lpszValue) |
| 937 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 938 | size += strlenW(lpwhr->pCustHeaders[i].lpszField) + |
| 939 | strlenW(lpwhr->pCustHeaders[i].lpszValue) + delim + 2; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 940 | } |
| 941 | } |
| 942 | |
| 943 | /* Calculate the length of stadard request headers */ |
| 944 | for (i = 0; i <= HTTP_QUERY_MAX; i++) |
| 945 | { |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 946 | if ((~lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST) && lpwhr->StdHeaders[i].lpszField && |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 947 | lpwhr->StdHeaders[i].lpszValue) |
| 948 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 949 | size += strlenW(lpwhr->StdHeaders[i].lpszField) + |
| 950 | strlenW(lpwhr->StdHeaders[i].lpszValue) + delim + 2; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 951 | } |
| 952 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 953 | size += delim; |
| 954 | |
Alexandre Julliard | a2bf4d0 | 2004-03-31 20:09:54 +0000 | [diff] [blame] | 955 | if (size + 1 > *lpdwBufferLength/sizeof(WCHAR)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 956 | { |
Alexandre Julliard | a2bf4d0 | 2004-03-31 20:09:54 +0000 | [diff] [blame] | 957 | *lpdwBufferLength = (size + 1) * sizeof(WCHAR); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 958 | INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); |
| 959 | goto lend; |
| 960 | } |
| 961 | |
| 962 | /* Append standard request heades */ |
| 963 | for (i = 0; i <= HTTP_QUERY_MAX; i++) |
| 964 | { |
| 965 | if ((~lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST) && |
| 966 | lpwhr->StdHeaders[i].lpszField && |
| 967 | lpwhr->StdHeaders[i].lpszValue) |
| 968 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 969 | cnt += sprintfW((WCHAR*)lpBuffer + cnt, szFmt, |
| 970 | lpwhr->StdHeaders[i].lpszField, lpwhr->StdHeaders[i].lpszValue, |
| 971 | index == HTTP_QUERY_RAW_HEADERS_CRLF ? szcrlf : sznul ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 972 | } |
| 973 | } |
| 974 | |
| 975 | /* Append custom request heades */ |
| 976 | for (i = 0; i < lpwhr->nCustHeaders; i++) |
| 977 | { |
| 978 | if ((~lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST) && |
| 979 | lpwhr->pCustHeaders[i].lpszField && |
| 980 | lpwhr->pCustHeaders[i].lpszValue) |
| 981 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 982 | cnt += sprintfW((WCHAR*)lpBuffer + cnt, szFmt, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 983 | lpwhr->pCustHeaders[i].lpszField, lpwhr->pCustHeaders[i].lpszValue, |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 984 | index == HTTP_QUERY_RAW_HEADERS_CRLF ? szcrlf : sznul); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 985 | } |
| 986 | } |
| 987 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 988 | strcpyW((WCHAR*)lpBuffer + cnt, index == HTTP_QUERY_RAW_HEADERS_CRLF ? szcrlf : sznul); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 989 | |
Alexandre Julliard | a2bf4d0 | 2004-03-31 20:09:54 +0000 | [diff] [blame] | 990 | *lpdwBufferLength = (cnt + delim) * sizeof(WCHAR); |
| 991 | bSuccess = TRUE; |
| 992 | goto lend; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 993 | } |
| 994 | else if (index >= 0 && index <= HTTP_QUERY_MAX && lpwhr->StdHeaders[index].lpszValue) |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 995 | { |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 996 | lphttpHdr = &lpwhr->StdHeaders[index]; |
| 997 | } |
| 998 | else |
| 999 | goto lend; |
| 1000 | } |
| 1001 | |
| 1002 | /* Ensure header satisifies requested attributes */ |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1003 | if ((dwInfoLevel & HTTP_QUERY_FLAG_REQUEST_HEADERS) && |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1004 | (~lphttpHdr->wFlags & HDR_ISREQUEST)) |
| 1005 | goto lend; |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1006 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1007 | /* coalesce value to reuqested type */ |
| 1008 | if (dwInfoLevel & HTTP_QUERY_FLAG_NUMBER) |
| 1009 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1010 | *(int *)lpBuffer = atoiW(lphttpHdr->lpszValue); |
Lionel Ulmer | 1d5e6b6 | 2004-02-09 22:01:49 +0000 | [diff] [blame] | 1011 | bSuccess = TRUE; |
| 1012 | |
| 1013 | TRACE(" returning number : %d\n", *(int *)lpBuffer); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1014 | } |
| 1015 | else if (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME) |
| 1016 | { |
| 1017 | time_t tmpTime; |
| 1018 | struct tm tmpTM; |
| 1019 | SYSTEMTIME *STHook; |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1020 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1021 | tmpTime = ConvertTimeString(lphttpHdr->lpszValue); |
| 1022 | |
| 1023 | tmpTM = *gmtime(&tmpTime); |
| 1024 | STHook = (SYSTEMTIME *) lpBuffer; |
| 1025 | if(STHook==NULL) |
| 1026 | goto lend; |
| 1027 | |
Lionel Ulmer | 1d5e6b6 | 2004-02-09 22:01:49 +0000 | [diff] [blame] | 1028 | STHook->wDay = tmpTM.tm_mday; |
| 1029 | STHook->wHour = tmpTM.tm_hour; |
| 1030 | STHook->wMilliseconds = 0; |
| 1031 | STHook->wMinute = tmpTM.tm_min; |
| 1032 | STHook->wDayOfWeek = tmpTM.tm_wday; |
| 1033 | STHook->wMonth = tmpTM.tm_mon + 1; |
| 1034 | STHook->wSecond = tmpTM.tm_sec; |
| 1035 | STHook->wYear = tmpTM.tm_year; |
| 1036 | |
| 1037 | bSuccess = TRUE; |
| 1038 | |
| 1039 | TRACE(" returning time : %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n", |
| 1040 | STHook->wYear, STHook->wMonth, STHook->wDay, STHook->wDayOfWeek, |
| 1041 | STHook->wHour, STHook->wMinute, STHook->wSecond, STHook->wMilliseconds); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1042 | } |
| 1043 | else if (dwInfoLevel & HTTP_QUERY_FLAG_COALESCE) |
| 1044 | { |
| 1045 | if (*lpdwIndex >= lphttpHdr->wCount) |
| 1046 | { |
| 1047 | INTERNET_SetLastError(ERROR_HTTP_HEADER_NOT_FOUND); |
| 1048 | } |
| 1049 | else |
| 1050 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1051 | /* Copy strncpyW(lpBuffer, lphttpHdr[*lpdwIndex], len); */ |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1052 | (*lpdwIndex)++; |
| 1053 | } |
| 1054 | } |
| 1055 | else |
| 1056 | { |
Alexandre Julliard | a2bf4d0 | 2004-03-31 20:09:54 +0000 | [diff] [blame] | 1057 | INT len = (strlenW(lphttpHdr->lpszValue) + 1) * sizeof(WCHAR); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1058 | |
Alexandre Julliard | a2bf4d0 | 2004-03-31 20:09:54 +0000 | [diff] [blame] | 1059 | if (len > *lpdwBufferLength) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1060 | { |
Alexandre Julliard | a2bf4d0 | 2004-03-31 20:09:54 +0000 | [diff] [blame] | 1061 | *lpdwBufferLength = len; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1062 | INTERNET_SetLastError(ERROR_INSUFFICIENT_BUFFER); |
| 1063 | goto lend; |
| 1064 | } |
| 1065 | |
Alexandre Julliard | a2bf4d0 | 2004-03-31 20:09:54 +0000 | [diff] [blame] | 1066 | memcpy(lpBuffer, lphttpHdr->lpszValue, len); |
| 1067 | *lpdwBufferLength = len - sizeof(WCHAR); |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1068 | bSuccess = TRUE; |
Lionel Ulmer | 1d5e6b6 | 2004-02-09 22:01:49 +0000 | [diff] [blame] | 1069 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1070 | TRACE(" returning string : '%s'\n", debugstr_w(lpBuffer)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1071 | } |
| 1072 | |
| 1073 | lend: |
| 1074 | TRACE("%d <--\n", bSuccess); |
| 1075 | return bSuccess; |
| 1076 | } |
| 1077 | |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1078 | /*********************************************************************** |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1079 | * HttpQueryInfoA (WININET.@) |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1080 | * |
| 1081 | * Queries for information about an HTTP request |
| 1082 | * |
| 1083 | * RETURNS |
| 1084 | * TRUE on success |
| 1085 | * FALSE on failure |
| 1086 | * |
| 1087 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1088 | BOOL WINAPI HttpQueryInfoA(HINTERNET hHttpRequest, DWORD dwInfoLevel, |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1089 | LPVOID lpBuffer, LPDWORD lpdwBufferLength, LPDWORD lpdwIndex) |
| 1090 | { |
| 1091 | BOOL result; |
Mike McCormack | 1baf39f | 2004-03-30 20:37:49 +0000 | [diff] [blame] | 1092 | DWORD len; |
| 1093 | WCHAR* bufferW; |
| 1094 | |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1095 | if((dwInfoLevel & HTTP_QUERY_FLAG_NUMBER) || |
| 1096 | (dwInfoLevel & HTTP_QUERY_FLAG_SYSTEMTIME)) |
| 1097 | { |
Mike McCormack | 1baf39f | 2004-03-30 20:37:49 +0000 | [diff] [blame] | 1098 | return HttpQueryInfoW( hHttpRequest, dwInfoLevel, lpBuffer, |
| 1099 | lpdwBufferLength, lpdwIndex ); |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1100 | } |
Mike McCormack | 1baf39f | 2004-03-30 20:37:49 +0000 | [diff] [blame] | 1101 | |
| 1102 | len = (*lpdwBufferLength)*sizeof(WCHAR); |
| 1103 | bufferW = HeapAlloc( GetProcessHeap(), 0, len ); |
| 1104 | result = HttpQueryInfoW( hHttpRequest, dwInfoLevel, bufferW, |
| 1105 | &len, lpdwIndex ); |
| 1106 | if( result ) |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1107 | { |
Mike McCormack | 1baf39f | 2004-03-30 20:37:49 +0000 | [diff] [blame] | 1108 | len = WideCharToMultiByte( CP_ACP,0, bufferW, len / sizeof(WCHAR), |
| 1109 | lpBuffer, *lpdwBufferLength, NULL, NULL ); |
| 1110 | *lpdwBufferLength = len * sizeof(WCHAR); |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1111 | } |
Mike McCormack | 1baf39f | 2004-03-30 20:37:49 +0000 | [diff] [blame] | 1112 | HeapFree(GetProcessHeap(), 0, bufferW ); |
| 1113 | |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1114 | return result; |
| 1115 | } |
Huw D M Davies | f9b6d7b | 2000-10-28 00:30:23 +0000 | [diff] [blame] | 1116 | |
| 1117 | /*********************************************************************** |
Patrik Stridvall | 3ca9823 | 2001-06-20 23:03:14 +0000 | [diff] [blame] | 1118 | * HttpSendRequestExA (WININET.@) |
Huw D M Davies | f9b6d7b | 2000-10-28 00:30:23 +0000 | [diff] [blame] | 1119 | * |
| 1120 | * Sends the specified request to the HTTP server and allows chunked |
| 1121 | * transfers |
| 1122 | */ |
| 1123 | BOOL WINAPI HttpSendRequestExA(HINTERNET hRequest, |
| 1124 | LPINTERNET_BUFFERSA lpBuffersIn, |
| 1125 | LPINTERNET_BUFFERSA lpBuffersOut, |
| 1126 | DWORD dwFlags, DWORD dwContext) |
| 1127 | { |
| 1128 | FIXME("(%p, %p, %p, %08lx, %08lx): stub\n", hRequest, lpBuffersIn, |
| 1129 | lpBuffersOut, dwFlags, dwContext); |
| 1130 | return FALSE; |
| 1131 | } |
| 1132 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1133 | /*********************************************************************** |
Patrik Stridvall | 8b216b3 | 2001-06-19 18:20:47 +0000 | [diff] [blame] | 1134 | * HttpSendRequestA (WININET.@) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1135 | * |
| 1136 | * Sends the specified request to the HTTP server |
| 1137 | * |
| 1138 | * RETURNS |
| 1139 | * TRUE on success |
| 1140 | * FALSE on failure |
| 1141 | * |
| 1142 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1143 | BOOL WINAPI HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1144 | DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength) |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1145 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1146 | LPWININETHTTPREQW lpwhr; |
| 1147 | LPWININETHTTPSESSIONW lpwhs = NULL; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1148 | LPWININETAPPINFOW hIC = NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1149 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1150 | TRACE("%p, %p (%s), %li, %p, %li)\n", hHttpRequest, |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1151 | lpszHeaders, debugstr_w(lpszHeaders), dwHeaderLength, lpOptional, dwOptionalLength); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1152 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1153 | lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1154 | if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) |
| 1155 | { |
| 1156 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
| 1157 | return FALSE; |
| 1158 | } |
| 1159 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1160 | lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1161 | if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) |
| 1162 | { |
| 1163 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
| 1164 | return FALSE; |
| 1165 | } |
| 1166 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1167 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1168 | if (NULL == hIC || hIC->hdr.htype != WH_HINIT) |
| 1169 | { |
| 1170 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
| 1171 | return FALSE; |
| 1172 | } |
| 1173 | |
| 1174 | if (hIC->hdr.dwFlags & INTERNET_FLAG_ASYNC) |
| 1175 | { |
| 1176 | WORKREQUEST workRequest; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1177 | struct WORKREQ_HTTPSENDREQUESTW *req; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1178 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1179 | workRequest.asyncall = HTTPSENDREQUESTW; |
Mike McCormack | b8921a2 | 2003-09-25 20:25:22 +0000 | [diff] [blame] | 1180 | workRequest.handle = hHttpRequest; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1181 | req = &workRequest.u.HttpSendRequestW; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1182 | if (lpszHeaders) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1183 | req->lpszHeader = WININET_strdupW(lpszHeaders); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1184 | else |
Mike McCormack | b8921a2 | 2003-09-25 20:25:22 +0000 | [diff] [blame] | 1185 | req->lpszHeader = 0; |
| 1186 | req->dwHeaderLength = dwHeaderLength; |
| 1187 | req->lpOptional = lpOptional; |
| 1188 | req->dwOptionalLength = dwOptionalLength; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1189 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1190 | INTERNET_AsyncCall(&workRequest); |
| 1191 | /* |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1192 | * This is from windows. |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1193 | */ |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1194 | SetLastError(ERROR_IO_PENDING); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1195 | return 0; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1196 | } |
| 1197 | else |
| 1198 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1199 | return HTTP_HttpSendRequestW(hHttpRequest, lpszHeaders, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1200 | dwHeaderLength, lpOptional, dwOptionalLength); |
| 1201 | } |
| 1202 | } |
| 1203 | |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1204 | /*********************************************************************** |
| 1205 | * HttpSendRequestW (WININET.@) |
| 1206 | * |
| 1207 | * Sends the specified request to the HTTP server |
| 1208 | * |
| 1209 | * RETURNS |
| 1210 | * TRUE on success |
| 1211 | * FALSE on failure |
| 1212 | * |
| 1213 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1214 | BOOL WINAPI HttpSendRequestA(HINTERNET hHttpRequest, LPCSTR lpszHeaders, |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1215 | DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength) |
| 1216 | { |
| 1217 | BOOL result; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1218 | LPWSTR szHeaders=NULL; |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1219 | DWORD nLen=dwHeaderLength; |
| 1220 | if(lpszHeaders!=NULL) |
| 1221 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1222 | nLen=MultiByteToWideChar(CP_ACP,0,lpszHeaders,dwHeaderLength,NULL,0); |
| 1223 | szHeaders=HeapAlloc(GetProcessHeap(),0,nLen*sizeof(WCHAR)); |
| 1224 | MultiByteToWideChar(CP_ACP,0,lpszHeaders,dwHeaderLength,szHeaders,nLen); |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1225 | } |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1226 | result=HttpSendRequestW(hHttpRequest, szHeaders, nLen, lpOptional, dwOptionalLength); |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1227 | if(szHeaders!=NULL) |
Mike McCormack | 43629c9 | 2003-08-15 03:47:30 +0000 | [diff] [blame] | 1228 | HeapFree(GetProcessHeap(),0,szHeaders); |
Alberto Massari | d476a5a | 2002-11-12 02:13:04 +0000 | [diff] [blame] | 1229 | return result; |
| 1230 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1231 | |
| 1232 | /*********************************************************************** |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1233 | * HTTP_HandleRedirect (internal) |
| 1234 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1235 | static BOOL HTTP_HandleRedirect(LPWININETHTTPREQW lpwhr, LPCWSTR lpszUrl, LPCWSTR lpszHeaders, |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1236 | DWORD dwHeaderLength, LPVOID lpOptional, DWORD dwOptionalLength) |
| 1237 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1238 | LPWININETHTTPSESSIONW lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1239 | LPWININETAPPINFOW hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1240 | WCHAR path[2048]; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1241 | HINTERNET handle; |
| 1242 | |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1243 | if(lpszUrl[0]=='/') |
| 1244 | { |
| 1245 | /* if it's an absolute path, keep the same session info */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1246 | strcpyW(path,lpszUrl); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1247 | } |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 1248 | else if (NULL != hIC->lpszProxy && hIC->lpszProxy[0] != 0) |
| 1249 | { |
| 1250 | TRACE("Redirect through proxy\n"); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1251 | strcpyW(path,lpszUrl); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 1252 | } |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1253 | else |
| 1254 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1255 | URL_COMPONENTSW urlComponents; |
| 1256 | WCHAR protocol[32], hostName[MAXHOSTNAME], userName[1024]; |
| 1257 | WCHAR password[1024], extra[1024]; |
| 1258 | urlComponents.dwStructSize = sizeof(URL_COMPONENTSW); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1259 | urlComponents.lpszScheme = protocol; |
| 1260 | urlComponents.dwSchemeLength = 32; |
| 1261 | urlComponents.lpszHostName = hostName; |
| 1262 | urlComponents.dwHostNameLength = MAXHOSTNAME; |
| 1263 | urlComponents.lpszUserName = userName; |
| 1264 | urlComponents.dwUserNameLength = 1024; |
| 1265 | urlComponents.lpszPassword = password; |
| 1266 | urlComponents.dwPasswordLength = 1024; |
| 1267 | urlComponents.lpszUrlPath = path; |
| 1268 | urlComponents.dwUrlPathLength = 2048; |
| 1269 | urlComponents.lpszExtraInfo = extra; |
| 1270 | urlComponents.dwExtraInfoLength = 1024; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1271 | if(!InternetCrackUrlW(lpszUrl, strlenW(lpszUrl), 0, &urlComponents)) |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1272 | return FALSE; |
| 1273 | |
| 1274 | if (urlComponents.nPort == INTERNET_INVALID_PORT_NUMBER) |
| 1275 | urlComponents.nPort = INTERNET_DEFAULT_HTTP_PORT; |
| 1276 | |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 1277 | #if 0 |
| 1278 | /* |
| 1279 | * This upsets redirects to binary files on sourceforge.net |
| 1280 | * and gives an html page instead of the target file |
| 1281 | * Examination of the HTTP request sent by native wininet.dll |
| 1282 | * reveals that it doesn't send a referrer in that case. |
| 1283 | * Maybe there's a flag that enables this, or maybe a referrer |
| 1284 | * shouldn't be added in case of a redirect. |
| 1285 | */ |
| 1286 | |
| 1287 | /* consider the current host as the referrer */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1288 | if (NULL != lpwhs->lpszServerName && strlenW(lpwhs->lpszServerName)) |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 1289 | HTTP_ProcessHeader(lpwhr, HTTP_REFERER, lpwhs->lpszServerName, |
| 1290 | HTTP_ADDHDR_FLAG_REQ|HTTP_ADDREQ_FLAG_REPLACE| |
| 1291 | HTTP_ADDHDR_FLAG_ADD_IF_NEW); |
| 1292 | #endif |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1293 | |
| 1294 | if (NULL != lpwhs->lpszServerName) |
| 1295 | HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1296 | lpwhs->lpszServerName = WININET_strdupW(hostName); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1297 | if (NULL != lpwhs->lpszUserName) |
| 1298 | HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1299 | lpwhs->lpszUserName = WININET_strdupW(userName); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1300 | lpwhs->nServerPort = urlComponents.nPort; |
| 1301 | |
| 1302 | if (NULL != lpwhr->lpszHostName) |
| 1303 | HeapFree(GetProcessHeap(), 0, lpwhr->lpszHostName); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1304 | lpwhr->lpszHostName=WININET_strdupW(hostName); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1305 | |
| 1306 | SendAsyncCallback(hIC, lpwhs, lpwhr->hdr.dwContext, |
| 1307 | INTERNET_STATUS_RESOLVING_NAME, |
| 1308 | lpwhs->lpszServerName, |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1309 | strlenW(lpwhs->lpszServerName)+1); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1310 | |
| 1311 | if (!GetAddress(lpwhs->lpszServerName, lpwhs->nServerPort, |
| 1312 | &lpwhs->phostent, &lpwhs->socketAddress)) |
| 1313 | { |
| 1314 | INTERNET_SetLastError(ERROR_INTERNET_NAME_NOT_RESOLVED); |
| 1315 | return FALSE; |
| 1316 | } |
| 1317 | |
| 1318 | SendAsyncCallback(hIC, lpwhs, lpwhr->hdr.dwContext, |
| 1319 | INTERNET_STATUS_NAME_RESOLVED, |
| 1320 | &(lpwhs->socketAddress), |
| 1321 | sizeof(struct sockaddr_in)); |
| 1322 | |
| 1323 | } |
| 1324 | |
| 1325 | if(lpwhr->lpszPath) |
| 1326 | HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath); |
| 1327 | lpwhr->lpszPath=NULL; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1328 | if (strlenW(path)) |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1329 | { |
| 1330 | DWORD needed = 0; |
| 1331 | HRESULT rc; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1332 | |
| 1333 | rc = UrlEscapeW(path, NULL, &needed, URL_ESCAPE_SPACES_ONLY); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1334 | if (rc != E_POINTER) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1335 | needed = strlenW(path)+1; |
| 1336 | lpwhr->lpszPath = HeapAlloc(GetProcessHeap(), 0, needed*sizeof(WCHAR)); |
| 1337 | rc = UrlEscapeW(path, lpwhr->lpszPath, &needed, |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1338 | URL_ESCAPE_SPACES_ONLY); |
| 1339 | if (rc) |
| 1340 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1341 | ERR("Unable to escape string!(%s) (%ld)\n",debugstr_w(path),rc); |
| 1342 | strcpyW(lpwhr->lpszPath,path); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1343 | } |
| 1344 | } |
| 1345 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1346 | handle = WININET_FindHandle( &lpwhr->hdr ); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1347 | return HttpSendRequestW(handle, lpszHeaders, dwHeaderLength, lpOptional, dwOptionalLength); |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1348 | } |
| 1349 | |
| 1350 | /*********************************************************************** |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1351 | * HTTP_HttpSendRequestW (internal) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1352 | * |
| 1353 | * Sends the specified request to the HTTP server |
| 1354 | * |
| 1355 | * RETURNS |
| 1356 | * TRUE on success |
| 1357 | * FALSE on failure |
| 1358 | * |
| 1359 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1360 | BOOL WINAPI HTTP_HttpSendRequestW(HINTERNET hHttpRequest, LPCWSTR lpszHeaders, |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1361 | DWORD dwHeaderLength, LPVOID lpOptional ,DWORD dwOptionalLength) |
| 1362 | { |
| 1363 | INT cnt; |
| 1364 | INT i; |
| 1365 | BOOL bSuccess = FALSE; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1366 | LPWSTR requestString = NULL; |
| 1367 | LPWSTR lpszHeaders_r_n = NULL; /* lpszHeaders with atleast one pair of \r\n at the end */ |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1368 | INT requestStringLen; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1369 | INT responseLen; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1370 | INT headerLength = 0; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1371 | LPWININETHTTPREQW lpwhr; |
| 1372 | LPWININETHTTPSESSIONW lpwhs = NULL; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1373 | LPWININETAPPINFOW hIC = NULL; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1374 | BOOL loop_next = FALSE; |
| 1375 | int CustHeaderIndex; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1376 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1377 | TRACE("--> 0x%08lx\n", (ULONG)hHttpRequest); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1378 | |
| 1379 | /* Verify our tree of internet handles */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1380 | lpwhr = (LPWININETHTTPREQW) WININET_GetObject( hHttpRequest ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1381 | if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) |
| 1382 | { |
| 1383 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
| 1384 | return FALSE; |
| 1385 | } |
| 1386 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1387 | lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1388 | if (NULL == lpwhs || lpwhs->hdr.htype != WH_HHTTPSESSION) |
| 1389 | { |
| 1390 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
| 1391 | return FALSE; |
| 1392 | } |
| 1393 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1394 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1395 | if (NULL == hIC || hIC->hdr.htype != WH_HINIT) |
| 1396 | { |
| 1397 | INTERNET_SetLastError(ERROR_INTERNET_INCORRECT_HANDLE_TYPE); |
| 1398 | return FALSE; |
| 1399 | } |
| 1400 | |
| 1401 | /* Clear any error information */ |
| 1402 | INTERNET_SetLastError(0); |
| 1403 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1404 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1405 | /* We must have a verb */ |
| 1406 | if (NULL == lpwhr->lpszVerb) |
| 1407 | { |
| 1408 | goto lend; |
| 1409 | } |
| 1410 | |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1411 | /* if we are using optional stuff, we must add the fixed header of that option length */ |
| 1412 | if (lpOptional && dwOptionalLength) |
| 1413 | { |
| 1414 | char contentLengthStr[sizeof("Content-Length: ") + 20 /* int */ + 2 /* \n\r */]; |
| 1415 | sprintf(contentLengthStr, "Content-Length: %li\r\n", dwOptionalLength); |
| 1416 | HttpAddRequestHeadersA(hHttpRequest, contentLengthStr, -1L, HTTP_ADDREQ_FLAG_ADD); |
| 1417 | } |
| 1418 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1419 | do |
Nikolas Zimmermann | 7659882 | 2001-10-04 18:12:41 +0000 | [diff] [blame] | 1420 | { |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 1421 | static const WCHAR szSlash[] = { '/',0 }; |
| 1422 | static const WCHAR szSpace[] = { ' ',0 }; |
| 1423 | static const WCHAR szHttp[] = { 'h','t','t','p',':','/','/', 0 }; |
| 1424 | static const WCHAR szcrlf[] = {'\r','\n', 0}; |
| 1425 | static const WCHAR sztwocrlf[] = {'\r','\n','\r','\n', 0}; |
| 1426 | static const WCHAR szSetCookie[] = {'S','e','t','-','C','o','o','k','i','e',0 }; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1427 | |
| 1428 | TRACE("Going to url %s %s\n", debugstr_w(lpwhr->lpszHostName), debugstr_w(lpwhr->lpszPath)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1429 | loop_next = FALSE; |
Nikolas Zimmermann | 7659882 | 2001-10-04 18:12:41 +0000 | [diff] [blame] | 1430 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1431 | /* If we don't have a path we set it to root */ |
| 1432 | if (NULL == lpwhr->lpszPath) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1433 | lpwhr->lpszPath = WININET_strdupW(szSlash); |
| 1434 | |
| 1435 | if(CSTR_EQUAL != CompareStringW( LOCALE_SYSTEM_DEFAULT, NORM_IGNORECASE, |
| 1436 | lpwhr->lpszPath, strlenW(szHttp), szHttp, strlenW(szHttp) ) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1437 | && lpwhr->lpszPath[0] != '/') /* not an absolute path ?? --> fix it !! */ |
| 1438 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1439 | WCHAR *fixurl = HeapAlloc(GetProcessHeap(), 0, |
| 1440 | (strlenW(lpwhr->lpszPath) + 2)*sizeof(WCHAR)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1441 | *fixurl = '/'; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1442 | strcpyW(fixurl + 1, lpwhr->lpszPath); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1443 | HeapFree( GetProcessHeap(), 0, lpwhr->lpszPath ); |
| 1444 | lpwhr->lpszPath = fixurl; |
| 1445 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1446 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1447 | /* Calculate length of request string */ |
| 1448 | requestStringLen = |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1449 | strlenW(lpwhr->lpszVerb) + |
| 1450 | strlenW(lpwhr->lpszPath) + |
| 1451 | strlenW(HTTPHEADER) + |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1452 | 5; /* " \r\n\r\n" */ |
| 1453 | |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1454 | /* add "\r\n" to end of lpszHeaders if needed */ |
| 1455 | if (lpszHeaders) |
| 1456 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1457 | int len = strlenW(lpszHeaders); |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1458 | |
| 1459 | /* Check if the string is terminated with \r\n, but not if |
| 1460 | * the string is less that 2 characters long, because then |
| 1461 | * we would be looking at memory before the beginning of |
| 1462 | * the string. Besides, if it is less than 2 characters |
| 1463 | * long, then clearly, its not terminated with \r\n. |
| 1464 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1465 | if ((len > 2) && (memcmp(lpszHeaders + (len - 2), szcrlf, sizeof szcrlf) == 0)) |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1466 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1467 | lpszHeaders_r_n = WININET_strdupW(lpszHeaders); |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1468 | } |
| 1469 | else |
| 1470 | { |
| 1471 | TRACE("Adding \r\n to lpszHeaders.\n"); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1472 | lpszHeaders_r_n = HeapAlloc( GetProcessHeap(), 0, |
| 1473 | (len + 3)*sizeof(WCHAR) ); |
| 1474 | strcpyW( lpszHeaders_r_n, lpszHeaders ); |
| 1475 | strcatW( lpszHeaders_r_n, szcrlf ); |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1476 | } |
| 1477 | } |
| 1478 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1479 | /* Add length of passed headers */ |
| 1480 | if (lpszHeaders) |
| 1481 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1482 | headerLength = -1 == dwHeaderLength ? strlenW(lpszHeaders_r_n) : dwHeaderLength; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1483 | requestStringLen += headerLength + 2; /* \r\n */ |
| 1484 | } |
| 1485 | |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 1486 | |
| 1487 | /* if there isa proxy username and password, add it to the headers */ |
| 1488 | if( hIC && (hIC->lpszProxyUsername || hIC->lpszProxyPassword ) ) |
| 1489 | { |
| 1490 | HTTP_InsertProxyAuthorization( lpwhr, hIC->lpszProxyUsername, hIC->lpszProxyPassword ); |
| 1491 | } |
| 1492 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1493 | /* Calculate length of custom request headers */ |
| 1494 | for (i = 0; i < lpwhr->nCustHeaders; i++) |
| 1495 | { |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1496 | if (lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST) |
| 1497 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1498 | requestStringLen += strlenW(lpwhr->pCustHeaders[i].lpszField) + |
| 1499 | strlenW(lpwhr->pCustHeaders[i].lpszValue) + 4; /*: \r\n */ |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1500 | } |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1501 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1502 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1503 | /* Calculate the length of standard request headers */ |
| 1504 | for (i = 0; i <= HTTP_QUERY_MAX; i++) |
| 1505 | { |
| 1506 | if (lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST) |
| 1507 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1508 | requestStringLen += strlenW(lpwhr->StdHeaders[i].lpszField) + |
| 1509 | strlenW(lpwhr->StdHeaders[i].lpszValue) + 4; /*: \r\n */ |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1510 | } |
| 1511 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1512 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1513 | if (lpwhr->lpszHostName) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1514 | requestStringLen += (strlenW(HTTPHOSTHEADER) + strlenW(lpwhr->lpszHostName)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1515 | |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1516 | /* if there is optional data to send, add the length */ |
| 1517 | if (lpOptional) |
| 1518 | { |
| 1519 | requestStringLen += dwOptionalLength; |
| 1520 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1521 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1522 | /* Allocate string to hold entire request */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1523 | requestString = HeapAlloc(GetProcessHeap(), 0, (requestStringLen + 1)*sizeof(WCHAR)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1524 | if (NULL == requestString) |
| 1525 | { |
| 1526 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
| 1527 | goto lend; |
| 1528 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1529 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1530 | /* Build request string */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1531 | strcpyW(requestString, lpwhr->lpszVerb); |
| 1532 | strcatW(requestString, szSpace); |
| 1533 | strcatW(requestString, lpwhr->lpszPath); |
| 1534 | strcatW(requestString, HTTPHEADER ); |
| 1535 | cnt = strlenW(requestString); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1536 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1537 | /* Append standard request headers */ |
| 1538 | for (i = 0; i <= HTTP_QUERY_MAX; i++) |
| 1539 | { |
| 1540 | if (lpwhr->StdHeaders[i].wFlags & HDR_ISREQUEST) |
| 1541 | { |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 1542 | static const WCHAR szFmt[] = { '\r','\n','%','s',':',' ','%','s', 0}; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1543 | cnt += sprintfW(requestString + cnt, szFmt, |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1544 | lpwhr->StdHeaders[i].lpszField, lpwhr->StdHeaders[i].lpszValue); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1545 | TRACE("Adding header %s (%s)\n", |
| 1546 | debugstr_w(lpwhr->StdHeaders[i].lpszField), |
| 1547 | debugstr_w(lpwhr->StdHeaders[i].lpszValue)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1548 | } |
| 1549 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1550 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1551 | /* Append custom request heades */ |
| 1552 | for (i = 0; i < lpwhr->nCustHeaders; i++) |
| 1553 | { |
| 1554 | if (lpwhr->pCustHeaders[i].wFlags & HDR_ISREQUEST) |
| 1555 | { |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 1556 | static const WCHAR szFmt[] = { '\r','\n','%','s',':',' ','%','s', 0}; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1557 | cnt += sprintfW(requestString + cnt, szFmt, |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1558 | lpwhr->pCustHeaders[i].lpszField, lpwhr->pCustHeaders[i].lpszValue); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1559 | TRACE("Adding custom header %s (%s)\n", |
| 1560 | debugstr_w(lpwhr->pCustHeaders[i].lpszField), |
| 1561 | debugstr_w(lpwhr->pCustHeaders[i].lpszValue)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1562 | } |
| 1563 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1564 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1565 | if (lpwhr->lpszHostName) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1566 | { |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 1567 | static const WCHAR szFmt[] = { '%','s','%','s',0 }; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1568 | cnt += sprintfW(requestString + cnt, szFmt, HTTPHOSTHEADER, lpwhr->lpszHostName); |
| 1569 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1570 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1571 | /* Append passed request headers */ |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1572 | if (lpszHeaders_r_n) |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1573 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1574 | strcpyW(requestString + cnt, szcrlf); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1575 | cnt += 2; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1576 | strcpyW(requestString + cnt, lpszHeaders_r_n); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1577 | cnt += headerLength; |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1578 | /* only add \r\n if not already present */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1579 | if (memcmp((requestString + cnt) - 2, szcrlf, sizeof szcrlf) != 0) |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1580 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1581 | strcpyW(requestString + cnt, szcrlf); |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1582 | cnt += 2; |
| 1583 | } |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1584 | } |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1585 | |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1586 | /* Set (header) termination string for request */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1587 | if (memcmp((requestString + cnt) - 4, sztwocrlf, sizeof sztwocrlf) != 0) |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1588 | { /* only add it if the request string doesn't already |
| 1589 | have the thing.. (could happen if the custom header |
| 1590 | added it */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1591 | strcpyW(requestString + cnt, szcrlf); |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1592 | cnt += 2; |
| 1593 | } |
| 1594 | else |
| 1595 | requestStringLen -= 2; |
| 1596 | |
| 1597 | /* if optional data, append it */ |
| 1598 | if (lpOptional) |
| 1599 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1600 | memcpy(requestString + cnt, lpOptional, dwOptionalLength*sizeof(WCHAR)); |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1601 | cnt += dwOptionalLength; |
| 1602 | /* we also have to decrease the expected string length by two, |
| 1603 | * since we won't be adding on those following \r\n's */ |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1604 | requestStringLen -= 2; |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1605 | } |
| 1606 | else |
| 1607 | { /* if there is no optional data, add on another \r\n just to be safe */ |
| 1608 | /* termination for request */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1609 | strcpyW(requestString + cnt, szcrlf); |
David Hammerton | 6226f3f | 2003-08-05 18:31:02 +0000 | [diff] [blame] | 1610 | cnt += 2; |
| 1611 | } |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1612 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1613 | TRACE("(%s) len(%d)\n", debugstr_w(requestString), requestStringLen); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1614 | /* Send the request and store the results */ |
| 1615 | if (!HTTP_OpenConnection(lpwhr)) |
| 1616 | goto lend; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1617 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1618 | SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, |
| 1619 | INTERNET_STATUS_SENDING_REQUEST, NULL, 0); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1620 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1621 | /* send the request as ASCII */ |
| 1622 | { |
| 1623 | int ascii_len; |
| 1624 | char *ascii_req; |
| 1625 | |
| 1626 | ascii_len = WideCharToMultiByte( CP_ACP, 0, requestString, |
| 1627 | requestStringLen, NULL, 0, NULL, NULL ); |
| 1628 | ascii_req = HeapAlloc( GetProcessHeap(), 0, ascii_len ); |
| 1629 | WideCharToMultiByte( CP_ACP, 0, requestString, requestStringLen, |
| 1630 | ascii_req, ascii_len, NULL, NULL ); |
| 1631 | NETCON_send(&lpwhr->netConnection, ascii_req, ascii_len, 0, &cnt); |
| 1632 | HeapFree( GetProcessHeap(), 0, ascii_req ); |
| 1633 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1634 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1635 | |
| 1636 | SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, |
| 1637 | INTERNET_STATUS_REQUEST_SENT, |
| 1638 | &requestStringLen,sizeof(DWORD)); |
| 1639 | |
| 1640 | SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, |
| 1641 | INTERNET_STATUS_RECEIVING_RESPONSE, NULL, 0); |
| 1642 | |
| 1643 | if (cnt < 0) |
| 1644 | goto lend; |
| 1645 | |
| 1646 | responseLen = HTTP_GetResponseHeaders(lpwhr); |
| 1647 | if (responseLen) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1648 | bSuccess = TRUE; |
| 1649 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1650 | SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, |
| 1651 | INTERNET_STATUS_RESPONSE_RECEIVED, &responseLen, |
| 1652 | sizeof(DWORD)); |
| 1653 | |
| 1654 | /* process headers here. Is this right? */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1655 | CustHeaderIndex = HTTP_GetCustomHeaderIndex(lpwhr, szSetCookie); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1656 | if (CustHeaderIndex >= 0) |
| 1657 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1658 | LPHTTPHEADERW setCookieHeader; |
| 1659 | int nPosStart = 0, nPosEnd = 0, len; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 1660 | static const WCHAR szFmt[] = { 'h','t','t','p',':','/','/','%','s','/',0}; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1661 | |
| 1662 | setCookieHeader = &lpwhr->pCustHeaders[CustHeaderIndex]; |
| 1663 | |
| 1664 | while (setCookieHeader->lpszValue[nPosEnd] != '\0') |
| 1665 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1666 | LPWSTR buf_cookie, cookie_name, cookie_data; |
| 1667 | LPWSTR buf_url; |
| 1668 | LPWSTR domain = NULL; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1669 | int nEqualPos = 0; |
| 1670 | while (setCookieHeader->lpszValue[nPosEnd] != ';' && setCookieHeader->lpszValue[nPosEnd] != ',' && |
| 1671 | setCookieHeader->lpszValue[nPosEnd] != '\0') |
| 1672 | { |
| 1673 | nPosEnd++; |
| 1674 | } |
| 1675 | if (setCookieHeader->lpszValue[nPosEnd] == ';') |
| 1676 | { |
| 1677 | /* fixme: not case sensitive, strcasestr is gnu only */ |
| 1678 | int nDomainPosEnd = 0; |
| 1679 | int nDomainPosStart = 0, nDomainLength = 0; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 1680 | static const WCHAR szDomain[] = {'d','o','m','a','i','n','=',0}; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1681 | LPWSTR lpszDomain = strstrW(&setCookieHeader->lpszValue[nPosEnd], szDomain); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1682 | if (lpszDomain) |
| 1683 | { /* they have specified their own domain, lets use it */ |
| 1684 | while (lpszDomain[nDomainPosEnd] != ';' && lpszDomain[nDomainPosEnd] != ',' && |
| 1685 | lpszDomain[nDomainPosEnd] != '\0') |
| 1686 | { |
| 1687 | nDomainPosEnd++; |
| 1688 | } |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1689 | nDomainPosStart = strlenW(szDomain); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1690 | nDomainLength = (nDomainPosEnd - nDomainPosStart) + 1; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1691 | domain = HeapAlloc(GetProcessHeap(), 0, (nDomainLength + 1)*sizeof(WCHAR)); |
| 1692 | strncpyW(domain, &lpszDomain[nDomainPosStart], nDomainLength); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1693 | domain[nDomainLength] = '\0'; |
| 1694 | } |
| 1695 | } |
| 1696 | if (setCookieHeader->lpszValue[nPosEnd] == '\0') break; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1697 | buf_cookie = HeapAlloc(GetProcessHeap(), 0, ((nPosEnd - nPosStart) + 1)*sizeof(WCHAR)); |
| 1698 | strncpyW(buf_cookie, &setCookieHeader->lpszValue[nPosStart], (nPosEnd - nPosStart)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1699 | buf_cookie[(nPosEnd - nPosStart)] = '\0'; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1700 | TRACE("%s\n", debugstr_w(buf_cookie)); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1701 | while (buf_cookie[nEqualPos] != '=' && buf_cookie[nEqualPos] != '\0') |
| 1702 | { |
| 1703 | nEqualPos++; |
| 1704 | } |
| 1705 | if (buf_cookie[nEqualPos] == '\0' || buf_cookie[nEqualPos + 1] == '\0') |
| 1706 | { |
| 1707 | HeapFree(GetProcessHeap(), 0, buf_cookie); |
| 1708 | break; |
| 1709 | } |
| 1710 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1711 | cookie_name = HeapAlloc(GetProcessHeap(), 0, (nEqualPos + 1)*sizeof(WCHAR)); |
| 1712 | strncpyW(cookie_name, buf_cookie, nEqualPos); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1713 | cookie_name[nEqualPos] = '\0'; |
| 1714 | cookie_data = &buf_cookie[nEqualPos + 1]; |
| 1715 | |
| 1716 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1717 | len = strlenW((domain ? domain : lpwhr->lpszHostName)) + strlenW(lpwhr->lpszPath) + 9; |
| 1718 | buf_url = HeapAlloc(GetProcessHeap(), 0, len*sizeof(WCHAR)); |
| 1719 | sprintfW(buf_url, szFmt, (domain ? domain : lpwhr->lpszHostName)); /* FIXME PATH!!! */ |
| 1720 | InternetSetCookieW(buf_url, cookie_name, cookie_data); |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1721 | |
| 1722 | HeapFree(GetProcessHeap(), 0, buf_url); |
| 1723 | HeapFree(GetProcessHeap(), 0, buf_cookie); |
| 1724 | HeapFree(GetProcessHeap(), 0, cookie_name); |
| 1725 | if (domain) HeapFree(GetProcessHeap(), 0, domain); |
| 1726 | nPosStart = nPosEnd; |
| 1727 | } |
| 1728 | } |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1729 | } |
| 1730 | while (loop_next); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1731 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1732 | lend: |
| 1733 | |
| 1734 | if (requestString) |
| 1735 | HeapFree(GetProcessHeap(), 0, requestString); |
| 1736 | |
Jeremy Shaw | 3cd1cfe | 2003-12-11 04:25:41 +0000 | [diff] [blame] | 1737 | if (lpszHeaders) |
| 1738 | HeapFree(GetProcessHeap(), 0, lpszHeaders_r_n); |
| 1739 | |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1740 | /* TODO: send notification for P3P header */ |
| 1741 | |
| 1742 | if(!(hIC->hdr.dwFlags & INTERNET_FLAG_NO_AUTO_REDIRECT) && bSuccess) |
| 1743 | { |
| 1744 | DWORD dwCode,dwCodeLength=sizeof(DWORD),dwIndex=0; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1745 | if(HttpQueryInfoW(hHttpRequest,HTTP_QUERY_FLAG_NUMBER|HTTP_QUERY_STATUS_CODE,&dwCode,&dwCodeLength,&dwIndex) && |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1746 | (dwCode==302 || dwCode==301)) |
| 1747 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1748 | WCHAR szNewLocation[2048]; |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1749 | DWORD dwBufferSize=2048; |
| 1750 | dwIndex=0; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1751 | if(HttpQueryInfoW(hHttpRequest,HTTP_QUERY_LOCATION,szNewLocation,&dwBufferSize,&dwIndex)) |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 1752 | { |
| 1753 | SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, |
| 1754 | INTERNET_STATUS_REDIRECT, szNewLocation, |
| 1755 | dwBufferSize); |
| 1756 | return HTTP_HandleRedirect(lpwhr, szNewLocation, lpszHeaders, |
| 1757 | dwHeaderLength, lpOptional, dwOptionalLength); |
| 1758 | } |
| 1759 | } |
| 1760 | } |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1761 | |
| 1762 | if (hIC->lpfnStatusCB) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1763 | { |
| 1764 | INTERNET_ASYNC_RESULT iar; |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1765 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1766 | iar.dwResult = (DWORD)bSuccess; |
| 1767 | iar.dwError = bSuccess ? ERROR_SUCCESS : INTERNET_GetLastError(); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1768 | |
| 1769 | SendAsyncCallback(hIC, hHttpRequest, lpwhr->hdr.dwContext, |
| 1770 | INTERNET_STATUS_REQUEST_COMPLETE, &iar, |
| 1771 | sizeof(INTERNET_ASYNC_RESULT)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1772 | } |
| 1773 | |
| 1774 | TRACE("<--\n"); |
| 1775 | return bSuccess; |
| 1776 | } |
| 1777 | |
| 1778 | |
| 1779 | /*********************************************************************** |
| 1780 | * HTTP_Connect (internal) |
| 1781 | * |
| 1782 | * Create http session handle |
| 1783 | * |
| 1784 | * RETURNS |
| 1785 | * HINTERNET a session handle on success |
| 1786 | * NULL on failure |
| 1787 | * |
| 1788 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1789 | HINTERNET HTTP_Connect(HINTERNET hInternet, LPCWSTR lpszServerName, |
| 1790 | INTERNET_PORT nServerPort, LPCWSTR lpszUserName, |
| 1791 | LPCWSTR lpszPassword, DWORD dwFlags, DWORD dwContext) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1792 | { |
| 1793 | BOOL bSuccess = FALSE; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1794 | LPWININETAPPINFOW hIC = NULL; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1795 | LPWININETHTTPSESSIONW lpwhs = NULL; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1796 | HINTERNET handle = NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1797 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1798 | TRACE("-->\n"); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1799 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1800 | hIC = (LPWININETAPPINFOW) WININET_GetObject( hInternet ); |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1801 | if( (hIC == NULL) || (hIC->hdr.htype != WH_HINIT) ) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1802 | goto lerror; |
| 1803 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1804 | hIC->hdr.dwContext = dwContext; |
Dominik Strasser | 94c02fe | 2003-04-14 21:32:36 +0000 | [diff] [blame] | 1805 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1806 | lpwhs = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(WININETHTTPSESSIONW)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1807 | if (NULL == lpwhs) |
| 1808 | { |
| 1809 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
| 1810 | goto lerror; |
| 1811 | } |
| 1812 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1813 | handle = WININET_AllocHandle( &lpwhs->hdr ); |
| 1814 | if (NULL == handle) |
| 1815 | { |
| 1816 | ERR("Failed to alloc handle\n"); |
| 1817 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
| 1818 | goto lerror; |
| 1819 | } |
| 1820 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1821 | /* |
| 1822 | * According to my tests. The name is not resolved until a request is sent |
| 1823 | */ |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1824 | |
| 1825 | if (nServerPort == INTERNET_INVALID_PORT_NUMBER) |
| 1826 | nServerPort = INTERNET_DEFAULT_HTTP_PORT; |
| 1827 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1828 | lpwhs->hdr.htype = WH_HHTTPSESSION; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1829 | lpwhs->hdr.lpwhparent = &hIC->hdr; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1830 | lpwhs->hdr.dwFlags = dwFlags; |
| 1831 | lpwhs->hdr.dwContext = dwContext; |
Dominik Strasser | 94c02fe | 2003-04-14 21:32:36 +0000 | [diff] [blame] | 1832 | if(hIC->lpszProxy && hIC->dwAccessType == INTERNET_OPEN_TYPE_PROXY) { |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1833 | if(strchrW(hIC->lpszProxy, ' ')) |
Dominik Strasser | 94c02fe | 2003-04-14 21:32:36 +0000 | [diff] [blame] | 1834 | FIXME("Several proxies not implemented.\n"); |
| 1835 | if(hIC->lpszProxyBypass) |
| 1836 | FIXME("Proxy bypass is ignored.\n"); |
| 1837 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1838 | if (NULL != lpszServerName) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1839 | lpwhs->lpszServerName = WININET_strdupW(lpszServerName); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1840 | if (NULL != lpszUserName) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1841 | lpwhs->lpszUserName = WININET_strdupW(lpszUserName); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1842 | lpwhs->nServerPort = nServerPort; |
| 1843 | |
| 1844 | if (hIC->lpfnStatusCB) |
| 1845 | { |
| 1846 | INTERNET_ASYNC_RESULT iar; |
| 1847 | |
Lionel Ulmer | a29b4c7 | 2004-02-09 20:55:58 +0000 | [diff] [blame] | 1848 | iar.dwResult = (DWORD)handle; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1849 | iar.dwError = ERROR_SUCCESS; |
| 1850 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1851 | SendAsyncCallback(hIC, hInternet, dwContext, |
| 1852 | INTERNET_STATUS_HANDLE_CREATED, &iar, |
| 1853 | sizeof(INTERNET_ASYNC_RESULT)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1854 | } |
| 1855 | |
| 1856 | bSuccess = TRUE; |
| 1857 | |
| 1858 | lerror: |
| 1859 | if (!bSuccess && lpwhs) |
| 1860 | { |
| 1861 | HeapFree(GetProcessHeap(), 0, lpwhs); |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1862 | WININET_FreeHandle( handle ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1863 | lpwhs = NULL; |
| 1864 | } |
| 1865 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1866 | /* |
| 1867 | * a INTERNET_STATUS_REQUEST_COMPLETE is NOT sent here as per my tests on |
| 1868 | * windows |
| 1869 | */ |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1870 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 1871 | TRACE("%p --> %p\n", hInternet, handle); |
| 1872 | return handle; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1873 | } |
| 1874 | |
| 1875 | |
| 1876 | /*********************************************************************** |
| 1877 | * HTTP_OpenConnection (internal) |
| 1878 | * |
| 1879 | * Connect to a web server |
| 1880 | * |
| 1881 | * RETURNS |
| 1882 | * |
| 1883 | * TRUE on success |
| 1884 | * FALSE on failure |
| 1885 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1886 | BOOL HTTP_OpenConnection(LPWININETHTTPREQW lpwhr) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1887 | { |
| 1888 | BOOL bSuccess = FALSE; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1889 | LPWININETHTTPSESSIONW lpwhs; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1890 | LPWININETAPPINFOW hIC = NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1891 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1892 | TRACE("-->\n"); |
| 1893 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1894 | |
| 1895 | if (NULL == lpwhr || lpwhr->hdr.htype != WH_HHTTPREQ) |
| 1896 | { |
| 1897 | INTERNET_SetLastError(ERROR_INVALID_PARAMETER); |
| 1898 | goto lend; |
| 1899 | } |
| 1900 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1901 | lpwhs = (LPWININETHTTPSESSIONW)lpwhr->hdr.lpwhparent; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1902 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 1903 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1904 | SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, |
| 1905 | INTERNET_STATUS_CONNECTING_TO_SERVER, |
| 1906 | &(lpwhs->socketAddress), |
| 1907 | sizeof(struct sockaddr_in)); |
| 1908 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1909 | if (!NETCON_create(&lpwhr->netConnection, lpwhs->phostent->h_addrtype, |
| 1910 | SOCK_STREAM, 0)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1911 | { |
| 1912 | WARN("Socket creation failed\n"); |
| 1913 | goto lend; |
| 1914 | } |
| 1915 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1916 | if (!NETCON_connect(&lpwhr->netConnection, (struct sockaddr *)&lpwhs->socketAddress, |
| 1917 | sizeof(lpwhs->socketAddress))) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1918 | { |
Andreas Mohr | 3496556 | 2000-08-26 20:31:48 +0000 | [diff] [blame] | 1919 | WARN("Unable to connect to host (%s)\n", strerror(errno)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1920 | goto lend; |
| 1921 | } |
| 1922 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1923 | SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, |
| 1924 | INTERNET_STATUS_CONNECTED_TO_SERVER, |
| 1925 | &(lpwhs->socketAddress), |
| 1926 | sizeof(struct sockaddr_in)); |
| 1927 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1928 | bSuccess = TRUE; |
| 1929 | |
| 1930 | lend: |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1931 | TRACE("%d <--\n", bSuccess); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1932 | return bSuccess; |
| 1933 | } |
| 1934 | |
| 1935 | |
| 1936 | /*********************************************************************** |
| 1937 | * HTTP_GetResponseHeaders (internal) |
| 1938 | * |
| 1939 | * Read server response |
| 1940 | * |
| 1941 | * RETURNS |
| 1942 | * |
| 1943 | * TRUE on success |
| 1944 | * FALSE on error |
| 1945 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1946 | BOOL HTTP_GetResponseHeaders(LPWININETHTTPREQW lpwhr) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1947 | { |
| 1948 | INT cbreaks = 0; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1949 | WCHAR buffer[MAX_REPLY_LEN]; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1950 | DWORD buflen = MAX_REPLY_LEN; |
| 1951 | BOOL bSuccess = FALSE; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1952 | INT rc = 0; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1953 | WCHAR value[MAX_FIELD_VALUE_LEN], field[MAX_FIELD_LEN]; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 1954 | static const WCHAR szStatus[] = {'S','t','a','t','u','s',0}; |
| 1955 | static const WCHAR szHttp[] = { 'H','T','T','P',0 }; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1956 | char bufferA[MAX_REPLY_LEN]; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1957 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1958 | TRACE("-->\n"); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1959 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1960 | if (!NETCON_connected(&lpwhr->netConnection)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1961 | goto lend; |
| 1962 | |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1963 | /* |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1964 | * HACK peek at the buffer |
| 1965 | */ |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1966 | NETCON_recv(&lpwhr->netConnection, buffer, buflen, MSG_PEEK, &rc); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1967 | |
| 1968 | /* |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1969 | * We should first receive 'HTTP/1.x nnn' where nnn is the status code. |
| 1970 | */ |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 1971 | buflen = MAX_REPLY_LEN; |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 1972 | memset(buffer, 0, MAX_REPLY_LEN); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1973 | if (!NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1974 | goto lend; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1975 | MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1976 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1977 | if (strncmpW(buffer, szHttp, 4) != 0) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1978 | goto lend; |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 1979 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1980 | buffer[12]='\0'; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1981 | HTTP_ProcessHeader(lpwhr, szStatus, buffer+9, (HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1982 | |
| 1983 | /* Parse each response line */ |
| 1984 | do |
| 1985 | { |
| 1986 | buflen = MAX_REPLY_LEN; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1987 | if (NETCON_getNextLine(&lpwhr->netConnection, bufferA, &buflen)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1988 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 1989 | TRACE("got line %s, now interpretting\n", debugstr_a(bufferA)); |
| 1990 | MultiByteToWideChar( CP_ACP, 0, bufferA, buflen, buffer, MAX_REPLY_LEN ); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 1991 | if (!HTTP_InterpretHttpHeader(buffer, field, MAX_FIELD_LEN, value, MAX_FIELD_VALUE_LEN)) |
| 1992 | break; |
| 1993 | |
| 1994 | HTTP_ProcessHeader(lpwhr, field, value, (HTTP_ADDREQ_FLAG_ADD | HTTP_ADDREQ_FLAG_REPLACE)); |
| 1995 | } |
| 1996 | else |
| 1997 | { |
| 1998 | cbreaks++; |
| 1999 | if (cbreaks >= 2) |
| 2000 | break; |
| 2001 | } |
| 2002 | }while(1); |
| 2003 | |
| 2004 | bSuccess = TRUE; |
| 2005 | |
| 2006 | lend: |
| 2007 | |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2008 | TRACE("<--\n"); |
| 2009 | if (bSuccess) |
| 2010 | return rc; |
| 2011 | else |
| 2012 | return FALSE; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2013 | } |
| 2014 | |
| 2015 | |
| 2016 | /*********************************************************************** |
| 2017 | * HTTP_InterpretHttpHeader (internal) |
| 2018 | * |
| 2019 | * Parse server response |
| 2020 | * |
| 2021 | * RETURNS |
| 2022 | * |
| 2023 | * TRUE on success |
| 2024 | * FALSE on error |
| 2025 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2026 | INT stripSpaces(LPCWSTR lpszSrc, LPWSTR lpszStart, INT *len) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2027 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2028 | LPCWSTR lpsztmp; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2029 | INT srclen; |
| 2030 | |
| 2031 | srclen = 0; |
| 2032 | |
| 2033 | while (*lpszSrc == ' ' && *lpszSrc != '\0') |
| 2034 | lpszSrc++; |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 2035 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2036 | lpsztmp = lpszSrc; |
| 2037 | while(*lpsztmp != '\0') |
| 2038 | { |
| 2039 | if (*lpsztmp != ' ') |
| 2040 | srclen = lpsztmp - lpszSrc + 1; |
| 2041 | |
| 2042 | lpsztmp++; |
| 2043 | } |
| 2044 | |
| 2045 | *len = min(*len, srclen); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2046 | strncpyW(lpszStart, lpszSrc, *len); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2047 | lpszStart[*len] = '\0'; |
| 2048 | |
| 2049 | return *len; |
| 2050 | } |
| 2051 | |
| 2052 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2053 | BOOL HTTP_InterpretHttpHeader(LPWSTR buffer, LPWSTR field, INT fieldlen, LPWSTR value, INT valuelen) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2054 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2055 | WCHAR *pd; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2056 | BOOL bSuccess = FALSE; |
| 2057 | |
| 2058 | TRACE("\n"); |
| 2059 | |
| 2060 | *field = '\0'; |
| 2061 | *value = '\0'; |
| 2062 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2063 | pd = strchrW(buffer, ':'); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2064 | if (pd) |
| 2065 | { |
| 2066 | *pd = '\0'; |
| 2067 | if (stripSpaces(buffer, field, &fieldlen) > 0) |
| 2068 | { |
| 2069 | if (stripSpaces(pd+1, value, &valuelen) > 0) |
| 2070 | bSuccess = TRUE; |
| 2071 | } |
| 2072 | } |
| 2073 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2074 | TRACE("%d: field(%s) Value(%s)\n", bSuccess, debugstr_w(field), debugstr_w(value)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2075 | return bSuccess; |
| 2076 | } |
| 2077 | |
| 2078 | |
| 2079 | /*********************************************************************** |
| 2080 | * HTTP_GetStdHeaderIndex (internal) |
| 2081 | * |
John R. Sheets | 646d2a2 | 2000-07-23 13:34:43 +0000 | [diff] [blame] | 2082 | * Lookup field index in standard http header array |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2083 | * |
| 2084 | * FIXME: This should be stuffed into a hash table |
| 2085 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2086 | INT HTTP_GetStdHeaderIndex(LPCWSTR lpszField) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2087 | { |
| 2088 | INT index = -1; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2089 | static const WCHAR szContentLength[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2090 | 'C','o','n','t','e','n','t','-','L','e','n','g','t','h',0}; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2091 | static const WCHAR szStatus[] = {'S','t','a','t','u','s',0}; |
| 2092 | static const WCHAR szContentType[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2093 | 'C','o','n','t','e','n','t','-','T','y','p','e',0}; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2094 | static const WCHAR szLastModified[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2095 | 'L','a','s','t','-','M','o','d','i','f','i','e','d',0}; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2096 | static const WCHAR szLocation[] = {'L','o','c','a','t','i','o','n',0}; |
| 2097 | static const WCHAR szAccept[] = {'A','c','c','e','p','t',0}; |
| 2098 | static const WCHAR szReferer[] = { 'R','e','f','e','r','e','r',0}; |
| 2099 | static const WCHAR szContentTrans[] = { 'C','o','n','t','e','n','t','-', |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2100 | 'T','r','a','n','s','f','e','r','-','E','n','c','o','d','i','n','g',0}; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2101 | static const WCHAR szDate[] = { 'D','a','t','e',0}; |
| 2102 | static const WCHAR szServer[] = { 'S','e','r','v','e','r',0}; |
| 2103 | static const WCHAR szConnection[] = { 'C','o','n','n','e','c','t','i','o','n',0}; |
| 2104 | static const WCHAR szETag[] = { 'E','T','a','g',0}; |
| 2105 | static const WCHAR szAcceptRanges[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2106 | 'A','c','c','e','p','t','-','R','a','n','g','e','s',0 }; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2107 | static const WCHAR szExpires[] = { 'E','x','p','i','r','e','s',0 }; |
| 2108 | static const WCHAR szMimeVersion[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2109 | 'M','i','m','e','-','V','e','r','s','i','o','n', 0}; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2110 | static const WCHAR szPragma[] = { 'P','r','a','g','m','a', 0}; |
| 2111 | static const WCHAR szCacheControl[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2112 | 'C','a','c','h','e','-','C','o','n','t','r','o','l',0}; |
Francois Gouget | 6a6c85c | 2004-04-19 20:12:14 +0000 | [diff] [blame^] | 2113 | static const WCHAR szUserAgent[] = { 'U','s','e','r','-','A','g','e','n','t',0}; |
| 2114 | static const WCHAR szProxyAuth[] = { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2115 | 'P','r','o','x','y','-', |
| 2116 | 'A','u','t','h','e','n','t','i','c','a','t','e', 0}; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2117 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2118 | if (!strcmpiW(lpszField, szContentLength)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2119 | index = HTTP_QUERY_CONTENT_LENGTH; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2120 | else if (!strcmpiW(lpszField,szStatus)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2121 | index = HTTP_QUERY_STATUS_CODE; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2122 | else if (!strcmpiW(lpszField,szContentType)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2123 | index = HTTP_QUERY_CONTENT_TYPE; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2124 | else if (!strcmpiW(lpszField,szLastModified)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2125 | index = HTTP_QUERY_LAST_MODIFIED; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2126 | else if (!strcmpiW(lpszField,szLocation)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2127 | index = HTTP_QUERY_LOCATION; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2128 | else if (!strcmpiW(lpszField,szAccept)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2129 | index = HTTP_QUERY_ACCEPT; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2130 | else if (!strcmpiW(lpszField,szReferer)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2131 | index = HTTP_QUERY_REFERER; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2132 | else if (!strcmpiW(lpszField,szContentTrans)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2133 | index = HTTP_QUERY_CONTENT_TRANSFER_ENCODING; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2134 | else if (!strcmpiW(lpszField,szDate)) |
John R. Sheets | 646d2a2 | 2000-07-23 13:34:43 +0000 | [diff] [blame] | 2135 | index = HTTP_QUERY_DATE; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2136 | else if (!strcmpiW(lpszField,szServer)) |
John R. Sheets | 646d2a2 | 2000-07-23 13:34:43 +0000 | [diff] [blame] | 2137 | index = HTTP_QUERY_SERVER; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2138 | else if (!strcmpiW(lpszField,szConnection)) |
John R. Sheets | 646d2a2 | 2000-07-23 13:34:43 +0000 | [diff] [blame] | 2139 | index = HTTP_QUERY_CONNECTION; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2140 | else if (!strcmpiW(lpszField,szETag)) |
John R. Sheets | 646d2a2 | 2000-07-23 13:34:43 +0000 | [diff] [blame] | 2141 | index = HTTP_QUERY_ETAG; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2142 | else if (!strcmpiW(lpszField,szAcceptRanges)) |
John R. Sheets | 646d2a2 | 2000-07-23 13:34:43 +0000 | [diff] [blame] | 2143 | index = HTTP_QUERY_ACCEPT_RANGES; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2144 | else if (!strcmpiW(lpszField,szExpires)) |
John R. Sheets | 646d2a2 | 2000-07-23 13:34:43 +0000 | [diff] [blame] | 2145 | index = HTTP_QUERY_EXPIRES; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2146 | else if (!strcmpiW(lpszField,szMimeVersion)) |
John R. Sheets | 66b4dd2 | 2000-08-03 22:16:39 +0000 | [diff] [blame] | 2147 | index = HTTP_QUERY_MIME_VERSION; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2148 | else if (!strcmpiW(lpszField,szPragma)) |
Johan Dahlin | 664b9bb | 2001-12-17 20:50:53 +0000 | [diff] [blame] | 2149 | index = HTTP_QUERY_PRAGMA; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2150 | else if (!strcmpiW(lpszField,szCacheControl)) |
Johan Dahlin | 664b9bb | 2001-12-17 20:50:53 +0000 | [diff] [blame] | 2151 | index = HTTP_QUERY_CACHE_CONTROL; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2152 | else if (!strcmpiW(lpszField,szUserAgent)) |
Johan Dahlin | 664b9bb | 2001-12-17 20:50:53 +0000 | [diff] [blame] | 2153 | index = HTTP_QUERY_USER_AGENT; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2154 | else if (!strcmpiW(lpszField,szProxyAuth)) |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2155 | index = HTTP_QUERY_PROXY_AUTHENTICATE; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2156 | else |
| 2157 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2158 | TRACE("Couldn't find %s in standard header table\n", debugstr_w(lpszField)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2159 | } |
| 2160 | |
| 2161 | return index; |
| 2162 | } |
| 2163 | |
| 2164 | |
| 2165 | /*********************************************************************** |
| 2166 | * HTTP_ProcessHeader (internal) |
| 2167 | * |
| 2168 | * Stuff header into header tables according to <dwModifier> |
| 2169 | * |
| 2170 | */ |
| 2171 | |
| 2172 | #define COALESCEFLASG (HTTP_ADDHDR_FLAG_COALESCE|HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA|HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON) |
| 2173 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2174 | BOOL HTTP_ProcessHeader(LPWININETHTTPREQW lpwhr, LPCWSTR field, LPCWSTR value, DWORD dwModifier) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2175 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2176 | LPHTTPHEADERW lphttpHdr = NULL; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2177 | BOOL bSuccess = FALSE; |
| 2178 | INT index; |
| 2179 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2180 | TRACE("--> %s: %s - 0x%08x\n", debugstr_w(field), debugstr_w(value), (unsigned int)dwModifier); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2181 | |
| 2182 | /* Adjust modifier flags */ |
| 2183 | if (dwModifier & COALESCEFLASG) |
| 2184 | dwModifier |= HTTP_ADDHDR_FLAG_ADD; |
| 2185 | |
| 2186 | /* Try to get index into standard header array */ |
| 2187 | index = HTTP_GetStdHeaderIndex(field); |
| 2188 | if (index >= 0) |
| 2189 | { |
| 2190 | lphttpHdr = &lpwhr->StdHeaders[index]; |
| 2191 | } |
| 2192 | else /* Find or create new custom header */ |
| 2193 | { |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2194 | index = HTTP_GetCustomHeaderIndex(lpwhr, field); |
| 2195 | if (index >= 0) |
| 2196 | { |
| 2197 | if (dwModifier & HTTP_ADDHDR_FLAG_ADD_IF_NEW) |
| 2198 | { |
| 2199 | return FALSE; |
| 2200 | } |
| 2201 | lphttpHdr = &lpwhr->pCustHeaders[index]; |
| 2202 | } |
| 2203 | else |
| 2204 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2205 | HTTPHEADERW hdr; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2206 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2207 | hdr.lpszField = (LPWSTR)field; |
| 2208 | hdr.lpszValue = (LPWSTR)value; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2209 | hdr.wFlags = hdr.wCount = 0; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2210 | |
| 2211 | if (dwModifier & HTTP_ADDHDR_FLAG_REQ) |
| 2212 | hdr.wFlags |= HDR_ISREQUEST; |
| 2213 | |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2214 | return HTTP_InsertCustomHeader(lpwhr, &hdr); |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2215 | } |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2216 | } |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 2217 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2218 | if (dwModifier & HTTP_ADDHDR_FLAG_REQ) |
| 2219 | lphttpHdr->wFlags |= HDR_ISREQUEST; |
| 2220 | else |
| 2221 | lphttpHdr->wFlags &= ~HDR_ISREQUEST; |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 2222 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2223 | if (!lphttpHdr->lpszValue && (dwModifier & (HTTP_ADDHDR_FLAG_ADD|HTTP_ADDHDR_FLAG_ADD_IF_NEW))) |
| 2224 | { |
| 2225 | INT slen; |
| 2226 | |
| 2227 | if (!lpwhr->StdHeaders[index].lpszField) |
| 2228 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2229 | lphttpHdr->lpszField = WININET_strdupW(field); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2230 | |
| 2231 | if (dwModifier & HTTP_ADDHDR_FLAG_REQ) |
| 2232 | lphttpHdr->wFlags |= HDR_ISREQUEST; |
| 2233 | } |
| 2234 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2235 | slen = strlenW(value) + 1; |
| 2236 | lphttpHdr->lpszValue = HeapAlloc(GetProcessHeap(), 0, slen*sizeof(WCHAR)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2237 | if (lphttpHdr->lpszValue) |
| 2238 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2239 | strcpyW(lphttpHdr->lpszValue, value); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2240 | bSuccess = TRUE; |
| 2241 | } |
| 2242 | else |
| 2243 | { |
| 2244 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
| 2245 | } |
| 2246 | } |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 2247 | else if (lphttpHdr->lpszValue) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2248 | { |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 2249 | if (dwModifier & HTTP_ADDHDR_FLAG_REPLACE) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2250 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2251 | LPWSTR lpsztmp; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2252 | INT len; |
| 2253 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2254 | len = strlenW(value); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2255 | |
| 2256 | if (len <= 0) |
| 2257 | { |
Patrik Stridvall | fc2be7e | 2002-04-29 18:48:56 +0000 | [diff] [blame] | 2258 | /* if custom header delete from array */ |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2259 | HeapFree(GetProcessHeap(), 0, lphttpHdr->lpszValue); |
| 2260 | lphttpHdr->lpszValue = NULL; |
| 2261 | bSuccess = TRUE; |
| 2262 | } |
| 2263 | else |
| 2264 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2265 | lpsztmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lphttpHdr->lpszValue, (len+1)*sizeof(WCHAR)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2266 | if (lpsztmp) |
| 2267 | { |
| 2268 | lphttpHdr->lpszValue = lpsztmp; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2269 | strcpyW(lpsztmp, value); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2270 | bSuccess = TRUE; |
| 2271 | } |
| 2272 | else |
| 2273 | { |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 2274 | WARN("HeapReAlloc (%d bytes) failed\n",len+1); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2275 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
| 2276 | } |
| 2277 | } |
| 2278 | } |
| 2279 | else if (dwModifier & COALESCEFLASG) |
| 2280 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2281 | LPWSTR lpsztmp; |
| 2282 | WCHAR ch = 0; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2283 | INT len = 0; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2284 | INT origlen = strlenW(lphttpHdr->lpszValue); |
| 2285 | INT valuelen = strlenW(value); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2286 | |
| 2287 | if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_COMMA) |
| 2288 | { |
| 2289 | ch = ','; |
| 2290 | lphttpHdr->wFlags |= HDR_COMMADELIMITED; |
| 2291 | } |
| 2292 | else if (dwModifier & HTTP_ADDHDR_FLAG_COALESCE_WITH_SEMICOLON) |
| 2293 | { |
| 2294 | ch = ';'; |
| 2295 | lphttpHdr->wFlags |= HDR_COMMADELIMITED; |
| 2296 | } |
| 2297 | |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 2298 | len = origlen + valuelen + ((ch > 0) ? 1 : 0); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2299 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2300 | lpsztmp = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lphttpHdr->lpszValue, (len+1)*sizeof(WCHAR)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2301 | if (lpsztmp) |
| 2302 | { |
Vincent BĂ©ron | 9a62491 | 2002-05-31 23:06:46 +0000 | [diff] [blame] | 2303 | /* FIXME: Increment lphttpHdr->wCount. Perhaps lpszValue should be an array */ |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2304 | if (ch > 0) |
| 2305 | { |
| 2306 | lphttpHdr->lpszValue[origlen] = ch; |
| 2307 | origlen++; |
| 2308 | } |
| 2309 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2310 | memcpy(&lphttpHdr->lpszValue[origlen], value, valuelen*sizeof(WCHAR)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2311 | lphttpHdr->lpszValue[len] = '\0'; |
| 2312 | bSuccess = TRUE; |
| 2313 | } |
| 2314 | else |
| 2315 | { |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 2316 | WARN("HeapReAlloc (%d bytes) failed\n",len+1); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2317 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
| 2318 | } |
| 2319 | } |
| 2320 | } |
Alberto Massari | bc8bd72 | 2002-12-06 23:20:31 +0000 | [diff] [blame] | 2321 | TRACE("<-- %d\n",bSuccess); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2322 | return bSuccess; |
| 2323 | } |
| 2324 | |
| 2325 | |
| 2326 | /*********************************************************************** |
| 2327 | * HTTP_CloseConnection (internal) |
| 2328 | * |
| 2329 | * Close socket connection |
| 2330 | * |
| 2331 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2332 | VOID HTTP_CloseConnection(LPWININETHTTPREQW lpwhr) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2333 | { |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2334 | |
| 2335 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2336 | LPWININETHTTPSESSIONW lpwhs = NULL; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 2337 | LPWININETAPPINFOW hIC = NULL; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 2338 | HINTERNET handle; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2339 | |
| 2340 | TRACE("%p\n",lpwhr); |
| 2341 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 2342 | handle = WININET_FindHandle( &lpwhr->hdr ); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2343 | lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 2344 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2345 | |
| 2346 | SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, |
| 2347 | INTERNET_STATUS_CLOSING_CONNECTION, 0, 0); |
| 2348 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 2349 | if (NETCON_connected(&lpwhr->netConnection)) |
| 2350 | { |
| 2351 | NETCON_close(&lpwhr->netConnection); |
| 2352 | } |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2353 | |
| 2354 | SendAsyncCallback(hIC, lpwhr, lpwhr->hdr.dwContext, |
| 2355 | INTERNET_STATUS_CONNECTION_CLOSED, 0, 0); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2356 | } |
| 2357 | |
| 2358 | |
| 2359 | /*********************************************************************** |
| 2360 | * HTTP_CloseHTTPRequestHandle (internal) |
| 2361 | * |
| 2362 | * Deallocate request handle |
| 2363 | * |
| 2364 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2365 | void HTTP_CloseHTTPRequestHandle(LPWININETHTTPREQW lpwhr) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2366 | { |
| 2367 | int i; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2368 | LPWININETHTTPSESSIONW lpwhs = NULL; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 2369 | LPWININETAPPINFOW hIC = NULL; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 2370 | HINTERNET handle; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2371 | |
| 2372 | TRACE("\n"); |
| 2373 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 2374 | if (NETCON_connected(&lpwhr->netConnection)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2375 | HTTP_CloseConnection(lpwhr); |
| 2376 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 2377 | handle = WININET_FindHandle( &lpwhr->hdr ); |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2378 | lpwhs = (LPWININETHTTPSESSIONW) lpwhr->hdr.lpwhparent; |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 2379 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2380 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 2381 | SendAsyncCallback(hIC, handle, lpwhr->hdr.dwContext, |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2382 | INTERNET_STATUS_HANDLE_CLOSING, lpwhr, |
| 2383 | sizeof(HINTERNET)); |
| 2384 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2385 | if (lpwhr->lpszPath) |
| 2386 | HeapFree(GetProcessHeap(), 0, lpwhr->lpszPath); |
| 2387 | if (lpwhr->lpszVerb) |
| 2388 | HeapFree(GetProcessHeap(), 0, lpwhr->lpszVerb); |
| 2389 | if (lpwhr->lpszHostName) |
| 2390 | HeapFree(GetProcessHeap(), 0, lpwhr->lpszHostName); |
| 2391 | |
| 2392 | for (i = 0; i <= HTTP_QUERY_MAX; i++) |
| 2393 | { |
| 2394 | if (lpwhr->StdHeaders[i].lpszField) |
| 2395 | HeapFree(GetProcessHeap(), 0, lpwhr->StdHeaders[i].lpszField); |
| 2396 | if (lpwhr->StdHeaders[i].lpszValue) |
| 2397 | HeapFree(GetProcessHeap(), 0, lpwhr->StdHeaders[i].lpszValue); |
| 2398 | } |
| 2399 | |
| 2400 | for (i = 0; i < lpwhr->nCustHeaders; i++) |
| 2401 | { |
| 2402 | if (lpwhr->pCustHeaders[i].lpszField) |
| 2403 | HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders[i].lpszField); |
| 2404 | if (lpwhr->pCustHeaders[i].lpszValue) |
| 2405 | HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders[i].lpszValue); |
| 2406 | } |
| 2407 | |
| 2408 | HeapFree(GetProcessHeap(), 0, lpwhr->pCustHeaders); |
| 2409 | HeapFree(GetProcessHeap(), 0, lpwhr); |
| 2410 | } |
| 2411 | |
| 2412 | |
| 2413 | /*********************************************************************** |
| 2414 | * HTTP_CloseHTTPSessionHandle (internal) |
| 2415 | * |
| 2416 | * Deallocate session handle |
| 2417 | * |
| 2418 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2419 | void HTTP_CloseHTTPSessionHandle(LPWININETHTTPSESSIONW lpwhs) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2420 | { |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 2421 | LPWININETAPPINFOW hIC = NULL; |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 2422 | HINTERNET handle; |
| 2423 | |
David Hammerton | 852c7ae | 2003-06-20 23:26:56 +0000 | [diff] [blame] | 2424 | TRACE("%p\n", lpwhs); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2425 | |
Mike McCormack | 09d2d47 | 2004-03-25 05:29:47 +0000 | [diff] [blame] | 2426 | hIC = (LPWININETAPPINFOW) lpwhs->hdr.lpwhparent; |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2427 | |
Mike McCormack | 7cc70c0 | 2004-02-07 01:03:41 +0000 | [diff] [blame] | 2428 | handle = WININET_FindHandle( &lpwhs->hdr ); |
| 2429 | SendAsyncCallback(hIC, handle, lpwhs->hdr.dwContext, |
Aric Stewart | ff9b9d4 | 2002-06-21 23:59:49 +0000 | [diff] [blame] | 2430 | INTERNET_STATUS_HANDLE_CLOSING, lpwhs, |
| 2431 | sizeof(HINTERNET)); |
| 2432 | |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2433 | if (lpwhs->lpszServerName) |
| 2434 | HeapFree(GetProcessHeap(), 0, lpwhs->lpszServerName); |
| 2435 | if (lpwhs->lpszUserName) |
| 2436 | HeapFree(GetProcessHeap(), 0, lpwhs->lpszUserName); |
| 2437 | HeapFree(GetProcessHeap(), 0, lpwhs); |
| 2438 | } |
| 2439 | |
| 2440 | |
| 2441 | /*********************************************************************** |
| 2442 | * HTTP_GetCustomHeaderIndex (internal) |
| 2443 | * |
| 2444 | * Return index of custom header from header array |
| 2445 | * |
| 2446 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2447 | INT HTTP_GetCustomHeaderIndex(LPWININETHTTPREQW lpwhr, LPCWSTR lpszField) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2448 | { |
| 2449 | INT index; |
| 2450 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2451 | TRACE("%s\n", debugstr_w(lpszField)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2452 | |
| 2453 | for (index = 0; index < lpwhr->nCustHeaders; index++) |
| 2454 | { |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2455 | if (!strcmpiW(lpwhr->pCustHeaders[index].lpszField, lpszField)) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2456 | break; |
| 2457 | |
| 2458 | } |
| 2459 | |
| 2460 | if (index >= lpwhr->nCustHeaders) |
| 2461 | index = -1; |
| 2462 | |
| 2463 | TRACE("Return: %d\n", index); |
| 2464 | return index; |
| 2465 | } |
| 2466 | |
| 2467 | |
| 2468 | /*********************************************************************** |
| 2469 | * HTTP_InsertCustomHeader (internal) |
| 2470 | * |
| 2471 | * Insert header into array |
| 2472 | * |
| 2473 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2474 | BOOL HTTP_InsertCustomHeader(LPWININETHTTPREQW lpwhr, LPHTTPHEADERW lpHdr) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2475 | { |
| 2476 | INT count; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2477 | LPHTTPHEADERW lph = NULL; |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2478 | BOOL r = FALSE; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2479 | |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2480 | TRACE("--> %s: %s\n", debugstr_w(lpHdr->lpszField), debugstr_w(lpHdr->lpszValue)); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2481 | count = lpwhr->nCustHeaders + 1; |
| 2482 | if (count > 1) |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2483 | lph = HeapReAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, lpwhr->pCustHeaders, sizeof(HTTPHEADERW) * count); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2484 | else |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2485 | lph = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(HTTPHEADERW) * count); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2486 | |
| 2487 | if (NULL != lph) |
| 2488 | { |
| 2489 | lpwhr->pCustHeaders = lph; |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2490 | lpwhr->pCustHeaders[count-1].lpszField = WININET_strdupW(lpHdr->lpszField); |
| 2491 | lpwhr->pCustHeaders[count-1].lpszValue = WININET_strdupW(lpHdr->lpszValue); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2492 | lpwhr->pCustHeaders[count-1].wFlags = lpHdr->wFlags; |
| 2493 | lpwhr->pCustHeaders[count-1].wCount= lpHdr->wCount; |
| 2494 | lpwhr->nCustHeaders++; |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2495 | r = TRUE; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2496 | } |
| 2497 | else |
| 2498 | { |
| 2499 | INTERNET_SetLastError(ERROR_OUTOFMEMORY); |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2500 | } |
| 2501 | |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2502 | return r; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2503 | } |
| 2504 | |
| 2505 | |
| 2506 | /*********************************************************************** |
| 2507 | * HTTP_DeleteCustomHeader (internal) |
| 2508 | * |
| 2509 | * Delete header from array |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2510 | * If this function is called, the indexs may change. |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2511 | */ |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2512 | BOOL HTTP_DeleteCustomHeader(LPWININETHTTPREQW lpwhr, INT index) |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2513 | { |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2514 | if( lpwhr->nCustHeaders <= 0 ) |
| 2515 | return FALSE; |
| 2516 | if( lpwhr->nCustHeaders >= index ) |
| 2517 | return FALSE; |
| 2518 | lpwhr->nCustHeaders--; |
| 2519 | |
| 2520 | memmove( &lpwhr->pCustHeaders[index], &lpwhr->pCustHeaders[index+1], |
Mike McCormack | a4e902c | 2004-03-30 04:36:09 +0000 | [diff] [blame] | 2521 | (lpwhr->nCustHeaders - index)* sizeof(HTTPHEADERW) ); |
| 2522 | memset( &lpwhr->pCustHeaders[lpwhr->nCustHeaders], 0, sizeof(HTTPHEADERW) ); |
Mike McCormack | a1c16d2 | 2003-07-22 03:17:52 +0000 | [diff] [blame] | 2523 | |
| 2524 | return TRUE; |
Ulrich Czekalla | c275724 | 2000-06-11 20:04:44 +0000 | [diff] [blame] | 2525 | } |
Alberto Massari | b09eef2 | 2002-11-13 04:08:26 +0000 | [diff] [blame] | 2526 | |
| 2527 | /*********************************************************************** |
| 2528 | * IsHostInProxyBypassList (@) |
| 2529 | * |
| 2530 | * Undocumented |
| 2531 | * |
| 2532 | */ |
| 2533 | BOOL WINAPI IsHostInProxyBypassList(DWORD flags, LPCSTR szHost, DWORD length) |
| 2534 | { |
| 2535 | FIXME("STUB: flags=%ld host=%s length=%ld\n",flags,szHost,length); |
| 2536 | return FALSE; |
| 2537 | } |