ReactOS 0.4.15-dev-7788-g1ad9096
request.c
Go to the documentation of this file.
1/*
2 * Copyright 2004 Mike McCormack for CodeWeavers
3 * Copyright 2006 Rob Shearman for CodeWeavers
4 * Copyright 2008, 2011 Hans Leidekker for CodeWeavers
5 * Copyright 2009 Juan Lang
6 *
7 * This library is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with this library; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
20 */
21
22#define COBJMACROS
23#include "config.h"
24#include "ws2tcpip.h"
25#include <stdarg.h>
26#include <assert.h>
27
28#include "windef.h"
29#include "winbase.h"
30#include "ole2.h"
31#include "initguid.h"
32#include "httprequest.h"
33#include "httprequestid.h"
34#include "schannel.h"
35#include "winhttp.h"
36
37#include "wine/debug.h"
38#include "winhttp_private.h"
39
41
42#ifdef __REACTOS__
43#include "inet_ntop.c"
44#endif
45
46#define DEFAULT_KEEP_ALIVE_TIMEOUT 30000
47
48static const WCHAR attr_accept[] = {'A','c','c','e','p','t',0};
49static const WCHAR attr_accept_charset[] = {'A','c','c','e','p','t','-','C','h','a','r','s','e','t', 0};
50static const WCHAR attr_accept_encoding[] = {'A','c','c','e','p','t','-','E','n','c','o','d','i','n','g',0};
51static const WCHAR attr_accept_language[] = {'A','c','c','e','p','t','-','L','a','n','g','u','a','g','e',0};
52static const WCHAR attr_accept_ranges[] = {'A','c','c','e','p','t','-','R','a','n','g','e','s',0};
53static const WCHAR attr_age[] = {'A','g','e',0};
54static const WCHAR attr_allow[] = {'A','l','l','o','w',0};
55static const WCHAR attr_authorization[] = {'A','u','t','h','o','r','i','z','a','t','i','o','n',0};
56static const WCHAR attr_cache_control[] = {'C','a','c','h','e','-','C','o','n','t','r','o','l',0};
57static const WCHAR attr_connection[] = {'C','o','n','n','e','c','t','i','o','n',0};
58static const WCHAR attr_content_base[] = {'C','o','n','t','e','n','t','-','B','a','s','e',0};
59static const WCHAR attr_content_encoding[] = {'C','o','n','t','e','n','t','-','E','n','c','o','d','i','n','g',0};
60static const WCHAR attr_content_id[] = {'C','o','n','t','e','n','t','-','I','D',0};
61static const WCHAR attr_content_language[] = {'C','o','n','t','e','n','t','-','L','a','n','g','u','a','g','e',0};
62static const WCHAR attr_content_length[] = {'C','o','n','t','e','n','t','-','L','e','n','g','t','h',0};
63static const WCHAR attr_content_location[] = {'C','o','n','t','e','n','t','-','L','o','c','a','t','i','o','n',0};
64static const WCHAR attr_content_md5[] = {'C','o','n','t','e','n','t','-','M','D','5',0};
65static const WCHAR attr_content_range[] = {'C','o','n','t','e','n','t','-','R','a','n','g','e',0};
66static const WCHAR attr_content_transfer_encoding[] = {'C','o','n','t','e','n','t','-','T','r','a','n','s','f','e','r','-','E','n','c','o','d','i','n','g',0};
67static const WCHAR attr_content_type[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
68static const WCHAR attr_cookie[] = {'C','o','o','k','i','e',0};
69static const WCHAR attr_date[] = {'D','a','t','e',0};
70static const WCHAR attr_from[] = {'F','r','o','m',0};
71static const WCHAR attr_etag[] = {'E','T','a','g',0};
72static const WCHAR attr_expect[] = {'E','x','p','e','c','t',0};
73static const WCHAR attr_expires[] = {'E','x','p','i','r','e','s',0};
74static const WCHAR attr_host[] = {'H','o','s','t',0};
75static const WCHAR attr_if_match[] = {'I','f','-','M','a','t','c','h',0};
76static const WCHAR attr_if_modified_since[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
77static const WCHAR attr_if_none_match[] = {'I','f','-','N','o','n','e','-','M','a','t','c','h',0};
78static const WCHAR attr_if_range[] = {'I','f','-','R','a','n','g','e',0};
79static const WCHAR attr_if_unmodified_since[] = {'I','f','-','U','n','m','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
80static const WCHAR attr_last_modified[] = {'L','a','s','t','-','M','o','d','i','f','i','e','d',0};
81static const WCHAR attr_location[] = {'L','o','c','a','t','i','o','n',0};
82static const WCHAR attr_max_forwards[] = {'M','a','x','-','F','o','r','w','a','r','d','s',0};
83static const WCHAR attr_mime_version[] = {'M','i','m','e','-','V','e','r','s','i','o','n',0};
84static const WCHAR attr_pragma[] = {'P','r','a','g','m','a',0};
85static const WCHAR attr_proxy_authenticate[] = {'P','r','o','x','y','-','A','u','t','h','e','n','t','i','c','a','t','e',0};
86static const WCHAR attr_proxy_authorization[] = {'P','r','o','x','y','-','A','u','t','h','o','r','i','z','a','t','i','o','n',0};
87static const WCHAR attr_proxy_connection[] = {'P','r','o','x','y','-','C','o','n','n','e','c','t','i','o','n',0};
88static const WCHAR attr_public[] = {'P','u','b','l','i','c',0};
89static const WCHAR attr_range[] = {'R','a','n','g','e',0};
90static const WCHAR attr_referer[] = {'R','e','f','e','r','e','r',0};
91static const WCHAR attr_retry_after[] = {'R','e','t','r','y','-','A','f','t','e','r',0};
92static const WCHAR attr_server[] = {'S','e','r','v','e','r',0};
93static const WCHAR attr_set_cookie[] = {'S','e','t','-','C','o','o','k','i','e',0};
94static const WCHAR attr_status[] = {'S','t','a','t','u','s',0};
95static const WCHAR attr_transfer_encoding[] = {'T','r','a','n','s','f','e','r','-','E','n','c','o','d','i','n','g',0};
96static const WCHAR attr_unless_modified_since[] = {'U','n','l','e','s','s','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0};
97static const WCHAR attr_upgrade[] = {'U','p','g','r','a','d','e',0};
98static const WCHAR attr_uri[] = {'U','R','I',0};
99static const WCHAR attr_user_agent[] = {'U','s','e','r','-','A','g','e','n','t',0};
100static const WCHAR attr_vary[] = {'V','a','r','y',0};
101static const WCHAR attr_via[] = {'V','i','a',0};
102static const WCHAR attr_warning[] = {'W','a','r','n','i','n','g',0};
103static const WCHAR attr_www_authenticate[] = {'W','W','W','-','A','u','t','h','e','n','t','i','c','a','t','e',0};
104
105static const WCHAR *attribute_table[] =
106{
107 attr_mime_version, /* WINHTTP_QUERY_MIME_VERSION = 0 */
108 attr_content_type, /* WINHTTP_QUERY_CONTENT_TYPE = 1 */
109 attr_content_transfer_encoding, /* WINHTTP_QUERY_CONTENT_TRANSFER_ENCODING = 2 */
110 attr_content_id, /* WINHTTP_QUERY_CONTENT_ID = 3 */
111 NULL, /* WINHTTP_QUERY_CONTENT_DESCRIPTION = 4 */
112 attr_content_length, /* WINHTTP_QUERY_CONTENT_LENGTH = 5 */
113 attr_content_language, /* WINHTTP_QUERY_CONTENT_LANGUAGE = 6 */
114 attr_allow, /* WINHTTP_QUERY_ALLOW = 7 */
115 attr_public, /* WINHTTP_QUERY_PUBLIC = 8 */
116 attr_date, /* WINHTTP_QUERY_DATE = 9 */
117 attr_expires, /* WINHTTP_QUERY_EXPIRES = 10 */
118 attr_last_modified, /* WINHTTP_QUERY_LAST_MODIFIEDcw = 11 */
119 NULL, /* WINHTTP_QUERY_MESSAGE_ID = 12 */
120 attr_uri, /* WINHTTP_QUERY_URI = 13 */
121 attr_from, /* WINHTTP_QUERY_DERIVED_FROM = 14 */
122 NULL, /* WINHTTP_QUERY_COST = 15 */
123 NULL, /* WINHTTP_QUERY_LINK = 16 */
124 attr_pragma, /* WINHTTP_QUERY_PRAGMA = 17 */
125 NULL, /* WINHTTP_QUERY_VERSION = 18 */
126 attr_status, /* WINHTTP_QUERY_STATUS_CODE = 19 */
127 NULL, /* WINHTTP_QUERY_STATUS_TEXT = 20 */
128 NULL, /* WINHTTP_QUERY_RAW_HEADERS = 21 */
129 NULL, /* WINHTTP_QUERY_RAW_HEADERS_CRLF = 22 */
130 attr_connection, /* WINHTTP_QUERY_CONNECTION = 23 */
131 attr_accept, /* WINHTTP_QUERY_ACCEPT = 24 */
132 attr_accept_charset, /* WINHTTP_QUERY_ACCEPT_CHARSET = 25 */
133 attr_accept_encoding, /* WINHTTP_QUERY_ACCEPT_ENCODING = 26 */
134 attr_accept_language, /* WINHTTP_QUERY_ACCEPT_LANGUAGE = 27 */
135 attr_authorization, /* WINHTTP_QUERY_AUTHORIZATION = 28 */
136 attr_content_encoding, /* WINHTTP_QUERY_CONTENT_ENCODING = 29 */
137 NULL, /* WINHTTP_QUERY_FORWARDED = 30 */
138 NULL, /* WINHTTP_QUERY_FROM = 31 */
139 attr_if_modified_since, /* WINHTTP_QUERY_IF_MODIFIED_SINCE = 32 */
140 attr_location, /* WINHTTP_QUERY_LOCATION = 33 */
141 NULL, /* WINHTTP_QUERY_ORIG_URI = 34 */
142 attr_referer, /* WINHTTP_QUERY_REFERER = 35 */
143 attr_retry_after, /* WINHTTP_QUERY_RETRY_AFTER = 36 */
144 attr_server, /* WINHTTP_QUERY_SERVER = 37 */
145 NULL, /* WINHTTP_TITLE = 38 */
146 attr_user_agent, /* WINHTTP_QUERY_USER_AGENT = 39 */
147 attr_www_authenticate, /* WINHTTP_QUERY_WWW_AUTHENTICATE = 40 */
148 attr_proxy_authenticate, /* WINHTTP_QUERY_PROXY_AUTHENTICATE = 41 */
149 attr_accept_ranges, /* WINHTTP_QUERY_ACCEPT_RANGES = 42 */
150 attr_set_cookie, /* WINHTTP_QUERY_SET_COOKIE = 43 */
151 attr_cookie, /* WINHTTP_QUERY_COOKIE = 44 */
152 NULL, /* WINHTTP_QUERY_REQUEST_METHOD = 45 */
153 NULL, /* WINHTTP_QUERY_REFRESH = 46 */
154 NULL, /* WINHTTP_QUERY_CONTENT_DISPOSITION = 47 */
155 attr_age, /* WINHTTP_QUERY_AGE = 48 */
156 attr_cache_control, /* WINHTTP_QUERY_CACHE_CONTROL = 49 */
157 attr_content_base, /* WINHTTP_QUERY_CONTENT_BASE = 50 */
158 attr_content_location, /* WINHTTP_QUERY_CONTENT_LOCATION = 51 */
159 attr_content_md5, /* WINHTTP_QUERY_CONTENT_MD5 = 52 */
160 attr_content_range, /* WINHTTP_QUERY_CONTENT_RANGE = 53 */
161 attr_etag, /* WINHTTP_QUERY_ETAG = 54 */
162 attr_host, /* WINHTTP_QUERY_HOST = 55 */
163 attr_if_match, /* WINHTTP_QUERY_IF_MATCH = 56 */
164 attr_if_none_match, /* WINHTTP_QUERY_IF_NONE_MATCH = 57 */
165 attr_if_range, /* WINHTTP_QUERY_IF_RANGE = 58 */
166 attr_if_unmodified_since, /* WINHTTP_QUERY_IF_UNMODIFIED_SINCE = 59 */
167 attr_max_forwards, /* WINHTTP_QUERY_MAX_FORWARDS = 60 */
168 attr_proxy_authorization, /* WINHTTP_QUERY_PROXY_AUTHORIZATION = 61 */
169 attr_range, /* WINHTTP_QUERY_RANGE = 62 */
170 attr_transfer_encoding, /* WINHTTP_QUERY_TRANSFER_ENCODING = 63 */
171 attr_upgrade, /* WINHTTP_QUERY_UPGRADE = 64 */
172 attr_vary, /* WINHTTP_QUERY_VARY = 65 */
173 attr_via, /* WINHTTP_QUERY_VIA = 66 */
174 attr_warning, /* WINHTTP_QUERY_WARNING = 67 */
175 attr_expect, /* WINHTTP_QUERY_EXPECT = 68 */
176 attr_proxy_connection, /* WINHTTP_QUERY_PROXY_CONNECTION = 69 */
177 attr_unless_modified_since, /* WINHTTP_QUERY_UNLESS_MODIFIED_SINCE = 70 */
178 NULL, /* WINHTTP_QUERY_PROXY_SUPPORT = 75 */
179 NULL, /* WINHTTP_QUERY_AUTHENTICATION_INFO = 76 */
180 NULL, /* WINHTTP_QUERY_PASSPORT_URLS = 77 */
181 NULL /* WINHTTP_QUERY_PASSPORT_CONFIG = 78 */
182};
183
184static struct task_header *dequeue_task( struct request *request )
185{
186 struct task_header *task;
187
189 TRACE("%u tasks queued\n", list_count( &request->task_queue ));
190 task = LIST_ENTRY( list_head( &request->task_queue ), struct task_header, entry );
191 if (task) list_remove( &task->entry );
193
194 TRACE("returning task %p\n", task);
195 return task;
196}
197
198#ifdef __REACTOS__
200#else
202#endif
203{
204#ifdef __REACTOS__
205 struct request *request = param;
206#else
207 struct request *request = ctx;
208#endif
209 HANDLE handles[2];
210
213 for (;;)
214 {
216 switch (err)
217 {
218 case WAIT_OBJECT_0:
219 {
220 struct task_header *task;
221 while ((task = dequeue_task( request )))
222 {
223 task->proc( task );
224 release_object( &task->request->hdr );
225 heap_free( task );
226 }
227 break;
228 }
229 case WAIT_OBJECT_0 + 1:
230 TRACE("exiting\n");
235 request->hdr.vtbl->destroy( &request->hdr );
236#ifdef __REACTOS__
237 return 0;
238#else
239 return;
240#endif
241
242 default:
243 ERR("wait failed %u (%u)\n", err, GetLastError());
244 break;
245 }
246 }
247#ifdef __REACTOS__
248 return 0;
249#endif
250}
251
252static BOOL queue_task( struct task_header *task )
253{
254 struct request *request = task->request;
255
256#ifdef __REACTOS__
257 if (!request->task_thread)
258#else
259 if (!request->task_wait)
260#endif
261 {
262 if (!(request->task_wait = CreateEventW( NULL, FALSE, FALSE, NULL ))) return FALSE;
264 {
267 return FALSE;
268 }
269#ifdef __REACTOS__
270 if (!(request->task_thread = CreateThread( NULL, 0, task_proc, request, 0, NULL )))
271#else
272 if (!TrySubmitThreadpoolCallback( task_proc, request, NULL ))
273#endif
274 {
279 return FALSE;
280 }
281#ifndef __REACTOS__
283#endif
285 request->task_cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": request.task_cs");
286 }
287
289 TRACE("queueing task %p\n", task );
292
294 return TRUE;
295}
296
297static void free_header( struct header *header )
298{
301 heap_free( header );
302}
303
305{
306 if (c < 32 || c == 127) return FALSE;
307 switch (c)
308 {
309 case '(': case ')':
310 case '<': case '>':
311 case '@': case ',':
312 case ';': case ':':
313 case '\\': case '\"':
314 case '/': case '[':
315 case ']': case '?':
316 case '=': case '{':
317 case '}': case ' ':
318 case '\t':
319 return FALSE;
320 default:
321 return TRUE;
322 }
323}
324
325static struct header *parse_header( const WCHAR *string )
326{
327 const WCHAR *p, *q;
328 struct header *header;
329 int len;
330
331 p = string;
332 if (!(q = strchrW( p, ':' )))
333 {
334 WARN("no ':' in line %s\n", debugstr_w(string));
335 return NULL;
336 }
337 if (q == string)
338 {
339 WARN("empty field name in line %s\n", debugstr_w(string));
340 return NULL;
341 }
342 while (*p != ':')
343 {
344 if (!valid_token_char( *p ))
345 {
346 WARN("invalid character in field name %s\n", debugstr_w(string));
347 return NULL;
348 }
349 p++;
350 }
351 len = q - string;
352 if (!(header = heap_alloc_zero( sizeof(struct header) ))) return NULL;
353 if (!(header->field = heap_alloc( (len + 1) * sizeof(WCHAR) )))
354 {
355 heap_free( header );
356 return NULL;
357 }
358 memcpy( header->field, string, len * sizeof(WCHAR) );
359 header->field[len] = 0;
360
361 q++; /* skip past colon */
362 while (*q == ' ') q++;
363 len = strlenW( q );
364
365 if (!(header->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
366 {
368 return NULL;
369 }
370 memcpy( header->value, q, len * sizeof(WCHAR) );
371 header->value[len] = 0;
372
373 return header;
374}
375
376static int get_header_index( struct request *request, const WCHAR *field, int requested_index, BOOL request_only )
377{
378 int index;
379
380 TRACE("%s\n", debugstr_w(field));
381
382 for (index = 0; index < request->num_headers; index++)
383 {
384 if (strcmpiW( request->headers[index].field, field )) continue;
385 if (request_only && !request->headers[index].is_request) continue;
386 if (!request_only && request->headers[index].is_request) continue;
387
388 if (!requested_index) break;
389 requested_index--;
390 }
391 if (index >= request->num_headers) index = -1;
392 TRACE("returning %d\n", index);
393 return index;
394}
395
396static BOOL insert_header( struct request *request, struct header *header )
397{
399 struct header *hdrs;
400
401 if (request->headers)
402 hdrs = heap_realloc_zero( request->headers, sizeof(struct header) * count );
403 else
404 hdrs = heap_alloc_zero( sizeof(struct header) );
405 if (!hdrs) return FALSE;
406
407 request->headers = hdrs;
408 request->headers[count - 1].field = strdupW( header->field );
409 request->headers[count - 1].value = strdupW( header->value );
410 request->headers[count - 1].is_request = header->is_request;
412 return TRUE;
413}
414
416{
417 if (!request->num_headers) return FALSE;
418 if (index >= request->num_headers) return FALSE;
420
421 heap_free( request->headers[index].field );
422 heap_free( request->headers[index].value );
423
425 (request->num_headers - index) * sizeof(struct header) );
426 memset( &request->headers[request->num_headers], 0, sizeof(struct header) );
427 return TRUE;
428}
429
430BOOL process_header( struct request *request, const WCHAR *field, const WCHAR *value, DWORD flags, BOOL request_only )
431{
432 int index;
433 struct header hdr;
434
435 TRACE("%s: %s 0x%08x\n", debugstr_w(field), debugstr_w(value), flags);
436
437 if ((index = get_header_index( request, field, 0, request_only )) >= 0)
438 {
440 }
441
443 {
444 if (index >= 0)
445 {
447 if (!value || !value[0]) return TRUE;
448 }
449 else if (!(flags & WINHTTP_ADDREQ_FLAG_ADD))
450 {
452 return FALSE;
453 }
454
455 hdr.field = (LPWSTR)field;
456 hdr.value = (LPWSTR)value;
457 hdr.is_request = request_only;
458 return insert_header( request, &hdr );
459 }
460 else if (value)
461 {
462
464 index >= 0)
465 {
466 WCHAR *tmp;
467 int len, len_orig, len_value;
468 struct header *header = &request->headers[index];
469
470 len_orig = strlenW( header->value );
471 len_value = strlenW( value );
472
473 len = len_orig + len_value + 2;
474 if (!(tmp = heap_realloc( header->value, (len + 1) * sizeof(WCHAR) ))) return FALSE;
475 header->value = tmp;
476 header->value[len_orig++] = (flags & WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA) ? ',' : ';';
477 header->value[len_orig++] = ' ';
478
479 memcpy( &header->value[len_orig], value, len_value * sizeof(WCHAR) );
480 header->value[len] = 0;
481 return TRUE;
482 }
483 else
484 {
485 hdr.field = (LPWSTR)field;
486 hdr.value = (LPWSTR)value;
487 hdr.is_request = request_only;
488 return insert_header( request, &hdr );
489 }
490 }
491
492 return TRUE;
493}
494
496{
497 BOOL ret = FALSE;
498 WCHAR *buffer, *p, *q;
499 struct header *header;
500
501 if (len == ~0u) len = strlenW( headers );
502 if (!len) return TRUE;
503 if (!(buffer = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
504 memcpy( buffer, headers, len * sizeof(WCHAR) );
505 buffer[len] = 0;
506
507 p = buffer;
508 do
509 {
510 q = p;
511 while (*q)
512 {
513 if (q[0] == '\n' && q[1] == '\r')
514 {
515 q[0] = '\r';
516 q[1] = '\n';
517 }
518 if (q[0] == '\r' && q[1] == '\n') break;
519 q++;
520 }
521 if (!*p) break;
522 if (*q == '\r')
523 {
524 *q = 0;
525 q += 2; /* jump over \r\n */
526 }
527 if ((header = parse_header( p )))
528 {
531 }
532 p = q;
533 } while (ret);
534
535 heap_free( buffer );
536 return ret;
537}
538
539/***********************************************************************
540 * WinHttpAddRequestHeaders (winhttp.@)
541 */
543{
544 BOOL ret;
545 struct request *request;
546
547 TRACE("%p, %s, %u, 0x%08x\n", hrequest, debugstr_wn(headers, len), len, flags);
548
549 if (!headers || !len)
550 {
552 return FALSE;
553 }
554 if (!(request = (struct request *)grab_object( hrequest )))
555 {
557 return FALSE;
558 }
560 {
563 return FALSE;
564 }
565
567
570 return ret;
571}
572
574{
575 static const WCHAR http[] = {'h','t','t','p',0};
576 static const WCHAR https[] = {'h','t','t','p','s',0};
577 static const WCHAR fmt[] = {'%','s',':','/','/','%','s',0};
578 const WCHAR *scheme;
579 WCHAR *ret;
580 int len;
581
582 scheme = (request->netconn ? request->netconn->secure : (request->hdr.flags & WINHTTP_FLAG_SECURE)) ? https : http;
583
584 len = strlenW( scheme ) + strlenW( request->connect->hostname ) + 4; /* '://' + nul */
585 if (request->connect->hostport) len += 6; /* ':' between host and port, up to 5 for port */
586
587 len += strlenW( request->path );
588 if ((ret = heap_alloc( len * sizeof(WCHAR) )))
589 {
590 len = sprintfW( ret, fmt, scheme, request->connect->hostname );
591 if (request->connect->hostport)
592 {
593 static const WCHAR port_fmt[] = {':','%','u',0};
594 len += sprintfW( ret + len, port_fmt, request->connect->hostport );
595 }
596 strcpyW( ret + len, request->path );
597 if (path) *path = ret + len;
598 }
599
600 return ret;
601}
602
604{
605 static const WCHAR spaceW[] = {' ',0}, crlfW[] = {'\r','\n',0}, colonW[] = {':',' ',0};
606 static const WCHAR twocrlfW[] = {'\r','\n','\r','\n',0};
607 WCHAR *path, *ret;
608 unsigned int i, len;
609
610 if (!strcmpiW( request->connect->hostname, request->connect->servername )) path = request->path;
611 else if (!(path = build_absolute_request_path( request, NULL ))) return NULL;
612
613 len = strlenW( request->verb ) + 1 /* ' ' */;
614 len += strlenW( path ) + 1 /* ' ' */;
615 len += strlenW( request->version );
616
617 for (i = 0; i < request->num_headers; i++)
618 {
619 if (request->headers[i].is_request)
620 len += strlenW( request->headers[i].field ) + strlenW( request->headers[i].value ) + 4; /* '\r\n: ' */
621 }
622 len += 4; /* '\r\n\r\n' */
623
624 if ((ret = heap_alloc( (len + 1) * sizeof(WCHAR) )))
625 {
626 strcpyW( ret, request->verb );
627 strcatW( ret, spaceW );
628 strcatW( ret, path );
629 strcatW( ret, spaceW );
631
632 for (i = 0; i < request->num_headers; i++)
633 {
634 if (request->headers[i].is_request)
635 {
636 strcatW( ret, crlfW );
637 strcatW( ret, request->headers[i].field );
638 strcatW( ret, colonW );
639 strcatW( ret, request->headers[i].value );
640 }
641 }
642 strcatW( ret, twocrlfW );
643 }
644
645 if (path != request->path) heap_free( path );
646 return ret;
647}
648
649#define QUERY_MODIFIER_MASK (WINHTTP_QUERY_FLAG_REQUEST_HEADERS | WINHTTP_QUERY_FLAG_SYSTEMTIME | WINHTTP_QUERY_FLAG_NUMBER)
650
651static BOOL query_headers( struct request *request, DWORD level, const WCHAR *name, void *buffer, DWORD *buflen,
652 DWORD *index )
653{
654 struct header *header = NULL;
655 BOOL request_only, ret = FALSE;
656 int requested_index, header_index = -1;
657 DWORD attr, len;
658
660 requested_index = index ? *index : 0;
661
662 attr = level & ~QUERY_MODIFIER_MASK;
663 switch (attr)
664 {
666 {
667 header_index = get_header_index( request, name, requested_index, request_only );
668 break;
669 }
671 {
672 WCHAR *headers, *p, *q;
673
674 if (request_only)
676 else
678
679 if (!(p = headers)) return FALSE;
680 for (len = 0; *p; p++) if (*p != '\r') len++;
681
682 if (!buffer || len * sizeof(WCHAR) > *buflen)
684 else
685 {
686 for (p = headers, q = buffer; *p; p++, q++)
687 {
688 if (*p != '\r') *q = *p;
689 else
690 {
691 *q = 0;
692 p++; /* skip '\n' */
693 }
694 }
695 TRACE("returning data: %s\n", debugstr_wn(buffer, len));
696 if (len) len--;
697 ret = TRUE;
698 }
699 *buflen = len * sizeof(WCHAR);
700 if (request_only) heap_free( headers );
701 return ret;
702 }
704 {
705 WCHAR *headers;
706
707 if (request_only)
709 else
711
712 if (!headers) return FALSE;
713 len = strlenW( headers ) * sizeof(WCHAR);
714 if (!buffer || len + sizeof(WCHAR) > *buflen)
715 {
716 len += sizeof(WCHAR);
718 }
719 else
720 {
721 memcpy( buffer, headers, len + sizeof(WCHAR) );
722 TRACE("returning data: %s\n", debugstr_wn(buffer, len / sizeof(WCHAR)));
723 ret = TRUE;
724 }
725 *buflen = len;
726 if (request_only) heap_free( headers );
727 return ret;
728 }
730 len = strlenW( request->version ) * sizeof(WCHAR);
731 if (!buffer || len + sizeof(WCHAR) > *buflen)
732 {
733 len += sizeof(WCHAR);
735 }
736 else
737 {
739 TRACE("returning string: %s\n", debugstr_w(buffer));
740 ret = TRUE;
741 }
742 *buflen = len;
743 return ret;
744
746 len = strlenW( request->status_text ) * sizeof(WCHAR);
747 if (!buffer || len + sizeof(WCHAR) > *buflen)
748 {
749 len += sizeof(WCHAR);
751 }
752 else
753 {
755 TRACE("returning string: %s\n", debugstr_w(buffer));
756 ret = TRUE;
757 }
758 *buflen = len;
759 return ret;
760
762 len = strlenW( request->verb ) * sizeof(WCHAR);
763 if (!buffer || len + sizeof(WCHAR) > *buflen)
764 {
765 len += sizeof(WCHAR);
767 }
768 else
769 {
771 TRACE("returning string: %s\n", debugstr_w(buffer));
772 ret = TRUE;
773 }
774 *buflen = len;
775 return ret;
776
777 default:
779 {
781 return FALSE;
782 }
783 if (!attribute_table[attr])
784 {
785 FIXME("attribute %u not implemented\n", attr);
787 return FALSE;
788 }
789 TRACE("attribute %s\n", debugstr_w(attribute_table[attr]));
790 header_index = get_header_index( request, attribute_table[attr], requested_index, request_only );
791 break;
792 }
793
794 if (header_index >= 0)
795 {
796 header = &request->headers[header_index];
797 }
798 if (!header || (request_only && !header->is_request))
799 {
801 return FALSE;
802 }
804 {
805 if (!buffer || sizeof(int) > *buflen)
806 {
808 }
809 else
810 {
811 int *number = buffer;
812 *number = atoiW( header->value );
813 TRACE("returning number: %d\n", *number);
814 ret = TRUE;
815 }
816 *buflen = sizeof(int);
817 }
819 {
820 SYSTEMTIME *st = buffer;
821 if (!buffer || sizeof(SYSTEMTIME) > *buflen)
822 {
824 }
825 else if ((ret = WinHttpTimeToSystemTime( header->value, st )))
826 {
827 TRACE("returning time: %04d/%02d/%02d - %d - %02d:%02d:%02d.%02d\n",
828 st->wYear, st->wMonth, st->wDay, st->wDayOfWeek,
829 st->wHour, st->wMinute, st->wSecond, st->wMilliseconds);
830 }
831 *buflen = sizeof(SYSTEMTIME);
832 }
833 else if (header->value)
834 {
835 len = strlenW( header->value ) * sizeof(WCHAR);
836 if (!buffer || len + sizeof(WCHAR) > *buflen)
837 {
838 len += sizeof(WCHAR);
840 }
841 else
842 {
844 TRACE("returning string: %s\n", debugstr_w(buffer));
845 ret = TRUE;
846 }
847 *buflen = len;
848 }
849 if (ret && index) *index += 1;
850 return ret;
851}
852
853/***********************************************************************
854 * WinHttpQueryHeaders (winhttp.@)
855 */
857{
858 BOOL ret;
859 struct request *request;
860
861 TRACE("%p, 0x%08x, %s, %p, %p, %p\n", hrequest, level, debugstr_w(name), buffer, buflen, index);
862
863 if (!(request = (struct request *)grab_object( hrequest )))
864 {
866 return FALSE;
867 }
869 {
872 return FALSE;
873 }
874
875 ret = query_headers( request, level, name, buffer, buflen, index );
876
879 return ret;
880}
881
882static const WCHAR basicW[] = {'B','a','s','i','c',0};
883static const WCHAR ntlmW[] = {'N','T','L','M',0};
884static const WCHAR passportW[] = {'P','a','s','s','p','o','r','t',0};
885static const WCHAR digestW[] = {'D','i','g','e','s','t',0};
886static const WCHAR negotiateW[] = {'N','e','g','o','t','i','a','t','e',0};
887
888static const struct
889{
890 const WCHAR *str;
891 unsigned int len;
893}
894auth_schemes[] =
895{
902
904{
905 int i;
906
907 for (i = 0; i < ARRAY_SIZE( auth_schemes ); i++) if (flag == auth_schemes[i].scheme) return i;
908 return SCHEME_INVALID;
909}
910
912{
913 unsigned int i;
914
915 for (i = 0; i < ARRAY_SIZE( auth_schemes ); i++)
916 {
918 (header[auth_schemes[i].len] == ' ' || !header[auth_schemes[i].len])) return auth_schemes[i].scheme;
919 }
920 return 0;
921}
922
924{
925 DWORD index = 0, supported_schemes = 0, first_scheme = 0;
926 BOOL ret = FALSE;
927
928 for (;;)
929 {
930 WCHAR *buffer;
932
933 size = 0;
936
937 if (!(buffer = heap_alloc( size ))) return FALSE;
939 {
940 heap_free( buffer );
941 return FALSE;
942 }
944 heap_free( buffer );
945 if (!scheme) continue;
946
947 if (!first_scheme) first_scheme = scheme;
948 supported_schemes |= scheme;
949
950 ret = TRUE;
951 }
952
953 if (ret)
954 {
955 *supported = supported_schemes;
956 *first = first_scheme;
957 }
958 return ret;
959}
960
961/***********************************************************************
962 * WinHttpQueryAuthSchemes (winhttp.@)
963 */
965{
966 BOOL ret = FALSE;
967 struct request *request;
968
969 TRACE("%p, %p, %p, %p\n", hrequest, supported, first, target);
970
971 if (!(request = (struct request *)grab_object( hrequest )))
972 {
974 return FALSE;
975 }
977 {
980 return FALSE;
981 }
982 if (!supported || !first || !target)
983 {
986 return FALSE;
987
988 }
989
991 {
993 ret = TRUE;
994 }
996 {
998 ret = TRUE;
999 }
1001
1004 return ret;
1005}
1006
1007static UINT encode_base64( const char *bin, unsigned int len, WCHAR *base64 )
1008{
1009 UINT n = 0, x;
1010 static const char base64enc[] =
1011 "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
1012
1013 while (len > 0)
1014 {
1015 /* first 6 bits, all from bin[0] */
1016 base64[n++] = base64enc[(bin[0] & 0xfc) >> 2];
1017 x = (bin[0] & 3) << 4;
1018
1019 /* next 6 bits, 2 from bin[0] and 4 from bin[1] */
1020 if (len == 1)
1021 {
1022 base64[n++] = base64enc[x];
1023 base64[n++] = '=';
1024 base64[n++] = '=';
1025 break;
1026 }
1027 base64[n++] = base64enc[x | ((bin[1] & 0xf0) >> 4)];
1028 x = (bin[1] & 0x0f) << 2;
1029
1030 /* next 6 bits 4 from bin[1] and 2 from bin[2] */
1031 if (len == 2)
1032 {
1033 base64[n++] = base64enc[x];
1034 base64[n++] = '=';
1035 break;
1036 }
1037 base64[n++] = base64enc[x | ((bin[2] & 0xc0) >> 6)];
1038
1039 /* last 6 bits, all from bin [2] */
1040 base64[n++] = base64enc[bin[2] & 0x3f];
1041 bin += 3;
1042 len -= 3;
1043 }
1044 base64[n] = 0;
1045 return n;
1046}
1047
1048static inline char decode_char( WCHAR c )
1049{
1050 if (c >= 'A' && c <= 'Z') return c - 'A';
1051 if (c >= 'a' && c <= 'z') return c - 'a' + 26;
1052 if (c >= '0' && c <= '9') return c - '0' + 52;
1053 if (c == '+') return 62;
1054 if (c == '/') return 63;
1055 return 64;
1056}
1057
1058static unsigned int decode_base64( const WCHAR *base64, unsigned int len, char *buf )
1059{
1060 unsigned int i = 0;
1061 char c0, c1, c2, c3;
1062 const WCHAR *p = base64;
1063
1064 while (len > 4)
1065 {
1066 if ((c0 = decode_char( p[0] )) > 63) return 0;
1067 if ((c1 = decode_char( p[1] )) > 63) return 0;
1068 if ((c2 = decode_char( p[2] )) > 63) return 0;
1069 if ((c3 = decode_char( p[3] )) > 63) return 0;
1070
1071 if (buf)
1072 {
1073 buf[i + 0] = (c0 << 2) | (c1 >> 4);
1074 buf[i + 1] = (c1 << 4) | (c2 >> 2);
1075 buf[i + 2] = (c2 << 6) | c3;
1076 }
1077 len -= 4;
1078 i += 3;
1079 p += 4;
1080 }
1081 if (p[2] == '=')
1082 {
1083 if ((c0 = decode_char( p[0] )) > 63) return 0;
1084 if ((c1 = decode_char( p[1] )) > 63) return 0;
1085
1086 if (buf) buf[i] = (c0 << 2) | (c1 >> 4);
1087 i++;
1088 }
1089 else if (p[3] == '=')
1090 {
1091 if ((c0 = decode_char( p[0] )) > 63) return 0;
1092 if ((c1 = decode_char( p[1] )) > 63) return 0;
1093 if ((c2 = decode_char( p[2] )) > 63) return 0;
1094
1095 if (buf)
1096 {
1097 buf[i + 0] = (c0 << 2) | (c1 >> 4);
1098 buf[i + 1] = (c1 << 4) | (c2 >> 2);
1099 }
1100 i += 2;
1101 }
1102 else
1103 {
1104 if ((c0 = decode_char( p[0] )) > 63) return 0;
1105 if ((c1 = decode_char( p[1] )) > 63) return 0;
1106 if ((c2 = decode_char( p[2] )) > 63) return 0;
1107 if ((c3 = decode_char( p[3] )) > 63) return 0;
1108
1109 if (buf)
1110 {
1111 buf[i + 0] = (c0 << 2) | (c1 >> 4);
1112 buf[i + 1] = (c1 << 4) | (c2 >> 2);
1113 buf[i + 2] = (c2 << 6) | c3;
1114 }
1115 i += 3;
1116 }
1117 return i;
1118}
1119
1120static struct authinfo *alloc_authinfo(void)
1121{
1122 struct authinfo *ret;
1123
1124 if (!(ret = heap_alloc( sizeof(*ret) ))) return NULL;
1125
1126 SecInvalidateHandle( &ret->cred );
1127 SecInvalidateHandle( &ret->ctx );
1128 memset( &ret->exp, 0, sizeof(ret->exp) );
1129 ret->scheme = 0;
1130 ret->attr = 0;
1131 ret->max_token = 0;
1132 ret->data = NULL;
1133 ret->data_len = 0;
1134 ret->finished = FALSE;
1135 return ret;
1136}
1137
1139{
1140 if (!authinfo) return;
1141
1142 if (SecIsValidHandle( &authinfo->ctx ))
1146
1149}
1150
1152{
1153 DWORD size, index = 0;
1154 for (;;)
1155 {
1156 size = len;
1157 if (!query_headers( request, level, NULL, buffer, &size, &index )) return FALSE;
1158 if (auth_scheme_from_header( buffer ) == scheme) break;
1159 }
1160 return TRUE;
1161}
1162
1163static BOOL do_authorization( struct request *request, DWORD target, DWORD scheme_flag )
1164{
1165 struct authinfo *authinfo, **auth_ptr;
1166 enum auth_scheme scheme = scheme_from_flag( scheme_flag );
1168 WCHAR auth_value[2048], *auth_reply;
1169 DWORD len = sizeof(auth_value), len_scheme, flags;
1170 BOOL ret, has_auth_value;
1171
1172 if (scheme == SCHEME_INVALID) return FALSE;
1173
1174 switch (target)
1175 {
1177 has_auth_value = get_authvalue( request, WINHTTP_QUERY_WWW_AUTHENTICATE, scheme_flag, auth_value, len );
1178 auth_ptr = &request->authinfo;
1180 if (request->creds[TARGET_SERVER][scheme].username)
1181 {
1182 if (scheme != SCHEME_BASIC && !has_auth_value) return FALSE;
1185 }
1186 else
1187 {
1188 if (!has_auth_value) return FALSE;
1189 username = request->connect->username;
1190 password = request->connect->password;
1191 }
1192 break;
1193
1195 if (!get_authvalue( request, WINHTTP_QUERY_PROXY_AUTHENTICATE, scheme_flag, auth_value, len ))
1196 return FALSE;
1197 auth_ptr = &request->proxy_authinfo;
1199 if (request->creds[TARGET_PROXY][scheme].username)
1200 {
1203 }
1204 else
1205 {
1206 username = request->connect->session->proxy_username;
1207 password = request->connect->session->proxy_password;
1208 }
1209 break;
1210
1211 default:
1212 WARN("unknown target %x\n", target);
1213 return FALSE;
1214 }
1215 authinfo = *auth_ptr;
1216
1217 switch (scheme)
1218 {
1219 case SCHEME_BASIC:
1220 {
1221 int userlen, passlen;
1222
1223 if (!username || !password) return FALSE;
1224 if ((!authinfo && !(authinfo = alloc_authinfo())) || authinfo->finished) return FALSE;
1225
1226 userlen = WideCharToMultiByte( CP_UTF8, 0, username, strlenW( username ), NULL, 0, NULL, NULL );
1227 passlen = WideCharToMultiByte( CP_UTF8, 0, password, strlenW( password ), NULL, 0, NULL, NULL );
1228
1229 authinfo->data_len = userlen + 1 + passlen;
1230 if (!(authinfo->data = heap_alloc( authinfo->data_len ))) return FALSE;
1231
1232 WideCharToMultiByte( CP_UTF8, 0, username, -1, authinfo->data, userlen, NULL, NULL );
1233 authinfo->data[userlen] = ':';
1234 WideCharToMultiByte( CP_UTF8, 0, password, -1, authinfo->data + userlen + 1, passlen, NULL, NULL );
1235
1238 break;
1239 }
1240 case SCHEME_NTLM:
1241 case SCHEME_NEGOTIATE:
1242 {
1244 SecBufferDesc out_desc, in_desc;
1245 SecBuffer out, in;
1247 const WCHAR *p;
1248 BOOL first = FALSE;
1249
1250 if (!authinfo)
1251 {
1252 TimeStamp exp;
1254 WCHAR *domain, *user;
1255
1256 if (!username || !password || !(authinfo = alloc_authinfo())) return FALSE;
1257
1258 first = TRUE;
1259 domain = (WCHAR *)username;
1260 user = strchrW( username, '\\' );
1261
1262 if (user) user++;
1263 else
1264 {
1265 user = (WCHAR *)username;
1266 domain = NULL;
1267 }
1269 id.User = user;
1270 id.UserLength = strlenW( user );
1271 id.Domain = domain;
1272 id.DomainLength = domain ? user - domain - 1 : 0;
1273 id.Password = (WCHAR *)password;
1274 id.PasswordLength = strlenW( password );
1275
1278 &authinfo->cred, &exp );
1279 if (status == SEC_E_OK)
1280 {
1283 if (status == SEC_E_OK)
1284 {
1285 authinfo->max_token = info->cbMaxToken;
1287 }
1288 }
1289 if (status != SEC_E_OK)
1290 {
1291 WARN("AcquireCredentialsHandleW for scheme %s failed with error 0x%08x\n",
1294 return FALSE;
1295 }
1297 }
1298 else if (authinfo->finished) return FALSE;
1299
1300 if ((strlenW( auth_value ) < auth_schemes[authinfo->scheme].len ||
1301 strncmpiW( auth_value, auth_schemes[authinfo->scheme].str, auth_schemes[authinfo->scheme].len )))
1302 {
1303 ERR("authentication scheme changed from %s to %s\n",
1304 debugstr_w(auth_schemes[authinfo->scheme].str), debugstr_w(auth_value));
1306 *auth_ptr = NULL;
1307 return FALSE;
1308 }
1309 in.BufferType = SECBUFFER_TOKEN;
1310 in.cbBuffer = 0;
1311 in.pvBuffer = NULL;
1312
1313 in_desc.ulVersion = 0;
1314 in_desc.cBuffers = 1;
1315 in_desc.pBuffers = &in;
1316
1317 p = auth_value + auth_schemes[scheme].len;
1318 if (*p == ' ')
1319 {
1320 int len = strlenW( ++p );
1321 in.cbBuffer = decode_base64( p, len, NULL );
1322 if (!(in.pvBuffer = heap_alloc( in.cbBuffer ))) {
1324 *auth_ptr = NULL;
1325 return FALSE;
1326 }
1327 decode_base64( p, len, in.pvBuffer );
1328 }
1329 out.BufferType = SECBUFFER_TOKEN;
1330 out.cbBuffer = authinfo->max_token;
1331 if (!(out.pvBuffer = heap_alloc( authinfo->max_token )))
1332 {
1333 heap_free( in.pvBuffer );
1335 *auth_ptr = NULL;
1336 return FALSE;
1337 }
1338 out_desc.ulVersion = 0;
1339 out_desc.cBuffers = 1;
1340 out_desc.pBuffers = &out;
1341
1343 first ? request->connect->servername : NULL, flags, 0,
1344 SECURITY_NETWORK_DREP, in.pvBuffer ? &in_desc : NULL, 0,
1345 &authinfo->ctx, &out_desc, &authinfo->attr, &authinfo->exp );
1346 heap_free( in.pvBuffer );
1347 if (status == SEC_E_OK)
1348 {
1350 authinfo->data = out.pvBuffer;
1351 authinfo->data_len = out.cbBuffer;
1353 TRACE("sending last auth packet\n");
1354 }
1355 else if (status == SEC_I_CONTINUE_NEEDED)
1356 {
1358 authinfo->data = out.pvBuffer;
1359 authinfo->data_len = out.cbBuffer;
1360 TRACE("sending next auth packet\n");
1361 }
1362 else
1363 {
1364 ERR("InitializeSecurityContextW failed with error 0x%08x\n", status);
1365 heap_free( out.pvBuffer );
1367 *auth_ptr = NULL;
1368 return FALSE;
1369 }
1370 break;
1371 }
1372 default:
1373 ERR("invalid scheme %u\n", scheme);
1374 return FALSE;
1375 }
1376 *auth_ptr = authinfo;
1377
1378 len_scheme = auth_schemes[authinfo->scheme].len;
1379 len = len_scheme + 1 + ((authinfo->data_len + 2) * 4) / 3;
1380 if (!(auth_reply = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
1381
1382 memcpy( auth_reply, auth_schemes[authinfo->scheme].str, len_scheme * sizeof(WCHAR) );
1383 auth_reply[len_scheme] = ' ';
1384 encode_base64( authinfo->data, authinfo->data_len, auth_reply + len_scheme + 1 );
1385
1387 ret = process_header( request, auth_target, auth_reply, flags, TRUE );
1388 heap_free( auth_reply );
1389 return ret;
1390}
1391
1393{
1394 static const WCHAR fmtW[] = {'%','s',':','%','u',0};
1395 static const WCHAR connectW[] = {'C','O','N','N','E','C','T', 0};
1396 static const WCHAR spaceW[] = {' ',0}, crlfW[] = {'\r','\n',0}, colonW[] = {':',' ',0};
1397 static const WCHAR twocrlfW[] = {'\r','\n','\r','\n',0};
1398 WCHAR *ret, *host;
1399 unsigned int i;
1400 int len;
1401
1402 if (!(host = heap_alloc( (strlenW( request->connect->hostname ) + 7) * sizeof(WCHAR) ))) return NULL;
1403 len = sprintfW( host, fmtW, request->connect->hostname, request->connect->hostport );
1404
1405 len += ARRAY_SIZE(connectW);
1407
1408 for (i = 0; i < request->num_headers; i++)
1409 {
1410 if (request->headers[i].is_request)
1411 len += strlenW( request->headers[i].field ) + strlenW( request->headers[i].value ) + 4; /* '\r\n: ' */
1412 }
1413 len += 4; /* '\r\n\r\n' */
1414
1415 if ((ret = heap_alloc( (len + 1) * sizeof(WCHAR) )))
1416 {
1417 strcpyW( ret, connectW );
1418 strcatW( ret, spaceW );
1419 strcatW( ret, host );
1420 strcatW( ret, spaceW );
1421 strcatW( ret, http1_1 );
1422
1423 for (i = 0; i < request->num_headers; i++)
1424 {
1425 if (request->headers[i].is_request)
1426 {
1427 strcatW( ret, crlfW );
1428 strcatW( ret, request->headers[i].field );
1429 strcatW( ret, colonW );
1430 strcatW( ret, request->headers[i].value );
1431 }
1432 }
1433 strcatW( ret, twocrlfW );
1434 }
1435
1436 heap_free( host );
1437 return ret;
1438}
1439
1440static BOOL read_reply( struct request *request );
1441
1443{
1444 WCHAR *str;
1445 char *strA;
1446 int len, bytes_sent;
1447 BOOL ret;
1448
1449 if (!(str = build_proxy_connect_string( request ))) return FALSE;
1450 strA = strdupWA( str );
1451 heap_free( str );
1452 if (!strA) return FALSE;
1453
1454 len = strlen( strA );
1455 ret = netconn_send( request->netconn, strA, len, &bytes_sent );
1456 heap_free( strA );
1457 if (ret) ret = read_reply( request );
1458
1459 return ret;
1460}
1461
1463{
1464 char buf[INET6_ADDRSTRLEN];
1465 void *src;
1466
1467 switch (addr->ss_family)
1468 {
1469 case AF_INET:
1470 src = &((struct sockaddr_in *)addr)->sin_addr;
1471 break;
1472 case AF_INET6:
1473 src = &((struct sockaddr_in6 *)addr)->sin6_addr;
1474 break;
1475 default:
1476 WARN("unsupported address family %d\n", addr->ss_family);
1477 return NULL;
1478 }
1479 if (!inet_ntop( addr->ss_family, src, buf, sizeof(buf) )) return NULL;
1480 return strdupAW( buf );
1481}
1482
1485{
1486 0, 0, &connection_pool_cs,
1488 0, 0, { (DWORD_PTR)(__FILE__ ": connection_pool_cs") }
1489};
1490static CRITICAL_SECTION connection_pool_cs = { &connection_pool_debug, -1, 0, 0, 0, 0 };
1491
1493
1495{
1496 LONG ref;
1497
1499 if (!(ref = --host->ref)) list_remove( &host->entry );
1501 if (ref) return;
1502
1503 assert( list_empty( &host->connections ) );
1504 heap_free( host->hostname );
1505 heap_free( host );
1506}
1507
1509
1510#ifdef __REACTOS__
1512#else
1514#endif
1515{
1516 unsigned int remaining_connections;
1517 struct netconn *netconn, *next_netconn;
1518 struct hostdata *host, *next_host;
1519 ULONGLONG now;
1520
1521 do
1522 {
1523 /* FIXME: Use more sophisticated method */
1524 Sleep(5000);
1525 remaining_connections = 0;
1526 now = GetTickCount64();
1527
1529
1531 {
1532 LIST_FOR_EACH_ENTRY_SAFE(netconn, next_netconn, &host->connections, struct netconn, entry)
1533 {
1534 if (netconn->keep_until < now)
1535 {
1536 TRACE("freeing %p\n", netconn);
1539 }
1540 else remaining_connections++;
1541 }
1542 }
1543
1544 if (!remaining_connections) connection_collector_running = FALSE;
1545
1547 } while(remaining_connections);
1548
1549#ifdef __REACTOS__
1551#else
1552 FreeLibraryWhenCallbackReturns( instance, winhttp_instance );
1553#endif
1554}
1555
1556static void cache_connection( struct netconn *netconn )
1557{
1558 TRACE( "caching connection %p\n", netconn );
1559
1561
1563 list_add_head( &netconn->host->connections, &netconn->entry );
1564
1566 {
1568#ifdef __REACTOS__
1569 HANDLE thread;
1570#endif
1571
1572 GetModuleHandleExW( GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (const WCHAR *)winhttp_instance, &module );
1573
1574#ifdef __REACTOS__
1576 if (thread)
1577 {
1580 }
1581 else
1582 {
1584 }
1585#else
1586 if (TrySubmitThreadpoolCallback( connection_collector, NULL, NULL )) connection_collector_running = TRUE;
1588#endif
1589 }
1590
1592}
1593
1595{
1596 DWORD ret = 0;
1602 return ret;
1603}
1604
1606{
1608
1610
1612 {
1613 SCHANNEL_CRED cred;
1614 memset( &cred, 0, sizeof(cred) );
1616 cred.grbitEnabledProtocols = map_secure_protocols( request->connect->session->secure_protocols );
1617 if (request->client_cert)
1618 {
1619 cred.paCred = &request->client_cert;
1620 cred.cCreds = 1;
1621 }
1623 &cred, NULL, NULL, &request->cred_handle, NULL );
1624 if (status == SEC_E_OK)
1626 }
1627
1628 if (status != SEC_E_OK)
1629 {
1630 WARN( "AcquireCredentialsHandleW failed: 0x%08x\n", status );
1631 return FALSE;
1632 }
1633 return TRUE;
1634}
1635
1637{
1639 struct hostdata *host = NULL, *iter;
1640 struct netconn *netconn = NULL;
1641 struct connect *connect;
1642 WCHAR *addressW = NULL;
1644 DWORD len;
1645
1646 if (request->netconn) goto done;
1647
1650
1652
1654 {
1655 if (iter->port == port && !strcmpW( connect->servername, iter->hostname ) && !is_secure == !iter->secure)
1656 {
1657 host = iter;
1658 host->ref++;
1659 break;
1660 }
1661 }
1662
1663 if (!host)
1664 {
1665 if ((host = heap_alloc( sizeof(*host) )))
1666 {
1667 host->ref = 1;
1668 host->secure = is_secure;
1669 host->port = port;
1670 list_init( &host->connections );
1671 if ((host->hostname = strdupW( connect->servername )))
1672 {
1673 list_add_head( &connection_pool, &host->entry );
1674 }
1675 else
1676 {
1677 heap_free( host );
1678 host = NULL;
1679 }
1680 }
1681 }
1682
1684
1685 if (!host) return FALSE;
1686
1687 for (;;)
1688 {
1690 if (!list_empty( &host->connections ))
1691 {
1692 netconn = LIST_ENTRY( list_head( &host->connections ), struct netconn, entry );
1694 }
1696 if (!netconn) break;
1697
1698 if (netconn_is_alive( netconn )) break;
1699 TRACE("connection %p no longer alive, closing\n", netconn);
1701 netconn = NULL;
1702 }
1703
1704 if (!connect->resolved && netconn)
1705 {
1708 }
1709
1710 if (!connect->resolved)
1711 {
1712 len = strlenW( host->hostname ) + 1;
1714
1716 {
1717 release_host( host );
1718 return FALSE;
1719 }
1721
1722 if (!(addressW = addr_to_str( &connect->sockaddr )))
1723 {
1724 release_host( host );
1725 return FALSE;
1726 }
1727 len = strlenW( addressW ) + 1;
1729 }
1730
1731 if (!netconn)
1732 {
1733 if (!addressW && !(addressW = addr_to_str( &connect->sockaddr )))
1734 {
1735 release_host( host );
1736 return FALSE;
1737 }
1738
1739 TRACE("connecting to %s:%u\n", debugstr_w(addressW), port);
1740
1742
1744 {
1745 heap_free( addressW );
1746 release_host( host );
1747 return FALSE;
1748 }
1751
1753
1754 if (is_secure)
1755 {
1756 if (connect->session->proxy_server &&
1758 {
1760 {
1761 request->netconn = NULL;
1762 heap_free( addressW );
1764 return FALSE;
1765 }
1766 }
1767
1770
1771 if (!ensure_cred_handle( request ) ||
1774 {
1775 request->netconn = NULL;
1776 heap_free( addressW );
1778 return FALSE;
1779 }
1780 }
1781
1783 }
1784 else
1785 {
1786 TRACE("using connection %p\n", netconn);
1787
1791 }
1792
1794 {
1795 heap_free( addressW );
1797 return FALSE;
1798 }
1799
1800done:
1805 heap_free( addressW );
1806 return TRUE;
1807}
1808
1810{
1811 if (!request->netconn) return;
1812
1815 request->netconn = NULL;
1817}
1818
1819static BOOL add_host_header( struct request *request, DWORD modifier )
1820{
1821 BOOL ret;
1822 DWORD len;
1823 WCHAR *host;
1824 static const WCHAR fmt[] = {'%','s',':','%','u',0};
1825 struct connect *connect = request->connect;
1827
1828 port = connect->hostport ? connect->hostport : (request->hdr.flags & WINHTTP_FLAG_SECURE ? 443 : 80);
1829
1831 {
1832 return process_header( request, attr_host, connect->hostname, modifier, TRUE );
1833 }
1834 len = strlenW( connect->hostname ) + 7; /* sizeof(":65335") */
1835 if (!(host = heap_alloc( len * sizeof(WCHAR) ))) return FALSE;
1837 ret = process_header( request, attr_host, host, modifier, TRUE );
1838 heap_free( host );
1839 return ret;
1840}
1841
1843{
1844 unsigned int i;
1845
1846 for (i = 0; i < request->num_headers; i++)
1847 {
1848 if (!request->headers[i].field) continue;
1849 if (!request->headers[i].value) continue;
1850 if (request->headers[i].is_request) continue;
1852 i--;
1853 }
1854}
1855
1856/* remove some amount of data from the read buffer */
1857static void remove_data( struct request *request, int count )
1858{
1859 if (!(request->read_size -= count)) request->read_pos = 0;
1860 else request->read_pos += count;
1861}
1862
1863/* read some more data into the read buffer */
1864static BOOL read_more_data( struct request *request, int maxlen, BOOL notify )
1865{
1866 int len;
1867 BOOL ret;
1868
1869 if (request->read_chunked_eof) return FALSE;
1870
1872 {
1873 /* move existing data to the start of the buffer */
1875 request->read_pos = 0;
1876 }
1877 if (maxlen == -1) maxlen = sizeof(request->read_buf);
1878
1880
1882 maxlen - request->read_size, 0, &len );
1883
1885
1886 request->read_size += len;
1887 return ret;
1888}
1889
1890/* discard data contents until we reach end of line */
1892{
1893 do
1894 {
1895 char *eol = memchr( request->read_buf + request->read_pos, '\n', request->read_size );
1896 if (eol)
1897 {
1898 remove_data( request, (eol + 1) - (request->read_buf + request->read_pos) );
1899 break;
1900 }
1901 request->read_pos = request->read_size = 0; /* discard everything */
1902 if (!read_more_data( request, -1, notify )) return FALSE;
1903 } while (request->read_size);
1904 return TRUE;
1905}
1906
1907/* read the size of the next chunk */
1909{
1910 DWORD chunk_size = 0;
1911
1913
1914 if (request->read_chunked_eof) return FALSE;
1915
1916 /* read terminator for the previous chunk */
1918
1919 for (;;)
1920 {
1921 while (request->read_size)
1922 {
1923 char ch = request->read_buf[request->read_pos];
1924 if (ch >= '0' && ch <= '9') chunk_size = chunk_size * 16 + ch - '0';
1925 else if (ch >= 'a' && ch <= 'f') chunk_size = chunk_size * 16 + ch - 'a' + 10;
1926 else if (ch >= 'A' && ch <= 'F') chunk_size = chunk_size * 16 + ch - 'A' + 10;
1927 else if (ch == ';' || ch == '\r' || ch == '\n')
1928 {
1929 TRACE("reading %u byte chunk\n", chunk_size);
1930
1931 if (request->content_length == ~0u) request->content_length = chunk_size;
1932 else request->content_length += chunk_size;
1933
1934 request->read_chunked_size = chunk_size;
1935 if (!chunk_size) request->read_chunked_eof = TRUE;
1936
1937 return discard_eol( request, notify );
1938 }
1939 remove_data( request, 1 );
1940 }
1941 if (!read_more_data( request, -1, notify )) return FALSE;
1942 if (!request->read_size)
1943 {
1946 return TRUE;
1947 }
1948 }
1949}
1950
1952{
1953 int len = sizeof(request->read_buf);
1954
1955 if (request->read_chunked)
1956 {
1957 if (request->read_chunked_eof) return FALSE;
1959 {
1960 if (!start_next_chunk( request, notify )) return FALSE;
1961 }
1963 }
1964 else if (request->content_length != ~0u)
1965 {
1967 }
1968
1969 if (len <= request->read_size) return TRUE;
1970 if (!read_more_data( request, len, notify )) return FALSE;
1972 return TRUE;
1973}
1974
1975static void finished_reading( struct request *request )
1976{
1977 static const WCHAR closeW[] = {'c','l','o','s','e',0};
1978
1979 BOOL close = FALSE;
1980 WCHAR connection[20];
1981 DWORD size = sizeof(connection);
1982
1983 if (!request->netconn) return;
1984
1985 if (request->hdr.disable_flags & WINHTTP_DISABLE_KEEP_ALIVE) close = TRUE;
1986 else if (query_headers( request, WINHTTP_QUERY_CONNECTION, NULL, connection, &size, NULL ) ||
1988 {
1989 if (!strcmpiW( connection, closeW )) close = TRUE;
1990 }
1991 else if (!strcmpW( request->version, http1_0 )) close = TRUE;
1992 if (close)
1993 {
1995 return;
1996 }
1997
1999 request->netconn = NULL;
2000}
2001
2002/* return the size of data available to be read immediately */
2004{
2006 return request->read_size;
2007}
2008
2009/* check if we have reached the end of the data to read */
2011{
2012 if (!request->content_length) return TRUE;
2014 if (request->content_length == ~0u) return FALSE;
2016}
2017
2018static BOOL read_data( struct request *request, void *buffer, DWORD size, DWORD *read, BOOL async )
2019{
2020 int count, bytes_read = 0;
2021 BOOL ret = TRUE;
2022
2023 if (end_of_read_data( request )) goto done;
2024
2025 while (size)
2026 {
2027 if (!(count = get_available_data( request )))
2028 {
2029 if (!(ret = refill_buffer( request, async ))) goto done;
2030 if (!(count = get_available_data( request ))) goto done;
2031 }
2032 count = min( count, size );
2033 memcpy( (char *)buffer + bytes_read, request->read_buf + request->read_pos, count );
2036 size -= count;
2037 bytes_read += count;
2039 if (end_of_read_data( request )) goto done;
2040 }
2042
2043done:
2044 TRACE( "retrieved %u bytes (%u/%u)\n", bytes_read, request->content_read, request->content_length );
2045 if (async)
2046 {
2048 else
2049 {
2051 result.dwResult = API_READ_DATA;
2052 result.dwError = GetLastError();
2054 }
2055 }
2056
2057 if (ret && read) *read = bytes_read;
2059 return ret;
2060}
2061
2062/* read any content returned by the server so that the connection can be reused */
2063static void drain_content( struct request *request )
2064{
2065 DWORD size, bytes_read, bytes_total = 0, bytes_left = request->content_length - request->content_read;
2066 char buffer[2048];
2067
2069 for (;;)
2070 {
2071 if (request->read_chunked) size = sizeof(buffer);
2072 else
2073 {
2074 if (bytes_total >= bytes_left) return;
2075 size = min( sizeof(buffer), bytes_left - bytes_total );
2076 }
2077 if (!read_data( request, buffer, size, &bytes_read, FALSE ) || !bytes_read) return;
2078 bytes_total += bytes_read;
2079 }
2080}
2081
2083{
2091};
2092
2093#define ESCAPE_MASK_DEFAULT (ESCAPE_FLAG_NON_PRINTABLE | ESCAPE_FLAG_SPACE | ESCAPE_FLAG_UNSAFE |\
2094 ESCAPE_FLAG_DEL | ESCAPE_FLAG_8BIT)
2095#define ESCAPE_MASK_PERCENT (ESCAPE_FLAG_PERCENT | ESCAPE_MASK_DEFAULT)
2096#define ESCAPE_MASK_DISABLE (ESCAPE_FLAG_SPACE | ESCAPE_FLAG_8BIT | ESCAPE_FLAG_STRIP_CRLF)
2097
2098static inline BOOL need_escape( char ch, enum escape_flags flags )
2099{
2100 static const char unsafe[] = "\"#<>[\\]^`{|}";
2101 const char *ptr = unsafe;
2102
2103 if ((flags & ESCAPE_FLAG_SPACE) && ch == ' ') return TRUE;
2104 if ((flags & ESCAPE_FLAG_PERCENT) && ch == '%') return TRUE;
2105 if ((flags & ESCAPE_FLAG_NON_PRINTABLE) && ch < 0x20) return TRUE;
2106 if ((flags & ESCAPE_FLAG_DEL) && ch == 0x7f) return TRUE;
2107 if ((flags & ESCAPE_FLAG_8BIT) && (ch & 0x80)) return TRUE;
2108 if ((flags & ESCAPE_FLAG_UNSAFE)) while (*ptr) { if (ch == *ptr++) return TRUE; }
2109 return FALSE;
2110}
2111
2112static DWORD escape_string( const char *src, DWORD len, char *dst, enum escape_flags flags )
2113{
2114 static const char hex[] = "0123456789ABCDEF";
2115 DWORD i, ret = len;
2116 char *ptr = dst;
2117
2118 for (i = 0; i < len; i++)
2119 {
2120 if ((flags & ESCAPE_FLAG_STRIP_CRLF) && (src[i] == '\r' || src[i] == '\n'))
2121 {
2122 ret--;
2123 continue;
2124 }
2125 if (need_escape( src[i], flags ))
2126 {
2127 if (dst)
2128 {
2129 ptr[0] = '%';
2130 ptr[1] = hex[(src[i] >> 4) & 0xf];
2131 ptr[2] = hex[src[i] & 0xf];
2132 ptr += 3;
2133 }
2134 ret += 2;
2135 }
2136 else if (dst) *ptr++ = src[i];
2137 }
2138
2139 if (dst) dst[ret] = 0;
2140 return ret;
2141}
2142
2143static DWORD str_to_wire( const WCHAR *src, int src_len, char *dst, enum escape_flags flags )
2144{
2145 DWORD len;
2146 char *utf8;
2147
2148 if (src_len < 0) src_len = strlenW( src );
2149 len = WideCharToMultiByte( CP_UTF8, 0, src, src_len, NULL, 0, NULL, NULL );
2150 if (!(utf8 = heap_alloc( len ))) return 0;
2151
2152 WideCharToMultiByte( CP_UTF8, 0, src, -1, utf8, len, NULL, NULL );
2153 len = escape_string( utf8, len, dst, flags );
2154 heap_free( utf8 );
2155
2156 return len;
2157}
2158
2160{
2161 WCHAR *full_path;
2162 const WCHAR *start, *path, *query = NULL;
2163 DWORD len, len_path = 0, len_query = 0;
2164 enum escape_flags path_flags, query_flags;
2165 char *ret;
2166
2167 if (!strcmpiW( request->connect->hostname, request->connect->servername )) start = full_path = request->path;
2168 else if (!(full_path = build_absolute_request_path( request, &start ))) return NULL;
2169
2170 len = strlenW( full_path );
2171 if ((path = strchrW( start, '/' )))
2172 {
2173 len_path = strlenW( path );
2174 if ((query = strchrW( path, '?' )))
2175 {
2176 len_query = strlenW( query );
2177 len_path -= len_query;
2178 }
2179 }
2180
2182 else if (request->hdr.flags & WINHTTP_FLAG_ESCAPE_PERCENT) path_flags = ESCAPE_MASK_PERCENT;
2183 else path_flags = ESCAPE_MASK_DEFAULT;
2184
2186 else query_flags = path_flags;
2187
2188 *ret_len = str_to_wire( full_path, len - len_path - len_query, NULL, 0 );
2189 if (path) *ret_len += str_to_wire( path, len_path, NULL, path_flags );
2190 if (query) *ret_len += str_to_wire( query, len_query, NULL, query_flags );
2191
2192 if ((ret = heap_alloc( *ret_len + 1 )))
2193 {
2194 len = str_to_wire( full_path, len - len_path - len_query, ret, 0 );
2195 if (path) len += str_to_wire( path, len_path, ret + len, path_flags );
2196 if (query) str_to_wire( query, len_query, ret + len, query_flags );
2197 }
2198
2199 if (full_path != request->path) heap_free( full_path );
2200 return ret;
2201}
2202
2203static char *build_wire_request( struct request *request, DWORD *len )
2204{
2205 char *path, *ptr, *ret;
2206 DWORD i, len_path;
2207
2208 if (!(path = build_wire_path( request, &len_path ))) return NULL;
2209
2210 *len = str_to_wire( request->verb, -1, NULL, 0 ) + 1; /* ' ' */
2211 *len += len_path + 1; /* ' ' */
2212 *len += str_to_wire( request->version, -1, NULL, 0 );
2213
2214 for (i = 0; i < request->num_headers; i++)
2215 {
2216 if (request->headers[i].is_request)
2217 {
2218 *len += str_to_wire( request->headers[i].field, -1, NULL, 0 ) + 2; /* ': ' */
2219 *len += str_to_wire( request->headers[i].value, -1, NULL, 0 ) + 2; /* '\r\n' */
2220 }
2221 }
2222 *len += 4; /* '\r\n\r\n' */
2223
2224 if ((ret = ptr = heap_alloc( *len + 1 )))
2225 {
2226 ptr += str_to_wire( request->verb, -1, ptr, 0 );
2227 *ptr++ = ' ';
2228 memcpy( ptr, path, len_path );
2229 ptr += len_path;
2230 *ptr++ = ' ';
2231 ptr += str_to_wire( request->version, -1, ptr, 0 );
2232
2233 for (i = 0; i < request->num_headers; i++)
2234 {
2235 if (request->headers[i].is_request)
2236 {
2237 *ptr++ = '\r';
2238 *ptr++ = '\n';
2239 ptr += str_to_wire( request->headers[i].field, -1, ptr, 0 );
2240 *ptr++ = ':';
2241 *ptr++ = ' ';
2242 ptr += str_to_wire( request->headers[i].value, -1, ptr, 0 );
2243 }
2244 }
2245 memcpy( ptr, "\r\n\r\n", sizeof("\r\n\r\n") );
2246 }
2247
2248 heap_free( path );
2249 return ret;
2250}
2251
2252static BOOL send_request( struct request *request, const WCHAR *headers, DWORD headers_len, void *optional,
2253 DWORD optional_len, DWORD total_len, DWORD_PTR context, BOOL async )
2254{
2255 static const WCHAR keep_alive[] = {'K','e','e','p','-','A','l','i','v','e',0};
2256 static const WCHAR no_cache[] = {'n','o','-','c','a','c','h','e',0};
2257 static const WCHAR length_fmt[] = {'%','l','d',0};
2258
2259 BOOL ret = FALSE;
2260 struct connect *connect = request->connect;
2261 struct session *session = connect->session;
2262 char *wire_req;
2263 int bytes_sent;
2264 DWORD len;
2265
2268
2269 if (session->agent)
2271
2272 if (connect->hostname)
2274
2275 if (request->creds[TARGET_SERVER][SCHEME_BASIC].username)
2277
2278 if (total_len || (request->verb && !strcmpW( request->verb, postW )))
2279 {
2280 WCHAR length[21]; /* decimal long int + null */
2281 sprintfW( length, length_fmt, total_len );
2283 }
2284 if (!(request->hdr.disable_flags & WINHTTP_DISABLE_KEEP_ALIVE))
2285 {
2287 }
2288 if (request->hdr.flags & WINHTTP_FLAG_REFRESH)
2289 {
2292 }
2294 {
2295 TRACE("failed to add request headers\n");
2296 return FALSE;
2297 }
2298 if (!(request->hdr.disable_flags & WINHTTP_DISABLE_COOKIES) && !add_cookie_headers( request ))
2299 {
2300 WARN("failed to add cookie headers\n");
2301 return FALSE;
2302 }
2303
2304 if (context) request->hdr.context = context;
2305
2306 if (!(ret = open_connection( request ))) goto end;
2307 if (!(wire_req = build_wire_request( request, &len ))) goto end;
2308 TRACE("full request: %s\n", debugstr_a(wire_req));
2309
2311
2312 ret = netconn_send( request->netconn, wire_req, len, &bytes_sent );
2313 heap_free( wire_req );
2314 if (!ret) goto end;
2315
2316 if (optional_len)
2317 {
2318 if (!netconn_send( request->netconn, optional, optional_len, &bytes_sent )) goto end;
2320 request->optional_len = optional_len;
2321 len += optional_len;
2322 }
2324
2325end:
2326 if (async)
2327 {
2329 else
2330 {
2332 result.dwResult = API_SEND_REQUEST;
2333 result.dwError = GetLastError();
2335 }
2336 }
2337 return ret;
2338}
2339
2340static void task_send_request( struct task_header *task )
2341{
2342 struct send_request *s = (struct send_request *)task;
2343 send_request( s->hdr.request, s->headers, s->headers_len, s->optional, s->optional_len, s->total_len, s->context, TRUE );
2344 heap_free( s->headers );
2345}
2346
2347/***********************************************************************
2348 * WinHttpSendRequest (winhttp.@)
2349 */
2352{
2353 BOOL ret;
2354 struct request *request;
2355
2356 TRACE("%p, %s, %u, %p, %u, %u, %lx\n", hrequest, debugstr_wn(headers, headers_len), headers_len, optional,
2357 optional_len, total_len, context);
2358
2359 if (!(request = (struct request *)grab_object( hrequest )))
2360 {
2362 return FALSE;
2363 }
2365 {
2368 return FALSE;
2369 }
2370
2371 if (headers && !headers_len) headers_len = strlenW( headers );
2372
2373 if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC)
2374 {
2375 struct send_request *s;
2376
2377 if (!(s = heap_alloc( sizeof(struct send_request) ))) return FALSE;
2378 s->hdr.request = request;
2379 s->hdr.proc = task_send_request;
2380 s->headers = strdupW( headers );
2381 s->headers_len = headers_len;
2382 s->optional = optional;
2383 s->optional_len = optional_len;
2384 s->total_len = total_len;
2385 s->context = context;
2386
2388 ret = queue_task( (struct task_header *)s );
2389 }
2390 else
2392
2395 return ret;
2396}
2397
2398static BOOL set_credentials( struct request *request, DWORD target, DWORD scheme_flag, const WCHAR *username,
2399 const WCHAR *password )
2400{
2401 enum auth_scheme scheme = scheme_from_flag( scheme_flag );
2402
2404 {
2406 return FALSE;
2407 }
2408 switch (target)
2409 {
2411 {
2413 if (!username) request->creds[TARGET_SERVER][scheme].username = NULL;
2414 else if (!(request->creds[TARGET_SERVER][scheme].username = strdupW( username ))) return FALSE;
2415
2417 if (!password) request->creds[TARGET_SERVER][scheme].password = NULL;
2418 else if (!(request->creds[TARGET_SERVER][scheme].password = strdupW( password ))) return FALSE;
2419 break;
2420 }
2422 {
2423 heap_free( request->creds[TARGET_PROXY][scheme].username );
2424 if (!username) request->creds[TARGET_PROXY][scheme].username = NULL;
2425 else if (!(request->creds[TARGET_PROXY][scheme].username = strdupW( username ))) return FALSE;
2426
2427 heap_free( request->creds[TARGET_PROXY][scheme].password );
2428 if (!password) request->creds[TARGET_PROXY][scheme].password = NULL;
2429 else if (!(request->creds[TARGET_PROXY][scheme].password = strdupW( password ))) return FALSE;
2430 break;
2431 }
2432 default:
2433 WARN("unknown target %u\n", target);
2434 return FALSE;
2435 }
2436 return TRUE;
2437}
2438
2439/***********************************************************************
2440 * WinHttpSetCredentials (winhttp.@)
2441 */
2444{
2445 BOOL ret;
2446 struct request *request;
2447
2448 TRACE("%p, %x, 0x%08x, %s, %p, %p\n", hrequest, target, scheme, debugstr_w(username), password, params);
2449
2450 if (!(request = (struct request *)grab_object( hrequest )))
2451 {
2453 return FALSE;
2454 }
2456 {
2459 return FALSE;
2460 }
2461
2463
2466 return ret;
2467}
2468
2470{
2471 DWORD i, schemes, first, level, target;
2472
2473 switch (status)
2474 {
2475 case HTTP_STATUS_DENIED:
2478 break;
2479
2483 break;
2484
2485 default:
2486 WARN("unhandled status %u\n", status);
2487 return FALSE;
2488 }
2489
2490 if (!query_auth_schemes( request, level, &schemes, &first )) return FALSE;
2491 if (do_authorization( request, target, first )) return TRUE;
2492
2493 schemes &= ~first;
2494 for (i = 0; i < ARRAY_SIZE( auth_schemes ); i++)
2495 {
2496 if (!(schemes & auth_schemes[i].scheme)) continue;
2498 }
2499 return FALSE;
2500}
2501
2502/* set the request content length based on the headers */
2504{
2505 WCHAR encoding[20];
2506 DWORD buflen = sizeof(request->content_length);
2507
2510 else
2511 {
2513 NULL, &request->content_length, &buflen, NULL ))
2515
2516 buflen = sizeof(encoding);
2519 {
2524 }
2525 }
2526 request->content_read = 0;
2527 return request->content_length;
2528}
2529
2530static BOOL read_line( struct request *request, char *buffer, DWORD *len )
2531{
2532 int count, bytes_read, pos = 0;
2533
2534 for (;;)
2535 {
2536 char *eol = memchr( request->read_buf + request->read_pos, '\n', request->read_size );
2537 if (eol)
2538 {
2539 count = eol - (request->read_buf + request->read_pos);
2540 bytes_read = count + 1;
2541 }
2542 else count = bytes_read = request->read_size;
2543
2544 count = min( count, *len - pos );
2546 pos += count;
2547 remove_data( request, bytes_read );
2548 if (eol) break;
2549
2550 if (!read_more_data( request, -1, TRUE )) return FALSE;
2551 if (!request->read_size)
2552 {
2553 *len = 0;
2554 TRACE("returning empty string\n");
2555 return FALSE;
2556 }
2557 }
2558 if (pos < *len)
2559 {
2560 if (pos && buffer[pos - 1] == '\r') pos--;
2561 *len = pos + 1;
2562 }
2563 buffer[*len - 1] = 0;
2564 TRACE("returning %s\n", debugstr_a(buffer));
2565 return TRUE;
2566}
2567
2568#define MAX_REPLY_LEN 1460
2569#define INITIAL_HEADER_BUFFER_LEN 512
2570
2572{
2573 static const WCHAR crlf[] = {'\r','\n',0};
2574
2575 char buffer[MAX_REPLY_LEN];
2576 DWORD buflen, len, offset, crlf_len = 2; /* strlenW(crlf) */
2577 char *status_code, *status_text;
2578 WCHAR *versionW, *status_textW, *raw_headers;
2579 WCHAR status_codeW[4]; /* sizeof("nnn") */
2580
2581 if (!request->netconn) return FALSE;
2582
2583 do
2584 {
2585 buflen = MAX_REPLY_LEN;
2586 if (!read_line( request, buffer, &buflen )) return FALSE;
2587
2588 /* first line should look like 'HTTP/1.x nnn OK' where nnn is the status code */
2589 if (!(status_code = strchr( buffer, ' ' ))) return FALSE;
2590 status_code++;
2591 if (!(status_text = strchr( status_code, ' ' ))) return FALSE;
2592 if ((len = status_text - status_code) != sizeof("nnn") - 1) return FALSE;
2593 status_text++;
2594
2595 TRACE("version [%s] status code [%s] status text [%s]\n",
2599
2600 } while (!memcmp( status_code, "100", len )); /* ignore "100 Continue" responses */
2601
2602 /* we rely on the fact that the protocol is ascii */
2603 MultiByteToWideChar( CP_ACP, 0, status_code, len, status_codeW, len );
2604 status_codeW[len] = 0;
2605 if (!(process_header( request, attr_status, status_codeW,
2607 return FALSE;
2608
2610 if (!(versionW = heap_alloc( len * sizeof(WCHAR) ))) return FALSE;
2612 versionW[len - 1] = 0;
2613
2616
2617 len = buflen - (status_text - buffer);
2618 if (!(status_textW = heap_alloc( len * sizeof(WCHAR) ))) return FALSE;
2619 MultiByteToWideChar( CP_ACP, 0, status_text, len, status_textW, len );
2620
2622 request->status_text = status_textW;
2623
2624 len = max( buflen + crlf_len, INITIAL_HEADER_BUFFER_LEN );
2625 if (!(raw_headers = heap_alloc( len * sizeof(WCHAR) ))) return FALSE;
2626 MultiByteToWideChar( CP_ACP, 0, buffer, buflen, raw_headers, buflen );
2627 memcpy( raw_headers + buflen - 1, crlf, sizeof(crlf) );
2628
2631
2632 offset = buflen + crlf_len - 1;
2633 for (;;)
2634 {
2635 struct header *header;
2636
2637 buflen = MAX_REPLY_LEN;
2638 if (!read_line( request, buffer, &buflen )) return TRUE;
2639 if (!*buffer) buflen = 1;
2640
2641 while (len - offset < buflen + crlf_len)
2642 {
2643 WCHAR *tmp;
2644 len *= 2;
2645 if (!(tmp = heap_realloc( raw_headers, len * sizeof(WCHAR) ))) return FALSE;
2646 request->raw_headers = raw_headers = tmp;
2647 }
2648 if (!*buffer)
2649 {
2650 memcpy( raw_headers + offset, crlf, sizeof(crlf) );
2651 break;
2652 }
2653 MultiByteToWideChar( CP_ACP, 0, buffer, buflen, raw_headers + offset, buflen );
2654
2655 if (!(header = parse_header( raw_headers + offset ))) break;
2657 {
2659 break;
2660 }
2662 memcpy( raw_headers + offset + buflen - 1, crlf, sizeof(crlf) );
2663 offset += buflen + crlf_len - 1;
2664 }
2665
2666 TRACE("raw headers: %s\n", debugstr_w(raw_headers));
2667 return TRUE;
2668}
2669
2670static void record_cookies( struct request *request )
2671{
2672 unsigned int i;
2673
2674 for (i = 0; i < request->num_headers; i++)
2675 {
2676 struct header *set_cookie = &request->headers[i];
2677 if (!strcmpiW( set_cookie->field, attr_set_cookie ) && !set_cookie->is_request)
2678 {
2679 set_cookies( request, set_cookie->value );
2680 }
2681 }
2682}
2683
2685{
2686 DWORD size;
2687 WCHAR *ret;
2688
2691 if (!(ret = heap_alloc( size ))) return NULL;
2692 *len = size / sizeof(WCHAR) - 1;
2694 heap_free( ret );
2695 return NULL;
2696}
2697
2699{
2700 BOOL ret = FALSE;
2701 DWORD len, len_loc;
2702 URL_COMPONENTS uc;
2703 struct connect *connect = request->connect;
2706 int index;
2707
2708 if (!(location = get_redirect_url( request, &len_loc ))) return FALSE;
2709
2710 memset( &uc, 0, sizeof(uc) );
2711 uc.dwStructSize = sizeof(uc);
2713
2714 if (!WinHttpCrackUrl( location, len_loc, 0, &uc )) /* assume relative redirect */
2715 {
2716 WCHAR *path, *p;
2717
2718 if (location[0] == '/')
2719 {
2720 if (!(path = heap_alloc( (len_loc + 1) * sizeof(WCHAR) ))) goto end;
2721 memcpy( path, location, len_loc * sizeof(WCHAR) );
2722 path[len_loc] = 0;
2723 }
2724 else
2725 {
2726 if ((p = strrchrW( request->path, '/' ))) *p = 0;
2727 len = strlenW( request->path ) + 1 + len_loc;
2728 if (!(path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
2729 strcpyW( path, request->path );
2730 strcatW( path, slashW );
2731 memcpy( path + strlenW(path), location, len_loc * sizeof(WCHAR) );
2732 path[len_loc] = 0;
2733 }
2735 request->path = path;
2736
2738 }
2739 else
2740 {
2742 {
2744 TRACE("redirect from secure page to non-secure page\n");
2745 request->hdr.flags &= ~WINHTTP_FLAG_SECURE;
2746 }
2747 else if (uc.nScheme == INTERNET_SCHEME_HTTPS && !(request->hdr.flags & WINHTTP_FLAG_SECURE))
2748 {
2749 TRACE("redirect from non-secure page to secure page\n");
2751 }
2752
2754
2755 len = uc.dwHostNameLength;
2756 if (!(hostname = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
2757 memcpy( hostname, uc.lpszHostName, len * sizeof(WCHAR) );
2758 hostname[len] = 0;
2759
2760 port = uc.nPort ? uc.nPort : (uc.nScheme == INTERNET_SCHEME_HTTPS ? 443 : 80);
2762 {
2766 if (!(ret = set_server_for_hostname( connect, hostname, port ))) goto end;
2767
2769 request->netconn = NULL;
2773 }
2774 else heap_free( hostname );
2775
2777 if (!(ret = open_connection( request ))) goto end;
2778
2780 request->path = NULL;
2781 if (uc.dwUrlPathLength)
2782 {
2784 if (!(request->path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
2785 memcpy( request->path, uc.lpszUrlPath, (len + 1) * sizeof(WCHAR) );
2786 request->path[len] = 0;
2787 }
2788 else request->path = strdupW( slashW );
2789 }
2790
2791 /* remove content-type/length headers */
2794
2796 {
2798 request->verb = strdupW( getW );
2800 request->optional_len = 0;
2801 }
2802 ret = TRUE;
2803
2804end:
2806 return ret;
2807}
2808
2810{
2811 static const WCHAR passportW[] = {'P','a','s','s','p','o','r','t','1','.','4'};
2812 WCHAR buf[1024];
2814
2815 if (!(request->connect->session->passport_flags & WINHTTP_ENABLE_PASSPORT_AUTH) ||
2817
2819 (buf[ARRAY_SIZE(passportW)] == ' ' || !buf[ARRAY_SIZE(passportW)])) return TRUE;
2820
2821 return FALSE;
2822}
2823
2825{
2826 static const WCHAR status401W[] = {'4','0','1',0};
2828 int i, len = strlenW( request->raw_headers );
2830
2831 if (!process_header( request, attr_status, status401W, flags, FALSE )) return FALSE;
2832
2833 for (i = 0; i < len; i++)
2834 {
2835 if (i <= len - 3 && p[i] == '3' && p[i + 1] == '0' && p[i + 2] == '2')
2836 {
2837 p[i] = '4';
2838 p[i + 2] = '1';
2839 break;
2840 }
2841 }
2842 return TRUE;
2843}
2844
2845static BOOL receive_response( struct request *request, BOOL async )
2846{
2847 BOOL ret;
2849
2850 if (!request->netconn)
2851 {
2853 return FALSE;
2854 }
2855
2857 for (;;)
2858 {
2859 if (!(ret = read_reply( request )))
2860 {
2862 break;
2863 }
2864 size = sizeof(DWORD);
2866 if (!(ret = query_headers( request, query, NULL, &status, &size, NULL ))) break;
2867
2869
2870 if (!(request->hdr.disable_flags & WINHTTP_DISABLE_COOKIES)) record_cookies( request );
2871
2873 {
2875 }
2877 {
2878 if (request->hdr.disable_flags & WINHTTP_DISABLE_REDIRECTS ||
2879 request->hdr.redirect_policy == WINHTTP_OPTION_REDIRECT_POLICY_NEVER) break;
2880
2881 if (!(ret = handle_redirect( request, status ))) break;
2882
2883 /* recurse synchronously */
2884 if ((ret = send_request( request, NULL, 0, request->optional, request->optional_len, 0, 0, FALSE ))) continue;
2885 }
2887 {
2888 if (request->hdr.disable_flags & WINHTTP_DISABLE_AUTHENTICATION) break;
2889
2890 if (!handle_authorization( request, status )) break;
2891
2892 /* recurse synchronously */
2893 if ((ret = send_request( request, NULL, 0, request->optional, request->optional_len, 0, 0, FALSE ))) continue;
2894 }
2895 break;
2896 }
2897
2900
2901 if (async)
2902 {
2904 else
2905 {
2907 result.dwResult = API_RECEIVE_RESPONSE;
2908 result.dwError = GetLastError();
2910 }
2911 }
2912 return ret;
2913}
2914
2915static void task_receive_response( struct task_header *task )
2916{
2917 struct receive_response *r = (struct receive_response *)task;
2918 receive_response( r->hdr.request, TRUE );
2919}
2920
2921/***********************************************************************
2922 * WinHttpReceiveResponse (winhttp.@)
2923 */
2925{
2926 BOOL ret;
2927 struct request *request;
2928
2929 TRACE("%p, %p\n", hrequest, reserved);
2930
2931 if (!(request = (struct request *)grab_object( hrequest )))
2932 {
2934 return FALSE;
2935 }
2937 {
2940 return FALSE;
2941 }
2942
2943 if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC)
2944 {
2945 struct receive_response *r;
2946
2947 if (!(r = heap_alloc( sizeof(struct receive_response) ))) return FALSE;
2948 r->hdr.request = request;
2949 r->hdr.proc = task_receive_response;
2950
2952 ret = queue_task( (struct task_header *)r );
2953 }
2954 else
2956
2959 return ret;
2960}
2961
2963{
2964 DWORD count = 0;
2965 BOOL ret = TRUE;
2966
2967 if (end_of_read_data( request )) goto done;
2968
2971 if (!count)
2972 {
2973 if (!(ret = refill_buffer( request, async ))) goto done;
2976 }
2977
2978done:
2979 TRACE("%u bytes available\n", count);
2980 if (async)
2981 {
2983 else
2984 {
2987 result.dwError = GetLastError();
2989 }
2990 }
2991
2992 if (ret && available) *available = count;
2993 return ret;
2994}
2995
2996static void task_query_data_available( struct task_header *task )
2997{
2998 struct query_data *q = (struct query_data *)task;
2999 query_data_available( q->hdr.request, q->available, TRUE );
3000}
3001
3002/***********************************************************************
3003 * WinHttpQueryDataAvailable (winhttp.@)
3004 */
3006{
3007 BOOL ret;
3008 struct request *request;
3009
3010 TRACE("%p, %p\n", hrequest, available);
3011
3012 if (!(request = (struct request *)grab_object( hrequest )))
3013 {
3015 return FALSE;
3016 }
3018 {
3021 return FALSE;
3022 }
3023
3024 if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC)
3025 {
3026 struct query_data *q;
3027
3028 if (!(q = heap_alloc( sizeof(struct query_data) ))) return FALSE;
3029 q->hdr.request = request;
3031 q->available = available;
3032
3034 ret = queue_task( (struct task_header *)q );
3035 }
3036 else
3038
3041 return ret;
3042}
3043
3044static void task_read_data( struct task_header *task )
3045{
3046 struct read_data *r = (struct read_data *)task;
3047 read_data( r->hdr.request, r->buffer, r->to_read, r->read, TRUE );
3048}
3049
3050/***********************************************************************
3051 * WinHttpReadData (winhttp.@)
3052 */
3054{
3055 BOOL ret;
3056 struct request *request;
3057
3058 TRACE("%p, %p, %d, %p\n", hrequest, buffer, to_read, read);
3059
3060 if (!(request = (struct request *)grab_object( hrequest )))
3061 {
3063 return FALSE;
3064 }
3066 {
3069 return FALSE;
3070 }
3071
3072 if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC)
3073 {
3074 struct read_data *r;
3075
3076 if (!(r = heap_alloc( sizeof(struct read_data) ))) return FALSE;
3077 r->hdr.request = request;
3078 r->hdr.proc = task_read_data;
3079 r->buffer = buffer;
3080 r->to_read = to_read;
3081 r->read = read;
3082
3084 ret = queue_task( (struct task_header *)r );
3085 }
3086 else
3088
3091 return ret;
3092}
3093
3094static BOOL write_data( struct request *request, const void *buffer, DWORD to_write, DWORD *written, BOOL async )
3095{
3096 BOOL ret;
3097 int num_bytes;
3098
3099 ret = netconn_send( request->netconn, buffer, to_write, &num_bytes );
3100
3101 if (async)
3102 {
3103 if (ret) send_callback( &request->hdr, WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE, &num_bytes, sizeof(num_bytes) );
3104 else
3105 {
3107 result.dwResult = API_WRITE_DATA;
3108 result.dwError = GetLastError();
3110 }
3111 }
3112 if (ret && written) *written = num_bytes;
3113 return ret;
3114}
3115
3116static void task_write_data( struct task_header *task )
3117{
3118 struct write_data *w = (struct write_data *)task;
3119 write_data( w->hdr.request, w->buffer, w->to_write, w->written, TRUE );
3120}
3121
3122/***********************************************************************
3123 * WinHttpWriteData (winhttp.@)
3124 */
3126{
3127 BOOL ret;
3128 struct request *request;
3129
3130 TRACE("%p, %p, %d, %p\n", hrequest, buffer, to_write, written);
3131
3132 if (!(request = (struct request *)grab_object( hrequest )))
3133 {
3135 return FALSE;
3136 }
3138 {
3141 return FALSE;
3142 }
3143
3144 if (request->connect->hdr.flags & WINHTTP_FLAG_ASYNC)
3145 {
3146 struct write_data *w;
3147
3148 if (!(w = heap_alloc( sizeof(struct write_data) ))) return FALSE;
3149 w->hdr.request = request;
3150 w->hdr.proc = task_write_data;
3151 w->buffer = buffer;
3152 w->to_write = to_write;
3153 w->written = written;
3154
3156 ret = queue_task( (struct task_header *)w );
3157 }
3158 else
3160
3163 return ret;
3164}
3165
3167{
3174
3176{
3177 IWinHttpRequest IWinHttpRequest_iface;
3186#ifdef __REACTOS__
3187 HANDLE thread;
3188#else
3190#endif
3193#ifndef __REACTOS__
3195#endif
3196 char *buffer;
3210};
3211
3212static inline struct winhttp_request *impl_from_IWinHttpRequest( IWinHttpRequest *iface )
3213{
3215}
3216
3218 IWinHttpRequest *iface )
3219{
3221 return InterlockedIncrement( &request->refs );
3222}
3223
3224/* critical section must be held */
3226{
3227 if (request->state <= REQUEST_STATE_CANCELLED) return;
3228
3229#ifdef __REACTOS__
3230 SetEvent( request->cancel );
3234
3236
3237 CloseHandle( request->thread );
3238 request->thread = NULL;
3239#else
3240 if (request->proc_running)
3241 {
3242 SetEvent( request->cancel );
3244
3246
3248 }
3250#endif
3251}
3252
3253/* critical section must be held */
3255{
3256 if (request->state < REQUEST_STATE_INITIALIZED) return;
3257 WinHttpCloseHandle( request->hrequest );
3258 WinHttpCloseHandle( request->hconnect );
3259 WinHttpCloseHandle( request->hsession );
3260#ifdef __REACTOS__
3261 CloseHandle( request->thread );
3262#else
3263 CloseHandle( request->done );
3264#endif
3265 CloseHandle( request->wait );
3266 CloseHandle( request->cancel );
3267 heap_free( (WCHAR *)request->proxy.lpszProxy );
3268 heap_free( (WCHAR *)request->proxy.lpszProxyBypass );
3269 heap_free( request->buffer );
3271 VariantClear( &request->data );
3272}
3273
3275 IWinHttpRequest *iface )
3276{
3279 if (!refs)
3280 {
3281 TRACE("destroying %p\n", request);
3282
3287 request->cs.DebugInfo->Spare[0] = 0;
3289 heap_free( request );
3290 }
3291 return refs;
3292}
3293
3295 IWinHttpRequest *iface,
3296 REFIID riid,
3297 void **obj )
3298{
3300
3301 TRACE("%p, %s, %p\n", request, debugstr_guid(riid), obj );
3302
3303 if (IsEqualGUID( riid, &IID_IWinHttpRequest ) ||
3306 {
3307 *obj = iface;
3308 }
3309 else
3310 {
3311 FIXME("interface %s not implemented\n", debugstr_guid(riid));
3312 return E_NOINTERFACE;
3313 }
3314 IWinHttpRequest_AddRef( iface );
3315 return S_OK;
3316}
3317
3319 IWinHttpRequest *iface,
3320 UINT *count )
3321{
3323
3324 TRACE("%p, %p\n", request, count);
3325 *count = 1;
3326 return S_OK;
3327}
3328
3330{
3332 last_tid
3334
3337
3339{
3340 &IID_IWinHttpRequest
3341};
3342
3344{
3345 HRESULT hr;
3346
3347 if (!winhttp_typelib)
3348 {
3350
3351 hr = LoadRegTypeLib( &LIBID_WinHttp, 5, 1, LOCALE_SYSTEM_DEFAULT, &typelib );
3352 if (FAILED(hr))
3353 {
3354 ERR("LoadRegTypeLib failed: %08x\n", hr);
3355 return hr;
3356 }
3358 ITypeLib_Release( typelib );
3359 }
3360 if (!winhttp_typeinfo[tid])
3361 {
3363
3364 hr = ITypeLib_GetTypeInfoOfGuid( winhttp_typelib, winhttp_tid_id[tid], &typeinfo );
3365 if (FAILED(hr))
3366 {
3367 ERR("GetTypeInfoOfGuid(%s) failed: %08x\n", debugstr_guid(winhttp_tid_id[tid]), hr);
3368 return hr;
3369 }
3371 ITypeInfo_Release( typeinfo );
3372 }
3374 ITypeInfo_AddRef(winhttp_typeinfo[tid]);
3375 return S_OK;
3376}
3377
3379{
3380 unsigned i;
3381
3382 for (i = 0; i < ARRAY_SIZE(winhttp_typeinfo); i++)
3383 if (winhttp_typeinfo[i])
3384 ITypeInfo_Release(winhttp_typeinfo[i]);
3385
3386 if (winhttp_typelib)
3387 ITypeLib_Release(winhttp_typelib);
3388}
3389
3391 IWinHttpRequest *iface,
3392 UINT index,
3393 LCID lcid,
3394 ITypeInfo **info )
3395{
3397 TRACE("%p, %u, %u, %p\n", request, index, lcid, info);
3398
3400}
3401
3403 IWinHttpRequest *iface,
3404 REFIID riid,
3405 LPOLESTR *names,
3406 UINT count,
3407 LCID lcid,
3408 DISPID *dispid )
3409{
3412 HRESULT hr;
3413
3414 TRACE("%p, %s, %p, %u, %u, %p\n", request, debugstr_guid(riid), names, count, lcid, dispid);
3415
3416 if (!names || !count || !dispid) return E_INVALIDARG;
3417
3419 if (SUCCEEDED(hr))
3420 {
3421 hr = ITypeInfo_GetIDsOfNames( typeinfo, names, count, dispid );
3422 ITypeInfo_Release( typeinfo );
3423 }
3424 return hr;
3425}
3426
3428 IWinHttpRequest *iface,
3429 DISPID member,
3430 REFIID riid,
3431 LCID lcid,
3432 WORD flags,
3433 DISPPARAMS *params,
3434 VARIANT *result,
3435 EXCEPINFO *excep_info,
3436 UINT *arg_err )
3437{
3440 HRESULT hr;
3441
3442 TRACE("%p, %d, %s, %d, %d, %p, %p, %p, %p\n", request, member, debugstr_guid(riid),
3443 lcid, flags, params, result, excep_info, arg_err);
3444
3446
3448 {
3449 VARIANT ret_value, option;
3450 UINT err_pos;
3451
3452 if (!result) result = &ret_value;
3453 if (!arg_err) arg_err = &err_pos;
3454
3455 VariantInit( &option );
3457
3458 if (!flags) return S_OK;
3459
3461 {
3462 hr = DispGetParam( params, 0, VT_I4, &option, arg_err );
3463 if (FAILED(hr)) return hr;
3464
3465 hr = IWinHttpRequest_put_Option( &request->IWinHttpRequest_iface, V_I4( &option ), params->rgvarg[0] );
3466 if (FAILED(hr))
3467 WARN("put_Option(%d) failed: %x\n", V_I4( &option ), hr);
3468 return hr;
3469 }
3471 {
3472 hr = DispGetParam( params, 0, VT_I4, &option, arg_err );
3473 if (FAILED(hr)) return hr;
3474
3475 hr = IWinHttpRequest_get_Option( &request->IWinHttpRequest_iface, V_I4( &option ), result );
3476 if (FAILED(hr))
3477 WARN("get_Option(%d) failed: %x\n", V_I4( &option ), hr);
3478 return hr;
3479 }
3480
3481 FIXME("unsupported flags %x\n", flags);
3482 return E_NOTIMPL;
3483 }
3484
3485 /* fallback to standard implementation */
3486
3488 if (SUCCEEDED(hr))
3489 {
3490 hr = ITypeInfo_Invoke( typeinfo, &request->IWinHttpRequest_iface, member, flags,
3491 params, result, excep_info, arg_err );
3492 ITypeInfo_Release( typeinfo );
3493 }
3494 return hr;
3495}
3496
3498 IWinHttpRequest *iface,
3499 HTTPREQUEST_PROXY_SETTING proxy_setting,
3501 VARIANT bypass_list )
3502{
3505
3506 TRACE("%p, %u, %s, %s\n", request, proxy_setting, debugstr_variant(&proxy_server),
3507 debugstr_variant(&bypass_list));
3508
3510 switch (proxy_setting)
3511 {
3512 case HTTPREQUEST_PROXYSETTING_DEFAULT:
3513 request->proxy.dwAccessType = WINHTTP_ACCESS_TYPE_DEFAULT_PROXY;
3514 heap_free( (WCHAR *)request->proxy.lpszProxy );
3515 heap_free( (WCHAR *)request->proxy.lpszProxyBypass );
3516 request->proxy.lpszProxy = NULL;
3517 request->proxy.lpszProxyBypass = NULL;
3518 break;
3519
3520 case HTTPREQUEST_PROXYSETTING_DIRECT:
3521 request->proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NO_PROXY;
3522 heap_free( (WCHAR *)request->proxy.lpszProxy );
3523 heap_free( (WCHAR *)request->proxy.lpszProxyBypass );
3524 request->proxy.lpszProxy = NULL;
3525 request->proxy.lpszProxyBypass = NULL;
3526 break;
3527
3528 case HTTPREQUEST_PROXYSETTING_PROXY:
3529 request->proxy.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY;
3530 if (V_VT( &proxy_server ) == VT_BSTR)
3531 {
3532 heap_free( (WCHAR *)request->proxy.lpszProxy );
3533 request->proxy.lpszProxy = strdupW( V_BSTR( &proxy_server ) );
3534 }
3535 if (V_VT( &bypass_list ) == VT_BSTR)
3536 {
3537 heap_free( (WCHAR *)request->proxy.lpszProxyBypass );
3538 request->proxy.lpszProxyBypass = strdupW( V_BSTR( &bypass_list ) );
3539 }
3540 break;
3541
3542 default:
3544 break;
3545 }
3547 return HRESULT_FROM_WIN32( err );
3548}
3549
3551 IWinHttpRequest *iface,
3552 BSTR username,
3553 BSTR password,
3554 HTTPREQUEST_SETCREDENTIALS_FLAGS flags )
3555{
3557 DWORD target, scheme = WINHTTP_AUTH_SCHEME_BASIC; /* FIXME: query supported schemes */
3559
3560 TRACE("%p, %s, %p, 0x%08x\n", request, debugstr_w(username), password, flags);
3561
3563 if (request->state < REQUEST_STATE_OPEN)
3564 {
3566 goto done;
3567 }
3568 switch (flags)
3569 {
3570 case HTTPREQUEST_SETCREDENTIALS_FOR_SERVER:
3572 break;
3573 case HTTPREQUEST_SETCREDENTIALS_FOR_PROXY:
3575 break;
3576 default:
3578 goto done;
3579 }
3581 {
3582 err = GetLastError();
3583 }
3584done:
3586 return HRESULT_FROM_WIN32( err );
3587}
3588
3590{
3591 request->wait = CreateEventW( NULL, FALSE, FALSE, NULL );
3592 request->cancel = CreateEventW( NULL, FALSE, FALSE, NULL );
3593#ifndef __REACTOS__
3594 request->done = CreateEventW( NULL, FALSE, FALSE, NULL );
3595#endif
3596 request->connect_timeout = 60000;
3597 request->send_timeout = 30000;
3598 request->receive_timeout = 30000;
3599 request->url_codepage = CP_UTF8;
3600 VariantInit( &request->data );
3602}
3603
3605{
3607 WinHttpCloseHandle( request->hrequest );
3608 request->hrequest = NULL;
3609 WinHttpCloseHandle( request->hconnect );
3610 request->hconnect = NULL;
3611 heap_free( request->buffer );
3612 request->buffer = NULL;
3614 request->verb = NULL;
3615 request->offset = 0;
3616 request->bytes_available = 0;
3617 request->bytes_read = 0;
3618 request->error = ERROR_SUCCESS;
3619 request->logon_policy = 0;
3620 request->disable_feature = 0;
3621 request->async = FALSE;
3622 request->connect_timeout = 60000;
3623 request->send_timeout = 30000;
3624 request->receive_timeout = 30000;
3625 request->url_codepage = CP_UTF8;
3626 heap_free( request->proxy.lpszProxy );
3627 request->proxy.lpszProxy = NULL;
3628 heap_free( request->proxy.lpszProxyBypass );
3629 request->proxy.lpszProxyBypass = NULL;
3630 VariantClear( &request->data );
3632}
3633
3635 IWinHttpRequest *iface,
3636 BSTR method,
3637 BSTR url,
3638 VARIANT async )
3639{
3640 static const WCHAR typeW[] = {'*','/','*',0};
3641 static const WCHAR *acceptW[] = {typeW, NULL};
3642 static const WCHAR httpsW[] = {'h','t','t','p','s'};
3643 static const WCHAR user_agentW[] = {
3644 'M','o','z','i','l','l','a','/','4','.','0',' ','(','c','o','m','p','a','t','i','b','l','e',';',' ',
3645 'W','i','n','3','2',';',' ','W','i','n','H','t','t','p','.','W','i','n','H','t','t','p',
3646 'R','e','q','u','e','s','t','.','5',')',0};
3648 URL_COMPONENTS uc;
3649 WCHAR *hostname, *path = NULL, *verb = NULL;
3651
3652 TRACE("%p, %s, %s, %s\n", request, debugstr_w(method), debugstr_w(url),
3654
3655 if (!method || !url) return E_INVALIDARG;
3656
3657 memset( &uc, 0, sizeof(uc) );
3658 uc.dwStructSize = sizeof(uc);
3659 uc.dwSchemeLength = ~0u;
3660 uc.dwHostNameLength = ~0u;
3661 uc.dwUrlPathLength = ~0u;
3662 uc.dwExtraInfoLength = ~0u;
3663 if (!WinHttpCrackUrl( url, 0, 0, &uc )) return HRESULT_FROM_WIN32( GetLastError() );
3664
3667
3668 if (!(hostname = heap_alloc( (uc.dwHostNameLength + 1) * sizeof(WCHAR) ))) goto error;
3669 memcpy( hostname, uc.lpszHostName, uc.dwHostNameLength * sizeof(WCHAR) );
3670 hostname[uc.dwHostNameLength] = 0;
3671
3672 if (!(path = heap_alloc( (uc.dwUrlPathLength + uc.dwExtraInfoLength + 1) * sizeof(WCHAR) ))) goto error;
3673 memcpy( path, uc.lpszUrlPath, (uc.dwUrlPathLength + uc.dwExtraInfoLength) * sizeof(WCHAR) );
3675
3676 if (!(verb = strdupW( method ))) goto error;
3677 if (SUCCEEDED( VariantChangeType( &async, &async, 0, VT_BOOL )) && V_BOOL( &async )) request->async = TRUE;
3678 else request->async = FALSE;
3679
3680 if (!request->hsession)
3681 {
3684 {
3685 err = GetLastError();
3686 goto error;
3687 }
3688 if (!(request->hconnect = WinHttpConnect( request->hsession, hostname, uc.nPort, 0 )))
3689 {
3690 WinHttpCloseHandle( request->hsession );
3691 request->hsession = NULL;
3692 err = GetLastError();
3693 goto error;
3694 }
3695 }
3696 else if (!(request->hconnect = WinHttpConnect( request->hsession, hostname, uc.nPort, 0 )))
3697 {
3698 err = GetLastError();
3699 goto error;
3700 }
3701
3702 len = ARRAY_SIZE( httpsW );
3703 if (uc.dwSchemeLength == len && !memcmp( uc.lpszScheme, httpsW, len * sizeof(WCHAR) ))
3704 {
3706 }
3707 if (!(request->hrequest = WinHttpOpenRequest( request->hconnect, method, path, NULL, NULL, acceptW, flags )))
3708 {
3709 err = GetLastError();
3710 goto error;
3711 }
3713
3714 request->state = REQUEST_STATE_OPEN;
3715 request->verb = verb;
3717 heap_free( path );
3719 return S_OK;
3720
3721error:
3722 WinHttpCloseHandle( request->hconnect );
3723 request->hconnect = NULL;
3725 heap_free( path );
3726 heap_free( verb );
3728 return HRESULT_FROM_WIN32( err );
3729}
3730
3732 IWinHttpRequest *iface,
3733 BSTR header,
3734 BSTR value )
3735{
3736 static const WCHAR fmtW[] = {'%','s',':',' ','%','s','\r','\n',0};
3737 static const WCHAR emptyW[] = {0};
3740 WCHAR *str;
3741
3742 TRACE("%p, %s, %s\n", request, debugstr_w(header), debugstr_w(value));
3743
3744 if (!header) return E_INVALIDARG;
3745
3747 if (request->state < REQUEST_STATE_OPEN)
3748 {
3750 goto done;
3751 }
3752 if (request->state >= REQUEST_STATE_SENT)
3753 {
3755 goto done;
3756 }
3757 len = strlenW( header ) + 4;
3758 if (value) len += strlenW( value );
3759 if (!(str = heap_alloc( (len + 1) * sizeof(WCHAR) )))
3760 {
3762 goto done;
3763 }
3764 sprintfW( str, fmtW, header, value ? value : emptyW );
3765 if (!WinHttpAddRequestHeaders( request->hrequest, str, len,
3767 {
3768 err = GetLastError();
3769 }
3770 heap_free( str );
3771
3772done:
3774 return HRESULT_FROM_WIN32( err );
3775}
3776
3778 IWinHttpRequest *iface,
3779 BSTR header,
3780 BSTR *value )
3781{
3784
3785 TRACE("%p, %p\n", request, header);
3786
3788 if (request->state < REQUEST_STATE_SENT)
3789 {
3791 goto done;
3792 }
3793 if (!header || !value)
3794 {
3796 goto done;
3797 }
3798 size = 0;
3800 {
3801 err = GetLastError();
3802 if (err != ERROR_INSUFFICIENT_BUFFER) goto done;
3803 }
3804 if (!(*value = SysAllocStringLen( NULL, size / sizeof(WCHAR) )))
3805 {
3807 goto done;
3808 }
3811 {
3812 err = GetLastError();
3813 SysFreeString( *value );
3814 }
3815done:
3817 return HRESULT_FROM_WIN32( err );
3818}
3819
3821 IWinHttpRequest *iface,
3822 BSTR *headers )
3823{
3826
3827 TRACE("%p, %p\n", request, headers);
3828
3829 if (!headers) return E_INVALIDARG;
3830
3832 if (request->state < REQUEST_STATE_SENT)
3833 {
3835 goto done;
3836 }
3837 size = 0;
3839 {
3840 err = GetLastError();
3841 if (err != ERROR_INSUFFICIENT_BUFFER) goto done;
3842 }
3843 if (!(*headers = SysAllocStringLen( NULL, size / sizeof(WCHAR) )))
3844 {
3846 goto done;
3847 }
3850 {
3851 err = GetLastError();
3853 }
3854done:
3856 return HRESULT_FROM_WIN32( err );
3857}
3858
3860{
3861 struct winhttp_request *request = (struct winhttp_request *)context;
3862
3863 switch (status)
3864 {
3866 request->bytes_available = *(DWORD *)buffer;
3867 request->error = ERROR_SUCCESS;
3868 break;
3870 request->bytes_read = size;
3871 request->error = ERROR_SUCCESS;
3872 break;
3874 {
3876 request->error = result->dwError;
3877 break;
3878 }
3879 default:
3880 request->error = ERROR_SUCCESS;
3881 break;
3882 }
3883 SetEvent( request->wait );
3884}
3885
3887{
3890}
3891
3893{
3894 HANDLE handles[2] = { request->wait, request->cancel };
3895#ifndef __REACTOS__
3896 DWORD ret;
3897#endif
3898
3900 {
3901 case WAIT_OBJECT_0:
3902#ifndef __REACTOS__
3903 ret = request->error;
3904#endif
3905 break;
3906 case WAIT_OBJECT_0 + 1:
3907#ifdef __REACTOS__
3908 request->error = ERROR_CANCELLED;
3909#else
3910 ret = request->error = ERROR_CANCELLED;
3911 SetEvent( request->done );
3912#endif
3913 break;
3914 default:
3915#ifdef __REACTOS__
3916 request->error = GetLastError();
3917#else
3918 ret = request->error = GetLastError();
3919#endif
3920 break;
3921 }
3922#ifdef __REACTOS__
3923 return request->error;
3924#else
3925 return ret;
3926#endif
3927}
3928
3930{
3931 DWORD err, size, buflen = 4096;
3932
3934 if (!WinHttpReceiveResponse( request->hrequest, NULL ))
3935 {
3936 return HRESULT_FROM_WIN32( GetLastError() );
3937 }
3939 if (!strcmpW( request->verb, headW ))
3940 {
3942 return S_OK;
3943 }
3944 if (!(request->buffer = heap_alloc( buflen ))) return E_OUTOFMEMORY;
3945 request->buffer[0] = 0;
3946 size = 0;
3947 do
3948 {
3950 if (!WinHttpQueryDataAvailable( request->hrequest, &request->bytes_available ))
3951 {
3952 err = GetLastError();
3953 goto error;
3954 }
3955 if ((err = wait_for_completion( request ))) goto error;
3956 if (!request->bytes_available) break;
3957 size += request->bytes_available;
3958 if (buflen < size)
3959 {
3960 char *tmp;
3961 while (buflen < size) buflen *= 2;
3962 if (!(tmp = heap_realloc( request->buffer, buflen )))
3963 {
3965 goto error;
3966 }
3967 request->buffer = tmp;
3968 }
3970 if (!WinHttpReadData( request->hrequest, request->buffer + request->offset,
3971 request->bytes_available, &request->bytes_read ))
3972 {
3973 err = GetLastError();
3974 goto error;
3975 }
3976 if ((err = wait_for_completion( request ))) goto error;
3977 request->offset += request->bytes_read;
3978 } while (request->bytes_read);
3979
3981 return S_OK;
3982
3983error:
3984 heap_free( request->buffer );
3985 request->buffer = NULL;
3986 return HRESULT_FROM_WIN32( err );
3987}
3988
3990{
3991 if (!WinHttpSetOption( request->hrequest, WINHTTP_OPTION_PROXY, &request->proxy,
3992 sizeof(request->proxy) )) return GetLastError();
3993
3994 if (!WinHttpSetOption( request->hrequest, WINHTTP_OPTION_AUTOLOGON_POLICY, &request->logon_policy,
3995 sizeof(request->logon_policy) )) return GetLastError();
3996
3997 if (!WinHttpSetOption( request->hrequest, WINHTTP_OPTION_DISABLE_FEATURE, &request->disable_feature,
3998 sizeof(request->disable_feature) )) return GetLastError();
3999
4000 if (!WinHttpSetTimeouts( request->hrequest,
4005 return ERROR_SUCCESS;
4006}
4007
4009{
4010 static const WCHAR fmtW[] = {'%','s',':',' ','%','s',0};
4011 static const WCHAR text_plainW[] = {'t','e','x','t','/','p','l','a','i','n',0};
4012 static const WCHAR charset_utf8W[] = {'c','h','a','r','s','e','t','=','u','t','f','-','8',0};
4013 WCHAR headerW[64];
4014 int len;
4015
4016 len = sprintfW( headerW, fmtW, attr_content_type, text_plainW );
4018 len = sprintfW( headerW, fmtW, attr_content_type, charset_utf8W );
4020}
4021
4023{
4024 SAFEARRAY *sa = NULL;
4025 VARIANT data;
4026 char *ptr = NULL;
4027 LONG size = 0;
4028 HRESULT hr;
4029 DWORD err;
4030
4032 if (strcmpW( request->verb, getW ))
4033 {
4034 VariantInit( &data );
4035 if (V_VT( &request->data ) == VT_BSTR)
4036 {
4037 UINT cp = CP_ACP;
4038 const WCHAR *str = V_BSTR( &request->data );
4039 int i, len = strlenW( str );
4040
4041 for (i = 0; i < len; i++)
4042 {
4043 if (str[i] > 127)
4044 {
4045 cp = CP_UTF8;
4046 break;
4047 }
4048 }
4049 size = WideCharToMultiByte( cp, 0, str, len, NULL, 0, NULL, NULL );
4050 if (!(ptr = heap_alloc( size ))) return E_OUTOFMEMORY;
4053 }
4054 else if (VariantChangeType( &data, &request->data, 0, VT_ARRAY|VT_UI1 ) == S_OK)
4055 {
4056 sa = V_ARRAY( &data );
4057 if ((hr = SafeArrayAccessData( sa, (void **)&ptr )) != S_OK) return hr;
4058 if ((hr = SafeArrayGetUBound( sa, 1, &size )) != S_OK)
4059 {
4061 return hr;
4062 }
4063 size++;
4064 }
4065 }
4067 if (!WinHttpSendRequest( request->hrequest, NULL, 0, ptr, size, size, 0 ))
4068 {
4069 err = GetLastError();
4070 goto error;
4071 }
4072 if ((err = wait_for_completion( request ))) goto error;
4073 if (sa) SafeArrayUnaccessData( sa );
4074 else heap_free( ptr );
4075 request->state = REQUEST_STATE_SENT;
4076 return S_OK;
4077
4078error:
4079 if (sa) SafeArrayUnaccessData( sa );
4080 else heap_free( ptr );
4081 return HRESULT_FROM_WIN32( err );
4082}
4083
4084#ifdef __REACTOS__
4085static HRESULT request_send_and_receive( struct winhttp_request *request )
4086{
4088 if (hr == S_OK) hr = request_receive( request );
4089 return hr;
4090}
4091
4093{
4094 struct winhttp_request *request = (struct winhttp_request *)arg;
4095 return request_send_and_receive( request );
4096}
4097#else
4099{
4100 struct winhttp_request *request = (struct winhttp_request *)ctx;
4102 SetEvent( request->done );
4103}
4104#endif
4105
4106/* critical section must be held */
4108{
4109#ifdef __REACTOS__
4110 HANDLE thread = request->thread;
4111#else
4112 HANDLE done = request->done;
4113#endif
4114 DWORD err, ret;
4115
4117#ifdef __REACTOS__
4119#else
4121#endif
4122 {
4123 MSG msg;
4124 while (PeekMessageW( &msg, NULL, 0, 0, PM_REMOVE ))
4125 {
4128 }
4129 }
4130 switch (err)
4131 {
4132 case WAIT_OBJECT_0:
4133 ret = request->error;
4134 break;
4135 case WAIT_TIMEOUT:
4137 break;
4138 default:
4139 ret = GetLastError();
4140 break;
4141 }
4143#ifndef __REACTOS__
4144 if (err == WAIT_OBJECT_0) request->proc_running = FALSE;
4145#endif
4146 return ret;
4147}
4148
4150 IWinHttpRequest *iface,
4151 VARIANT body )
4152{
4154 HRESULT hr;
4155
4156 TRACE("%p, %s\n", request, debugstr_variant(&body));
4157
4159 if (request->state < REQUEST_STATE_OPEN)
4160 {
4163 }
4164 if (request->state >= REQUEST_STATE_SENT)
4165 {
4167 return S_OK;
4168 }
4169 VariantClear( &request->data );
4170 if ((hr = VariantCopyInd( &request->data, &body )) != S_OK)
4171 {
4173 return hr;
4174 }
4175#ifdef __REACTOS__
4176 if (!(request->thread = CreateThread( NULL, 0, send_and_receive_proc, request, 0, NULL )))
4177#else
4178 if (!TrySubmitThreadpoolCallback( send_and_receive_proc, request, NULL ))
4179#endif
4180 {
4182 return HRESULT_FROM_WIN32( GetLastError() );
4183 }
4184#ifndef __REACTOS__
4185 request->proc_running = TRUE;
4186#endif
4187 if (!request->async)
4188 {
4190 }
4192 return hr;
4193}
4194
4196 IWinHttpRequest *iface,
4197 LONG *status )
4198{
4201
4202 TRACE("%p, %p\n", request, status);
4203
4204 if (!status) return E_INVALIDARG;
4205
4207 if (request->state < REQUEST_STATE_SENT)
4208 {
4210 goto done;
4211 }
4213 if (!WinHttpQueryHeaders( request->hrequest, flags, NULL, &status_code, &len, &index ))
4214 {
4215 err = GetLastError();
4216 goto done;
4217 }
4219
4220done:
4222 return HRESULT_FROM_WIN32( err );
4223}
4224
4226 IWinHttpRequest *iface,
4227 BSTR *status )
4228{
4230 DWORD err = ERROR_SUCCESS, len = 0, index = 0;
4231
4232 TRACE("%p, %p\n", request, status);
4233
4234 if (!status) return E_INVALIDARG;
4235
4237 if (request->state < REQUEST_STATE_SENT)
4238 {
4240 goto done;
4241 }
4243 {
4244 err = GetLastError();
4245 if (err != ERROR_INSUFFICIENT_BUFFER) goto done;
4246 }
4247 if (!(*status = SysAllocStringLen( NULL, len / sizeof(WCHAR) )))
4248 {
4250 goto done;
4251 }
4252 index = 0;
4255 {
4256 err = GetLastError();
4258 }
4259done:
4261 return HRESULT_FROM_WIN32( err );
4262}
4263
4265{
4266 static const WCHAR utf8W[] = {'u','t','f','-','8',0};
4267 static const WCHAR charsetW[] = {'c','h','a','r','s','e','t',0};
4268 WCHAR *buffer, *p;
4269 DWORD size;
4270
4271 *codepage = CP_ACP;
4274 {
4275 if (!(buffer = heap_alloc( size ))) return ERROR_OUTOFMEMORY;
4277 {
4278 return GetLastError();
4279 }
4280 if ((p = strstrW( buffer, charsetW )))
4281 {
4282 p += strlenW( charsetW );
4283 while (*p == ' ') p++;
4284 if (*p++ == '=')
4285 {
4286 while (*p == ' ') p++;
4287 if (!strcmpiW( p, utf8W )) *codepage = CP_UTF8;
4288 }
4289 }
4290 heap_free( buffer );
4291 }
4292 return ERROR_SUCCESS;
4293}
4294
4296 IWinHttpRequest *iface,
4297 BSTR *body )
4298{
4300 UINT codepage;
4302 int len;
4303
4304 TRACE("%p, %p\n", request, body);
4305
4306 if (!body) return E_INVALIDARG;
4307
4309 if (request->state < REQUEST_STATE_SENT)
4310 {
4312 goto done;
4313 }
4314 if ((err = request_get_codepage( request, &codepage ))) goto done;
4315 len = MultiByteToWideChar( codepage, 0, request->buffer, request->offset, NULL, 0 );
4316 if (!(*body = SysAllocStringLen( NULL, len )))
4317 {
4319 goto done;
4320 }
4321 MultiByteToWideChar( codepage, 0, request->buffer, request->offset, *body, len );
4322 (*body)[len] = 0;
4323
4324done:
4326 return HRESULT_FROM_WIN32( err );
4327}
4328
4330 IWinHttpRequest *iface,
4331 VARIANT *body )
4332{
4334 SAFEARRAY *sa;
4335 HRESULT hr;
4337 char *ptr;
4338
4339 TRACE("%p, %p\n", request, body);
4340
4341 if (!body) return E_INVALIDARG;
4342
4344 if (request->state < REQUEST_STATE_SENT)
4345 {
4347 goto done;
4348 }
4349 if (!(sa = SafeArrayCreateVector( VT_UI1, 0, request->offset )))
4350 {
4352 goto done;
4353 }
4354 if ((hr = SafeArrayAccessData( sa, (void **)&ptr )) != S_OK)
4355 {
4358 return hr;
4359 }
4360 memcpy( ptr, request->buffer, request->offset );
4361 if ((hr = SafeArrayUnaccessData( sa )) != S_OK)
4362 {
4365 return hr;
4366 }
4367 V_VT( body ) = VT_ARRAY|VT_UI1;
4368 V_ARRAY( body ) = sa;
4369
4370done:
4372 return HRESULT_FROM_WIN32( err );
4373}
4374
4375struct stream
4376{
4379 char *data;
4381};
4382
4383static inline struct stream *impl_from_IStream( IStream *iface )
4384{
4385 return CONTAINING_RECORD( iface, struct stream, IStream_iface );
4386}
4387
4389{
4390 struct stream *stream = impl_from_IStream( iface );
4391
4392 TRACE("%p, %s, %p\n", stream, debugstr_guid(riid), obj);
4393
4394 if (IsEqualGUID( riid, &IID_IStream ) || IsEqualGUID( riid, &IID_IUnknown ))
4395 {
4396 *obj = iface;
4397 }
4398 else
4399 {
4400 FIXME("interface %s not implemented\n", debugstr_guid(riid));
4401 return E_NOINTERFACE;
4402 }
4403 IStream_AddRef( iface );
4404 return S_OK;
4405}
4406
4408{
4409 struct stream *stream = impl_from_IStream( iface );
4410 return InterlockedIncrement( &stream->refs );
4411}
4412
4414{
4415 struct stream *stream = impl_from_IStream( iface );
4417 if (!refs)
4418 {
4419 heap_free( stream->data );
4420 heap_free( stream );
4421 }
4422 return refs;
4423}
4424
4426{
4427 struct stream *stream = impl_from_IStream( iface );
4428 ULONG size;
4429
4430 if (stream->pos.QuadPart >= stream->size.QuadPart)
4431 {
4432 *read = 0;
4433 return S_FALSE;
4434 }
4435
4436 size = min( stream->size.QuadPart - stream->pos.QuadPart, len );
4438 stream->pos.QuadPart += size;
4439 *read = size;
4440
4441 return S_OK;
4442}
4443
4444static HRESULT WINAPI stream_Write( IStream *iface, const void *buf, ULONG len, ULONG *written )
4445{
4446 FIXME("\n");
4447 return E_NOTIMPL;
4448}
4449
4451{
4452 struct stream *stream = impl_from_IStream( iface );
4453
4454 if (origin == STREAM_SEEK_SET)
4455 stream->pos.QuadPart = move.QuadPart;
4456 else if (origin == STREAM_SEEK_CUR)
4457 stream->pos.QuadPart += move.QuadPart;
4458 else if (origin == STREAM_SEEK_END)
4459 stream->pos.QuadPart = stream->size.QuadPart - move.QuadPart;
4460
4461 if (newpos) newpos->QuadPart = stream->pos.QuadPart;
4462 return S_OK;
4463}
4464
4466{
4467 FIXME("\n");
4468 return E_NOTIMPL;
4469}
4470
4472 ULARGE_INTEGER *written )
4473{
4474 FIXME("\n");
4475 return E_NOTIMPL;
4476}
4477
4479{
4480 FIXME("\n");
4481 return E_NOTIMPL;
4482}
4483
4485{
4486 FIXME("\n");
4487 return E_NOTIMPL;
4488}
4489
4491{
4492 FIXME("\n");
4493 return E_NOTIMPL;
4494}
4495
4497{
4498 FIXME("\n");
4499 return E_NOTIMPL;
4500}
4501
4502static HRESULT WINAPI stream_Stat( IStream *iface, STATSTG *stg, DWORD flag )
4503{
4504 FIXME("\n");
4505 return E_NOTIMPL;
4506}
4507
4509{
4510 FIXME("\n");
4511 return E_NOTIMPL;
4512}
4513
4514static const IStreamVtbl stream_vtbl =
4515{
4530};
4531
4533 IWinHttpRequest *iface,
4534 VARIANT *body )
4535{
4538 struct stream *stream;
4539
4540 TRACE("%p, %p\n", request, body);
4541
4542 if (!body) return E_INVALIDARG;
4543
4545 if (request->state < REQUEST_STATE_SENT)
4546 {
4548 goto done;
4549 }
4550 if (!(stream = heap_alloc( sizeof(*stream) )))
4551 {
4553 goto done;
4554 }
4555 stream->IStream_iface.lpVtbl = &stream_vtbl;
4556 stream->refs = 1;
4557 if (!(stream->data = heap_alloc( request->offset )))
4558 {
4559 heap_free( stream );
4561 goto done;
4562 }
4563 memcpy( stream->data, request->buffer, request->offset );
4564 stream->pos.QuadPart = 0;
4565 stream->size.QuadPart = request->offset;
4566 V_VT( body ) = VT_UNKNOWN;
4568
4569done:
4571 return HRESULT_FROM_WIN32( err );
4572}
4573
4575 IWinHttpRequest *iface,
4576 WinHttpRequestOption option,
4577 VARIANT *value )
4578{
4580 HRESULT hr = S_OK;
4581
4582 TRACE("%p, %u, %p\n", request, option, value);
4583
4585 switch (option)
4586 {
4587 case WinHttpRequestOption_URLCodePage:
4588 V_VT( value ) = VT_I4;
4589 V_I4( value ) = request->url_codepage;
4590 break;
4591 default:
4592 FIXME("unimplemented option %u\n", option);
4593 hr = E_NOTIMPL;
4594 break;
4595 }
4597 return hr;
4598}
4599
4601 IWinHttpRequest *iface,
4602 WinHttpRequestOption option,
4603 VARIANT value )
4604{
4606 HRESULT hr = S_OK;
4607
4608 TRACE("%p, %u, %s\n", request, option, debugstr_variant(&value));
4609
4611 switch (option)
4612 {
4613 case WinHttpRequestOption_EnableRedirects:
4614 {
4615 if (V_BOOL( &value ))
4616 request->disable_feature &= ~WINHTTP_DISABLE_REDIRECTS;
4617 else
4618 request->disable_feature |= WINHTTP_DISABLE_REDIRECTS;
4619 break;
4620 }
4621 case WinHttpRequestOption_URLCodePage:
4622 {
4623 static const WCHAR utf8W[] = {'u','t','f','-','8',0};
4624 VARIANT cp;
4625
4626 VariantInit( &cp );
4627 hr = VariantChangeType( &cp, &value, 0, VT_UI4 );
4628 if (SUCCEEDED( hr ))
4629 {
4630 request->url_codepage = V_UI4( &cp );
4631 TRACE("URL codepage: %u\n", request->url_codepage);
4632 }
4633 else if (V_VT( &value ) == VT_BSTR && !strcmpiW( V_BSTR( &value ), utf8W ))
4634 {
4635 TRACE("URL codepage: UTF-8\n");
4636 request->url_codepage = CP_UTF8;
4637 hr = S_OK;
4638 }
4639 else
4640 FIXME("URL codepage %s is not recognized\n", debugstr_variant( &value ));
4641 break;
4642 }
4643 default:
4644 FIXME("unimplemented option %u\n", option);
4645 hr = E_NOTIMPL;
4646 break;
4647 }
4649 return hr;
4650}
4651
4653 IWinHttpRequest *iface,
4655 VARIANT_BOOL *succeeded )
4656{
4658 DWORD err, msecs = (V_I4(&timeout) == -1) ? INFINITE : V_I4(&timeout) * 1000;
4659
4660 TRACE("%p, %s, %p\n", request, debugstr_variant(&timeout), succeeded);
4661
4664 {
4666 return S_OK;
4667 }
4668 switch ((err = request_wait( request, msecs )))
4669 {
4670 case ERROR_TIMEOUT:
4671 if (succeeded) *succeeded = VARIANT_FALSE;
4673 break;
4674
4675 default:
4676 if (succeeded) *succeeded = VARIANT_TRUE;
4677 break;
4678 }
4680 return HRESULT_FROM_WIN32( err );
4681}
4682
4684 IWinHttpRequest *iface )
4685{
4687
4688 TRACE("%p\n", request);
4689
4693 return S_OK;
4694}
4695
4697 IWinHttpRequest *iface,
4702{
4704
4706
4713 return S_OK;
4714}
4715
4717 IWinHttpRequest *iface,
4718 BSTR certificate )
4719{
4720 FIXME("\n");
4721 return E_NOTIMPL;
4722}
4723
4725 IWinHttpRequest *iface,
4726 WinHttpRequestAutoLogonPolicy policy )
4727{
4729 HRESULT hr = S_OK;
4730
4731 TRACE("%p, %u\n", request, policy );
4732
4734 switch (policy)
4735 {
4736 case AutoLogonPolicy_Always:
4738 break;
4739 case AutoLogonPolicy_OnlyIfBypassProxy:
4741 break;
4742 case AutoLogonPolicy_Never:
4744 break;
4745 default: hr = E_INVALIDARG;
4746 break;
4747 }
4749 return hr;
4750}
4751
4752static const struct IWinHttpRequestVtbl winhttp_request_vtbl =
4753{
4780};
4781
4783{
4784 struct winhttp_request *request;
4785
4786 TRACE("%p\n", obj);
4787
4788 if (!(request = heap_alloc_zero( sizeof(*request) ))) return E_OUTOFMEMORY;
4789 request->IWinHttpRequest_iface.lpVtbl = &winhttp_request_vtbl;
4790 request->refs = 1;
4792 request->cs.DebugInfo->Spare[0] = (DWORD_PTR)(__FILE__ ": winhttp_request.cs");
4794
4795 *obj = &request->IWinHttpRequest_iface;
4796 TRACE("returning iface %p\n", *obj);
4797 return S_OK;
4798}
ULONGLONG WINAPI GetTickCount64(VOID)
Definition: GetTickCount64.c:9
@ optional
Definition: SystemMenu.c:34
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
char * strchr(const char *String, int ch)
Definition: utclib.c:501
#define read
Definition: acwin.h:96
#define close
Definition: acwin.h:98
static struct sockaddr_in sa
Definition: adnsresfilter.c:69
static ITypeLib * typelib
Definition: apps.c:108
static void * heap_alloc(size_t len)
Definition: appwiz.h:66
static BOOL heap_free(void *mem)
Definition: appwiz.h:76
static void * heap_realloc(void *mem, size_t len)
Definition: appwiz.h:71
#define InterlockedIncrement
Definition: armddk.h:53
#define InterlockedDecrement
Definition: armddk.h:52
#define msg(x)
Definition: auth_time.c:54
#define WINE_DEFAULT_DEBUG_CHANNEL(t)
Definition: precomp.h:23
static WCHAR * strdupW(const WCHAR *src)
Definition: main.c:92
#define index(s, c)
Definition: various.h:29
void user(int argc, const char *argv[])
Definition: cmds.c:1350
char * hostname
Definition: ftp.c:88
#define ARRAY_SIZE(A)
Definition: main.h:33
static void list_remove(struct list_entry *entry)
Definition: list.h:90
static int list_empty(struct list_entry *head)
Definition: list.h:58
static void list_add_tail(struct list_entry *head, struct list_entry *entry)
Definition: list.h:83
static void list_add_head(struct list_entry *head, struct list_entry *entry)
Definition: list.h:76
static void list_init(struct list_entry *head)
Definition: list.h:51
static HANDLE thread
Definition: service.c:33
const GUID IID_IUnknown
#define FIXME(fmt,...)
Definition: debug.h:111
#define WARN(fmt,...)
Definition: debug.h:112
#define ERR(fmt,...)
Definition: debug.h:110
Definition: list.h:37
static const WCHAR proxy_server[]
Definition: connections.c:40
#define WAIT_TIMEOUT
Definition: dderror.h:14
#define ERROR_INSUFFICIENT_BUFFER
Definition: dderror.h:10
#define E_OUTOFMEMORY
Definition: ddrawi.h:100
#define E_INVALIDARG
Definition: ddrawi.h:101
#define E_NOTIMPL
Definition: ddrawi.h:99
#define ERROR_OUTOFMEMORY
Definition: deptool.c:13
#define ERROR_SUCCESS
Definition: deptool.c:10
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
static HINSTANCE instance
Definition: main.c:40
BOOL WINAPI CertFreeCertificateContext(PCCERT_CONTEXT pCertContext)
Definition: cert.c:371
static WCHAR available[MAX_STRING_RESOURCE_LEN]
Definition: object.c:2336
static const WCHAR crlf[]
Definition: object.c:1018
#define CloseHandle
Definition: compat.h:739
#define ERROR_INVALID_PARAMETER
Definition: compat.h:101
#define CP_ACP
Definition: compat.h:109
#define SetLastError(x)
Definition: compat.h:752
static __inline const char * debugstr_an(const char *s, int n)
Definition: compat.h:55
#define FreeLibrary(x)
Definition: compat.h:748
OLECHAR * BSTR
Definition: compat.h:2293
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
#define CALLBACK
Definition: compat.h:35
#define WideCharToMultiByte
Definition: compat.h:111
short VARIANT_BOOL
Definition: compat.h:2290
#define MultiByteToWideChar
Definition: compat.h:110
@ VT_BSTR
Definition: compat.h:2303
@ VT_UNKNOWN
Definition: compat.h:2308
@ VT_ARRAY
Definition: compat.h:2341
@ VT_I4
Definition: compat.h:2298
@ VT_BOOL
Definition: compat.h:2306
@ VT_UI4
Definition: compat.h:2313
@ VT_UI1
Definition: compat.h:2311
static const WCHAR getW[]
Definition: object.c:50
static char * strdupWA(const WCHAR *src)
Definition: main.c:91
static WCHAR * strdupAW(const char *src, int len)
Definition: main.c:76
BOOL WINAPI GetModuleHandleExW(IN DWORD dwFlags, IN LPCWSTR lpwModuleName OPTIONAL, OUT HMODULE *phModule)
Definition: loader.c:866
VOID WINAPI FreeLibraryAndExitThread(HMODULE hLibModule, DWORD dwExitCode)
Definition: loader.c:507
HANDLE WINAPI DECLSPEC_HOTPATCH CreateThread(IN LPSECURITY_ATTRIBUTES lpThreadAttributes, IN DWORD dwStackSize, IN LPTHREAD_START_ROUTINE lpStartAddress, IN LPVOID lpParameter, IN DWORD dwCreationFlags, OUT LPDWORD lpThreadId)
Definition: thread.c:137
static const WCHAR slashW[]
Definition: devenum.c:59
HRESULT WINAPI DispGetParam(DISPPARAMS *pdispparams, UINT position, VARTYPE vtTarg, VARIANT *pvarResult, UINT *puArgErr)
Definition: dispatch.c:116
HRESULT WINAPI SafeArrayGetUBound(SAFEARRAY *psa, UINT nDim, LONG *plUbound)
Definition: safearray.c:1033
HRESULT WINAPI SafeArrayAccessData(SAFEARRAY *psa, void **ppvData)
Definition: safearray.c:1137
HRESULT WINAPI SafeArrayUnaccessData(SAFEARRAY *psa)
Definition: safearray.c:1168
SAFEARRAY *WINAPI SafeArrayCreateVector(VARTYPE vt, LONG lLbound, ULONG cElements)
Definition: safearray.c:677
HRESULT WINAPI SafeArrayDestroy(SAFEARRAY *psa)
Definition: safearray.c:1347
HRESULT WINAPI LoadRegTypeLib(REFGUID rguid, WORD wVerMajor, WORD wVerMinor, LCID lcid, ITypeLib **ppTLib)
Definition: typelib.c:531
static const WCHAR typeW[]
Definition: name.c:51
static const WCHAR versionW[]
Definition: name.c:52
USHORT port
Definition: uri.c:228
unsigned int(__cdecl typeof(jpeg_read_scanlines))(struct jpeg_decompress_struct *
Definition: typeof.h:31
struct object_header * grab_object(HINTERNET hinternet)
Definition: handle.c:56
void release_object(struct object_header *hdr)
Definition: handle.c:72
struct object_header * addref_object(struct object_header *hdr)
Definition: handle.c:49
HINSTANCE winhttp_instance
Definition: main.c:34
ULONG netconn_query_data_available(struct netconn *conn)
Definition: net.c:591
BOOL netconn_secure_connect(struct netconn *conn, WCHAR *hostname, DWORD security_flags, CredHandle *cred_handle, BOOL check_revocation)
Definition: net.c:264
const void * netconn_get_certificate(struct netconn *conn)
Definition: net.c:758
void netconn_close(struct netconn *conn)
Definition: net.c:250
BOOL netconn_recv(struct netconn *conn, void *buf, size_t len, int flags, int *recvd)
Definition: net.c:539
BOOL netconn_is_alive(struct netconn *netconn)
Definition: net.c:608
BOOL netconn_resolve(WCHAR *hostname, INTERNET_PORT port, struct sockaddr_storage *addr, int timeout)
Definition: net.c:725
BOOL netconn_send(struct netconn *conn, const void *msg, size_t len, int *sent)
Definition: net.c:424
DWORD netconn_set_timeout(struct netconn *netconn, BOOL send, int value)
Definition: net.c:596
struct netconn * netconn_create(struct hostdata *host, const struct sockaddr_storage *sockaddr, int timeout)
Definition: net.c:186
void send_callback(struct object_header *hdr, DWORD status, void *info, DWORD buflen)
Definition: session.c:55
HINTERNET WINAPI WinHttpOpen(LPCWSTR agent, DWORD access, LPCWSTR proxy, LPCWSTR bypass, DWORD flags)
Definition: session.c:250
HINTERNET WINAPI WinHttpConnect(HINTERNET hsession, LPCWSTR server, INTERNET_PORT port, DWORD reserved)
Definition: session.c:541
BOOL set_server_for_hostname(struct connect *connect, const WCHAR *server, INTERNET_PORT port)
Definition: session.c:476
BOOL WINAPI WinHttpCloseHandle(HINTERNET handle)
Definition: session.c:1195
BOOL WINAPI WinHttpSetTimeouts(HINTERNET handle, int resolve, int connect, int send, int receive)
Definition: session.c:2081
HINTERNET WINAPI WinHttpOpenRequest(HINTERNET hconnect, LPCWSTR verb, LPCWSTR object, LPCWSTR version, LPCWSTR referrer, LPCWSTR *types, DWORD flags)
Definition: session.c:1117
BOOL WINAPI WinHttpSetOption(HINTERNET handle, DWORD option, LPVOID buffer, DWORD buflen)
Definition: session.c:1312
BOOL WINAPI WinHttpTimeToSystemTime(LPCWSTR string, SYSTEMTIME *time)
Definition: session.c:2188
WINHTTP_STATUS_CALLBACK WINAPI WinHttpSetStatusCallback(HINTERNET handle, WINHTTP_STATUS_CALLBACK callback, DWORD flags, DWORD_PTR reserved)
Definition: session.c:2056
BOOL WINAPI WinHttpCrackUrl(LPCWSTR url, DWORD len, DWORD flags, LPURL_COMPONENTSW uc)
Definition: url.c:179
static ULONG connect_timeout
Definition: internet.c:98
#define assert(x)
Definition: debug.h:53
method
Definition: dragdrop.c:54
r reserved
Definition: btrfs.c:3006
ULONG to_read
Definition: btrfs.c:4260
#define AF_INET
Definition: tcpip.h:117
#define INFINITE
Definition: serial.h:102
unsigned int BOOL
Definition: ntddk_ex.h:94
unsigned long DWORD
Definition: ntddk_ex.h:95
unsigned short WORD
Definition: ntddk_ex.h:93
time_t now
Definition: finger.c:65
WDF_INTERRUPT_POLICY policy
GLuint start
Definition: gl.h:1545
GLint level
Definition: gl.h:1546
GLint GLint GLint GLint GLint x
Definition: gl.h:1548
GLdouble s
Definition: gl.h:2039
GLuint GLuint end
Definition: gl.h:1545
GLuint GLuint GLsizei count
Definition: gl.h:1545
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl.h:1950
GLdouble GLdouble GLdouble r
Definition: gl.h:2055
GLdouble GLdouble GLdouble GLdouble q
Definition: gl.h:2063
GLsizeiptr size
Definition: glext.h:5919
GLdouble n
Definition: glext.h:7729
GLenum src
Definition: glext.h:6340
GLuint GLuint * names
Definition: glext.h:11545
GLuint buffer
Definition: glext.h:5915
const GLubyte * c
Definition: glext.h:8905
GLuint index
Definition: glext.h:6031
GLenum GLint GLuint mask
Definition: glext.h:6028
GLenum const GLfloat * params
Definition: glext.h:5645
GLenum GLuint GLenum GLsizei const GLchar * buf
Definition: glext.h:7751
GLuint in
Definition: glext.h:9616
GLenum GLenum dst
Definition: glext.h:6340
GLbitfield flags
Definition: glext.h:7161
GLuint GLsizei GLsizei * length
Definition: glext.h:6040
const GLint * first
Definition: glext.h:5794
GLenum const GLvoid * addr
Definition: glext.h:9621
GLfloat GLfloat p
Definition: glext.h:8902
GLfloat param
Definition: glext.h:5796
GLenum GLsizei len
Definition: glext.h:6722
GLubyte GLubyte GLubyte GLubyte w
Definition: glext.h:6102
GLuint64EXT * result
Definition: glext.h:11304
GLuint id
Definition: glext.h:5910
GLintptr offset
Definition: glext.h:5920
GLenum target
Definition: glext.h:7315
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean flag
Definition: glfuncs.h:52
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble * u
Definition: glfuncs.h:240
type_id
static const WCHAR headW[]
Definition: htmlelem.c:28
static const WCHAR charsetW[]
Definition: htmlmeta.c:149
#define DISPID_HTTPREQUEST_OPTION
Definition: httprequestid.h:28
int hex(char ch)
static const WCHAR emptyW[]
Definition: navigate.c:40
REFIID riid
Definition: atlbase.h:39
#define InterlockedCompareExchangePointer
Definition: interlocked.h:129
#define S_OK
Definition: intsafe.h:52
#define SUCCEEDED(hr)
Definition: intsafe.h:50
#define FAILED(hr)
Definition: intsafe.h:51
voidpf uLong int origin
Definition: ioapi.h:144
char hdr[14]
Definition: iptest.cpp:33
uint32_t entry
Definition: isohybrid.c:63
#define debugstr_guid
Definition: kernel32.h:35
#define debugstr_a
Definition: kernel32.h:31
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
#define location(file, line)
Definition: kmtest.h:18
if(dx< 0)
Definition: linetemp.h:194
POINT cp
Definition: magnifier.c:59
static const WCHAR text_plainW[]
Definition: mimefilter.c:507
#define error(str)
Definition: mkdosfs.c:1605
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
#define memmove(s1, s2, n)
Definition: mkisofs.h:881
#define memchr(s, c, n)
Definition: mkisofs.h:875
char string[160]
Definition: util.h:11
static PVOID ptr
Definition: dispmode.c:27
static const WCHAR url[]
Definition: encode.c:1432
static unsigned int number
Definition: dsound.c:1479
static const char * debugstr_variant(const VARIANT *var)
Definition: container.c:46
static struct _PeImage bin
static JOBOBJECTINFOCLASS LPVOID DWORD LPDWORD ret_len
Definition: process.c:79
static TfClientId tid
static LPOLESTR
Definition: stg_prop.c:27
static VARIANTARG static DISPID
Definition: ordinal.c:52
static const WCHAR user_agentW[]
Definition: protocol.c:138
char strA[12]
Definition: clipboard.c:2028
DWORD exp
Definition: msg.c:16058
static WCHAR http[]
Definition: url.c:30
static WCHAR password[]
Definition: url.c:33
static WCHAR username[]
Definition: url.c:32
static void close_connection(void)
Definition: http.c:5576
#define min(a, b)
Definition: monoChain.cc:55
int notify
Definition: msacm.c:1366
static const WCHAR utf8W[]
Definition: mxwriter.c:86
static const WCHAR crlfW[]
Definition: mxwriter.c:47
static const WCHAR spaceW[]
Definition: mxwriter.c:44
unsigned int UINT
Definition: ndis.h:50
static BOOL ensure_cred_handle(void)
#define DWORD
Definition: nt_native.h:44
#define LOCALE_SYSTEM_DEFAULT
void WINAPI DECLSPEC_HOTPATCH SysFreeString(BSTR str)
Definition: oleaut.c:271
BSTR WINAPI SysAllocStringLen(const OLECHAR *str, unsigned int len)
Definition: oleaut.c:339
#define V_BOOL(A)
Definition: oleauto.h:224
#define V_ARRAY(A)
Definition: oleauto.h:222
#define V_UNKNOWN(A)
Definition: oleauto.h:281
#define DISPATCH_PROPERTYPUT
Definition: oleauto.h:1008
#define DISPATCH_METHOD
Definition: oleauto.h:1006
#define V_VT(A)
Definition: oleauto.h:211
#define V_BSTR(A)
Definition: oleauto.h:226
#define V_I4(A)
Definition: oleauto.h:247
#define V_UI4(A)
Definition: oleauto.h:270
#define DISPATCH_PROPERTYGET
Definition: oleauto.h:1007
const GUID IID_IDispatch
long LONG
Definition: pedump.c:60
#define IsEqualGUID(rguid1, rguid2)
Definition: guiddef.h:147
#define IsEqualIID(riid1, riid2)
Definition: guiddef.h:95
#define REFIID
Definition: guiddef.h:118
#define IID_NULL
Definition: guiddef.h:98
LONG SECURITY_STATUS
Definition: sspi.h:34
#define SecIsValidHandle(x)
Definition: sspi.h:63
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:291
#define SECBUFFER_TOKEN
Definition: sspi.h:161
#define SECURITY_NETWORK_DREP
Definition: sspi.h:474
#define ISC_REQ_DELEGATE
Definition: sspi.h:362
#define UNISP_NAME_W
Definition: sspi.h:38
#define ISC_REQ_MUTUAL_AUTH
Definition: sspi.h:363
#define SecInvalidateHandle(x)
Definition: sspi.h:58
WCHAR SEC_WCHAR
Definition: sspi.h:29
#define ISC_REQ_CONNECTION
Definition: sspi.h:373
#define ISC_REQ_USE_DCE_STYLE
Definition: sspi.h:371
#define atoiW(s)
Definition: unicode.h:54
#define strncmpiW(s1, s2, n)
Definition: unicode.h:40
#define strcmpW(s1, s2)
Definition: unicode.h:38
#define strstrW(d, s)
Definition: unicode.h:32
#define strchrW(s, c)
Definition: unicode.h:34
#define strcmpiW(s1, s2)
Definition: unicode.h:39
#define strlenW(s)
Definition: unicode.h:28
#define strrchrW(s, c)
Definition: unicode.h:35
#define strcatW(d, s)
Definition: unicode.h:30
#define sprintfW
Definition: unicode.h:58
#define strcpyW(d, s)
Definition: unicode.h:29
#define err(...)
static FILE * out
Definition: regtests2xml.c:44
static const WCHAR attr_status[]
Definition: request.c:94
static HRESULT WINAPI stream_LockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER len, DWORD locktype)
Definition: request.c:4490
static const WCHAR attr_upgrade[]
Definition: request.c:97
static HRESULT request_receive(struct winhttp_request *request)
Definition: request.c:3929
static BOOL secure_proxy_connect(struct request *request)
Definition: request.c:1442
static const WCHAR attr_vary[]
Definition: request.c:100
static BOOL discard_eol(struct request *request, BOOL notify)
Definition: request.c:1891
static char * build_wire_request(struct request *request, DWORD *len)
Definition: request.c:2203
static const WCHAR attr_expect[]
Definition: request.c:72
static BOOL need_escape(char ch, enum escape_flags flags)
Definition: request.c:2098
static const WCHAR attr_if_none_match[]
Definition: request.c:77
static const WCHAR attr_user_agent[]
Definition: request.c:99
static WCHAR * build_request_string(struct request *request)
Definition: request.c:603
static const WCHAR attr_location[]
Definition: request.c:81
static const WCHAR attr_proxy_authorization[]
Definition: request.c:86
static const WCHAR attr_content_length[]
Definition: request.c:62
static HRESULT WINAPI winhttp_request_SetClientCertificate(IWinHttpRequest *iface, BSTR certificate)
Definition: request.c:4716
static const WCHAR attr_accept_charset[]
Definition: request.c:49
static const WCHAR digestW[]
Definition: request.c:885
static BOOL delete_header(struct request *request, DWORD index)
Definition: request.c:415
static const WCHAR attr_host[]
Definition: request.c:74
static const WCHAR attr_from[]
Definition: request.c:70
static HRESULT WINAPI winhttp_request_SetRequestHeader(IWinHttpRequest *iface, BSTR header, BSTR value)
Definition: request.c:3731
BOOL WINAPI WinHttpWriteData(HINTERNET hrequest, LPCVOID buffer, DWORD to_write, LPDWORD written)
Definition: request.c:3125
static HRESULT WINAPI winhttp_request_GetIDsOfNames(IWinHttpRequest *iface, REFIID riid, LPOLESTR *names, UINT count, LCID lcid, DISPID *dispid)
Definition: request.c:3402
static HRESULT WINAPI stream_Stat(IStream *iface, STATSTG *stg, DWORD flag)
Definition: request.c:4502
static HRESULT WINAPI winhttp_request_GetTypeInfo(IWinHttpRequest *iface, UINT index, LCID lcid, ITypeInfo **info)
Definition: request.c:3390
static const WCHAR attr_referer[]
Definition: request.c:90
static const WCHAR attr_allow[]
Definition: request.c:54
static void request_set_utf8_content_type(struct winhttp_request *request)
Definition: request.c:4008
static const WCHAR attr_pragma[]
Definition: request.c:84
static HRESULT WINAPI winhttp_request_put_Option(IWinHttpRequest *iface, WinHttpRequestOption option, VARIANT value)
Definition: request.c:4600
static const WCHAR attr_set_cookie[]
Definition: request.c:93
static BOOL handle_authorization(struct request *request, DWORD status)
Definition: request.c:2469
static HRESULT WINAPI winhttp_request_get_StatusText(IWinHttpRequest *iface, BSTR *status)
Definition: request.c:4225
static BOOL valid_token_char(WCHAR c)
Definition: request.c:304
static void CALLBACK task_proc(TP_CALLBACK_INSTANCE *instance, void *ctx)
Definition: request.c:201
static DWORD auth_scheme_from_header(const WCHAR *header)
Definition: request.c:911
static ULONG WINAPI stream_AddRef(IStream *iface)
Definition: request.c:4407
static void wait_set_status_callback(struct winhttp_request *request, DWORD status)
Definition: request.c:3886
static const WCHAR passportW[]
Definition: request.c:884
static BOOL do_authorization(struct request *request, DWORD target, DWORD scheme_flag)
Definition: request.c:1163
static ULONG WINAPI winhttp_request_Release(IWinHttpRequest *iface)
Definition: request.c:3274
static DWORD request_get_codepage(struct winhttp_request *request, UINT *codepage)
Definition: request.c:4264
static const WCHAR attr_content_base[]
Definition: request.c:58
static struct list connection_pool
Definition: request.c:1492
static BOOL handle_passport_redirect(struct request *request)
Definition: request.c:2824
static HRESULT WINAPI winhttp_request_SetProxy(IWinHttpRequest *iface, HTTPREQUEST_PROXY_SETTING proxy_setting, VARIANT proxy_server, VARIANT bypass_list)
Definition: request.c:3497
BOOL WINAPI WinHttpQueryHeaders(HINTERNET hrequest, DWORD level, LPCWSTR name, LPVOID buffer, LPDWORD buflen, LPDWORD index)
Definition: request.c:856
static const WCHAR attr_accept_ranges[]
Definition: request.c:52
static HRESULT WINAPI winhttp_request_get_ResponseText(IWinHttpRequest *iface, BSTR *body)
Definition: request.c:4295
static HRESULT WINAPI stream_Clone(IStream *iface, IStream **stream)
Definition: request.c:4508
static const WCHAR basicW[]
Definition: request.c:882
static const struct IWinHttpRequestVtbl winhttp_request_vtbl
Definition: request.c:4752
static HRESULT WINAPI winhttp_request_Abort(IWinHttpRequest *iface)
Definition: request.c:4683
#define DEFAULT_KEEP_ALIVE_TIMEOUT
Definition: request.c:46
BOOL process_header(struct request *request, const WCHAR *field, const WCHAR *value, DWORD flags, BOOL request_only)
Definition: request.c:430
static ITypeInfo * winhttp_typeinfo[last_tid]
Definition: request.c:3336
BOOL WINAPI WinHttpAddRequestHeaders(HINTERNET hrequest, LPCWSTR headers, DWORD len, DWORD flags)
Definition: request.c:542
static HRESULT WINAPI stream_CopyTo(IStream *iface, IStream *stream, ULARGE_INTEGER len, ULARGE_INTEGER *read, ULARGE_INTEGER *written)
Definition: request.c:4471
static HRESULT WINAPI winhttp_request_QueryInterface(IWinHttpRequest *iface, REFIID riid, void **obj)
Definition: request.c:3294
static const WCHAR attr_unless_modified_since[]
Definition: request.c:96
static BOOL connection_collector_running
Definition: request.c:1508
static unsigned int decode_base64(const WCHAR *base64, unsigned int len, char *buf)
Definition: request.c:1058
#define ESCAPE_MASK_DISABLE
Definition: request.c:2096
static DWORD set_content_length(struct request *request, DWORD status)
Definition: request.c:2503
static BOOL end_of_read_data(struct request *request)
Definition: request.c:2010
static const WCHAR attr_if_range[]
Definition: request.c:78
BOOL WINAPI WinHttpReadData(HINTERNET hrequest, LPVOID buffer, DWORD to_read, LPDWORD read)
Definition: request.c:3053
static void clear_response_headers(struct request *request)
Definition: request.c:1842
static HRESULT WINAPI winhttp_request_Send(IWinHttpRequest *iface, VARIANT body)
Definition: request.c:4149
static HRESULT WINAPI winhttp_request_get_ResponseStream(IWinHttpRequest *iface, VARIANT *body)
Definition: request.c:4532
static const WCHAR attr_etag[]
Definition: request.c:71
static BOOL add_host_header(struct request *request, DWORD modifier)
Definition: request.c:1819
static BOOL start_next_chunk(struct request *request, BOOL notify)
Definition: request.c:1908
static BOOL get_authvalue(struct request *request, DWORD level, DWORD scheme, WCHAR *buffer, DWORD len)
Definition: request.c:1151
static const WCHAR attr_cookie[]
Definition: request.c:68
static const WCHAR attr_server[]
Definition: request.c:92
const WCHAR * str
Definition: request.c:890
static const WCHAR attr_connection[]
Definition: request.c:57
static const WCHAR negotiateW[]
Definition: request.c:886
static BOOL query_auth_schemes(struct request *request, DWORD level, DWORD *supported, DWORD *first)
Definition: request.c:923
void release_host(struct hostdata *host)
Definition: request.c:1494
static ITypeLib * winhttp_typelib
Definition: request.c:3335
static DWORD get_available_data(struct request *request)
Definition: request.c:2003
static char decode_char(WCHAR c)
Definition: request.c:1048
static const WCHAR attr_mime_version[]
Definition: request.c:83
static void free_header(struct header *header)
Definition: request.c:297
static HRESULT get_typeinfo(enum type_id tid, ITypeInfo **ret)
Definition: request.c:3343
static const WCHAR attr_retry_after[]
Definition: request.c:91
static HRESULT WINAPI winhttp_request_WaitForResponse(IWinHttpRequest *iface, VARIANT timeout, VARIANT_BOOL *succeeded)
Definition: request.c:4652
unsigned int len
Definition: request.c:891
static HRESULT WINAPI stream_UnlockRegion(IStream *iface, ULARGE_INTEGER offset, ULARGE_INTEGER len, DWORD locktype)
Definition: request.c:4496
static const struct @594 auth_schemes[]
static ULONG WINAPI stream_Release(IStream *iface)
Definition: request.c:4413
static void drain_content(struct request *request)
Definition: request.c:2063
#define INITIAL_HEADER_BUFFER_LEN
Definition: request.c:2569
static DWORD request_wait(struct winhttp_request *request, DWORD timeout)
Definition: request.c:4107
static const WCHAR attr_public[]
Definition: request.c:88
static HRESULT WINAPI winhttp_request_SetAutoLogonPolicy(IWinHttpRequest *iface, WinHttpRequestAutoLogonPolicy policy)
Definition: request.c:4724
BOOL WINAPI WinHttpQueryDataAvailable(HINTERNET hrequest, LPDWORD available)
Definition: request.c:3005
static DWORD wait_for_completion(struct winhttp_request *request)
Definition: request.c:3892
static BOOL query_data_available(struct request *request, DWORD *available, BOOL async)
Definition: request.c:2962
static enum auth_scheme scheme_from_flag(DWORD flag)
Definition: request.c:903
static struct authinfo * alloc_authinfo(void)
Definition: request.c:1120
@ last_tid
Definition: request.c:3332
@ IWinHttpRequest_tid
Definition: request.c:3331
static BOOL insert_header(struct request *request, struct header *header)
Definition: request.c:396
static void finished_reading(struct request *request)
Definition: request.c:1975
static HRESULT WINAPI winhttp_request_Open(IWinHttpRequest *iface, BSTR method, BSTR url, VARIANT async)
Definition: request.c:3634
static const WCHAR attr_content_type[]
Definition: request.c:67
static UINT encode_base64(const char *bin, unsigned int len, WCHAR *base64)
Definition: request.c:1007
BOOL add_request_headers(struct request *request, const WCHAR *headers, DWORD len, DWORD flags)
Definition: request.c:495
BOOL WINAPI WinHttpSendRequest(HINTERNET hrequest, LPCWSTR headers, DWORD headers_len, LPVOID optional, DWORD optional_len, DWORD total_len, DWORD_PTR context)
Definition: request.c:2350
static HRESULT WINAPI winhttp_request_GetTypeInfoCount(IWinHttpRequest *iface, UINT *count)
Definition: request.c:3318
static HRESULT WINAPI winhttp_request_SetTimeouts(IWinHttpRequest *iface, LONG resolve_timeout, LONG connect_timeout, LONG send_timeout, LONG receive_timeout)
Definition: request.c:4696
static void reset_request(struct winhttp_request *request)
Definition: request.c:3604
static const WCHAR attr_content_range[]
Definition: request.c:65
static BOOL handle_redirect(struct request *request, DWORD status)
Definition: request.c:2698
static void remove_data(struct request *request, int count)
Definition: request.c:1857
static const WCHAR attr_last_modified[]
Definition: request.c:80
static WCHAR * get_redirect_url(struct request *request, DWORD *len)
Definition: request.c:2684
static DWORD map_secure_protocols(DWORD mask)
Definition: request.c:1594
static void task_write_data(struct task_header *task)
Definition: request.c:3116
static const WCHAR attr_authorization[]
Definition: request.c:55
static struct task_header * dequeue_task(struct request *request)
Definition: request.c:184
static const WCHAR attr_uri[]
Definition: request.c:98
static void initialize_request(struct winhttp_request *request)
Definition: request.c:3589
static void cancel_request(struct winhttp_request *request)
Definition: request.c:3225
static const WCHAR attr_if_match[]
Definition: request.c:75
static const WCHAR attr_date[]
Definition: request.c:69
void release_typelib(void)
Definition: request.c:3378
#define ESCAPE_MASK_PERCENT
Definition: request.c:2095
static const WCHAR attr_expires[]
Definition: request.c:73
static BOOL read_more_data(struct request *request, int maxlen, BOOL notify)
Definition: request.c:1864
static HRESULT WINAPI stream_Revert(IStream *iface)
Definition: request.c:4484
static DWORD escape_string(const char *src, DWORD len, char *dst, enum escape_flags flags)
Definition: request.c:2112
static void CALLBACK wait_status_callback(HINTERNET handle, DWORD_PTR context, DWORD status, LPVOID buffer, DWORD size)
Definition: request.c:3859
BOOL WINAPI WinHttpSetCredentials(HINTERNET hrequest, DWORD target, DWORD scheme, LPCWSTR username, LPCWSTR password, LPVOID params)
Definition: request.c:2442
static BOOL is_passport_request(struct request *request)
Definition: request.c:2809
static BOOL queue_task(struct task_header *task)
Definition: request.c:252
static HRESULT WINAPI winhttp_request_GetResponseHeader(IWinHttpRequest *iface, BSTR header, BSTR *value)
Definition: request.c:3777
static HRESULT WINAPI stream_Seek(IStream *iface, LARGE_INTEGER move, DWORD origin, ULARGE_INTEGER *newpos)
Definition: request.c:4450
static struct winhttp_request * impl_from_IWinHttpRequest(IWinHttpRequest *iface)
Definition: request.c:3212
static HRESULT WINAPI stream_SetSize(IStream *iface, ULARGE_INTEGER newsize)
Definition: request.c:4465
static BOOL refill_buffer(struct request *request, BOOL notify)
Definition: request.c:1951
static BOOL set_credentials(struct request *request, DWORD target, DWORD scheme_flag, const WCHAR *username, const WCHAR *password)
Definition: request.c:2398
static const WCHAR attr_warning[]
Definition: request.c:102
#define ESCAPE_MASK_DEFAULT
Definition: request.c:2093
static const WCHAR attr_proxy_connection[]
Definition: request.c:87
static WCHAR * build_absolute_request_path(struct request *request, const WCHAR **path)
Definition: request.c:573
static void task_read_data(struct task_header *task)
Definition: request.c:3044
static const WCHAR * attribute_table[]
Definition: request.c:105
static const WCHAR attr_proxy_authenticate[]
Definition: request.c:85
static const WCHAR attr_accept_language[]
Definition: request.c:51
static HRESULT WINAPI winhttp_request_GetAllResponseHeaders(IWinHttpRequest *iface, BSTR *headers)
Definition: request.c:3820
static HRESULT WINAPI stream_Write(IStream *iface, const void *buf, ULONG len, ULONG *written)
Definition: request.c:4444
static struct stream * impl_from_IStream(IStream *iface)
Definition: request.c:4383
static void record_cookies(struct request *request)
Definition: request.c:2670
HRESULT WinHttpRequest_create(void **obj)
Definition: request.c:4782
static const WCHAR attr_content_transfer_encoding[]
Definition: request.c:66
static char * build_wire_path(struct request *request, DWORD *ret_len)
Definition: request.c:2159
static CRITICAL_SECTION connection_pool_cs
Definition: request.c:1483
escape_flags
Definition: request.c:2083
@ ESCAPE_FLAG_NON_PRINTABLE
Definition: request.c:2084
@ ESCAPE_FLAG_8BIT
Definition: request.c:2089
@ ESCAPE_FLAG_STRIP_CRLF
Definition: request.c:2090
@ ESCAPE_FLAG_DEL
Definition: request.c:2088
@ ESCAPE_FLAG_SPACE
Definition: request.c:2085
@ ESCAPE_FLAG_PERCENT
Definition: request.c:2086
@ ESCAPE_FLAG_UNSAFE
Definition: request.c:2087
static void CALLBACK connection_collector(TP_CALLBACK_INSTANCE *instance, void *ctx)
Definition: request.c:1513
static BOOL open_connection(struct request *request)
Definition: request.c:1636
static BOOL query_headers(struct request *request, DWORD level, const WCHAR *name, void *buffer, DWORD *buflen, DWORD *index)
Definition: request.c:651
static HRESULT request_send(struct winhttp_request *request)
Definition: request.c:4022
request_state
Definition: request.c:3167
@ REQUEST_STATE_RESPONSE_RECEIVED
Definition: request.c:3172
@ REQUEST_STATE_OPEN
Definition: request.c:3170
@ REQUEST_STATE_INITIALIZED
Definition: request.c:3168
@ REQUEST_STATE_CANCELLED
Definition: request.c:3169
@ REQUEST_STATE_SENT
Definition: request.c:3171
static const WCHAR attr_accept_encoding[]
Definition: request.c:50
static const WCHAR attr_via[]
Definition: request.c:101
static HRESULT WINAPI winhttp_request_get_Option(IWinHttpRequest *iface, WinHttpRequestOption option, VARIANT *value)
Definition: request.c:4574
static HRESULT WINAPI stream_QueryInterface(IStream *iface, REFIID riid, void **obj)
Definition: request.c:4388
static const WCHAR attr_content_id[]
Definition: request.c:60
static const WCHAR attr_if_unmodified_since[]
Definition: request.c:79
static const WCHAR attr_age[]
Definition: request.c:53
static WCHAR * addr_to_str(struct sockaddr_storage *addr)
Definition: request.c:1462
static CRITICAL_SECTION_DEBUG connection_pool_debug
Definition: request.c:1484
void destroy_authinfo(struct authinfo *authinfo)
Definition: request.c:1138
static const WCHAR attr_range[]
Definition: request.c:89
static void task_receive_response(struct task_header *task)
Definition: request.c:2915
static const WCHAR attr_cache_control[]
Definition: request.c:56
static HRESULT WINAPI winhttp_request_get_Status(IWinHttpRequest *iface, LONG *status)
Definition: request.c:4195
static const WCHAR attr_content_md5[]
Definition: request.c:64
static const WCHAR attr_if_modified_since[]
Definition: request.c:76
static const WCHAR attr_content_language[]
Definition: request.c:61
static const WCHAR attr_transfer_encoding[]
Definition: request.c:95
static HRESULT WINAPI stream_Commit(IStream *iface, DWORD flags)
Definition: request.c:4478
static const WCHAR attr_accept[]
Definition: request.c:48
static HRESULT WINAPI stream_Read(IStream *iface, void *buf, ULONG len, ULONG *read)
Definition: request.c:4425
static void CALLBACK send_and_receive_proc(TP_CALLBACK_INSTANCE *instance, void *ctx)
Definition: request.c:4098
static ULONG WINAPI winhttp_request_AddRef(IWinHttpRequest *iface)
Definition: request.c:3217
static REFIID winhttp_tid_id[]
Definition: request.c:3338
static void task_query_data_available(struct task_header *task)
Definition: request.c:2996
static void free_request(struct winhttp_request *request)
Definition: request.c:3254
static const WCHAR attr_max_forwards[]
Definition: request.c:82
static DWORD str_to_wire(const WCHAR *src, int src_len, char *dst, enum escape_flags flags)
Definition: request.c:2143
static const WCHAR ntlmW[]
Definition: request.c:883
static const IStreamVtbl stream_vtbl
Definition: request.c:4514
static void task_send_request(struct task_header *task)
Definition: request.c:2340
static const WCHAR attr_content_encoding[]
Definition: request.c:59
static HRESULT WINAPI winhttp_request_Invoke(IWinHttpRequest *iface, DISPID member, REFIID riid, LCID lcid, WORD flags, DISPPARAMS *params, VARIANT *result, EXCEPINFO *excep_info, UINT *arg_err)
Definition: request.c:3427
DWORD scheme
Definition: request.c:892
static int get_header_index(struct request *request, const WCHAR *field, int requested_index, BOOL request_only)
Definition: request.c:376
static HRESULT WINAPI winhttp_request_get_ResponseBody(IWinHttpRequest *iface, VARIANT *body)
Definition: request.c:4329
BOOL WINAPI WinHttpReceiveResponse(HINTERNET hrequest, LPVOID reserved)
Definition: request.c:2924
static DWORD request_set_parameters(struct winhttp_request *request)
Definition: request.c:3989
static void cache_connection(struct netconn *netconn)
Definition: request.c:1556
static const WCHAR attr_www_authenticate[]
Definition: request.c:103
static HRESULT WINAPI winhttp_request_SetCredentials(IWinHttpRequest *iface, BSTR username, BSTR password, HTTPREQUEST_SETCREDENTIALS_FLAGS flags)
Definition: request.c:3550
static BOOL read_reply(struct request *request)
Definition: request.c:2571
BOOL WINAPI WinHttpQueryAuthSchemes(HINTERNET hrequest, LPDWORD supported, LPDWORD first, LPDWORD target)
Definition: request.c:964
static WCHAR * build_proxy_connect_string(struct request *request)
Definition: request.c:1392
#define MAX_REPLY_LEN
Definition: request.c:2568
static const WCHAR attr_content_location[]
Definition: request.c:63
static struct header * parse_header(const WCHAR *string)
Definition: request.c:325
static BOOL is_secure(RpcConnection_http *httpc)
#define SEC_WINNT_AUTH_IDENTITY_UNICODE
Definition: rpcdce.h:310
#define SP_PROT_TLS1_1_CLIENT
Definition: schannel.h:33
#define SP_PROT_TLS1_CLIENT
Definition: schannel.h:31
#define SCHANNEL_CRED_VERSION
Definition: schannel.h:22
#define SP_PROT_TLS1_2_CLIENT
Definition: schannel.h:34
#define SP_PROT_SSL2_CLIENT
Definition: schannel.h:29
#define SP_PROT_SSL3_CLIENT
Definition: schannel.h:30
DWORD LCID
Definition: nls.h:13
#define CP_UTF8
Definition: nls.h:20
__WINE_SERVER_LIST_INLINE unsigned int list_count(const struct list *list)
Definition: list.h:155
#define LIST_FOR_EACH_ENTRY(elem, list, type, field)
Definition: list.h:198
#define LIST_FOR_EACH_ENTRY_SAFE(cursor, cursor2, list, type, field)
Definition: list.h:204
static const void * body(MD5_CTX *ctx, const void *data, unsigned long size)
Definition: md5.c:100
#define memset(x, y, z)
Definition: compat.h:39
vector< Header * > headers
Definition: sdkparse.cpp:39
HRESULT hr
Definition: shlfolder.c:183
#define TRACE(s)
Definition: solgame.cpp:4
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699
INTERNET_PORT nPort
Definition: winhttp.h:471
LPWSTR lpszScheme
Definition: winhttp.h:466
LPWSTR lpszUrlPath
Definition: winhttp.h:476
DWORD dwHostNameLength
Definition: winhttp.h:470
DWORD dwExtraInfoLength
Definition: winhttp.h:479
DWORD dwUrlPathLength
Definition: winhttp.h:477
LPWSTR lpszHostName
Definition: winhttp.h:469
INTERNET_SCHEME nScheme
Definition: winhttp.h:468
DWORD dwStructSize
Definition: winhttp.h:465
DWORD dwSchemeLength
Definition: winhttp.h:467
DWORD_PTR Spare[8/sizeof(DWORD_PTR)]
Definition: winbase.h:887
LIST_ENTRY ProcessLocksList
Definition: winbase.h:883
PCRITICAL_SECTION_DEBUG DebugInfo
Definition: winbase.h:894
PCCERT_CONTEXT * paCred
Definition: schannel.h:90
DWORD dwVersion
Definition: schannel.h:88
DWORD cCreds
Definition: schannel.h:89
DWORD grbitEnabledProtocols
Definition: schannel.h:96
WORD wYear
Definition: winbase.h:905
WORD wMilliseconds
Definition: winbase.h:912
WORD wMonth
Definition: winbase.h:906
WORD wHour
Definition: winbase.h:909
WORD wSecond
Definition: winbase.h:911
WORD wMinute
Definition: winbase.h:910
WORD wDay
Definition: winbase.h:908
WORD wDayOfWeek
Definition: winbase.h:907
ULONG cBuffers
Definition: sspi.h:182
ULONG ulVersion
Definition: sspi.h:181
ULONGLONG QuadPart
Definition: ms-dtyp.idl:185
Definition: cookie.c:202
char * data
DWORD scheme
CredHandle cred
CtxtHandle ctx
TimeStamp exp
unsigned int data_len
ULONG max_token
WCHAR * hostname
struct sockaddr_storage sockaddr
struct session * session
WCHAR * servername
INTERNET_PORT hostport
INTERNET_PORT serverport
Definition: http.c:7252
Definition: cookie.c:42
Definition: parser.c:44
Definition: dsound.c:943
WCHAR * field
BOOL is_request
WCHAR * value
Definition: list.h:15
Definition: name.c:39
struct hostdata * host
struct list entry
struct sockaddr_storage sockaddr
ULONGLONG keep_until
Definition: getopt.h:109
Definition: send.c:48
Definition: tftpd.h:86
HANDLE task_cancel
DWORD content_read
DWORD read_size
HANDLE task_wait
BOOL task_proc_running
DWORD optional_len
const CERT_CONTEXT * server_cert
struct list task_queue
WCHAR * version
char path[256]
Definition: tftpd.h:94
const CERT_CONTEXT * client_cert
int send_timeout
struct header * headers
struct object_header hdr
WCHAR * verb
DWORD security_flags
struct authinfo * authinfo
DWORD num_headers
CredHandle cred_handle
WCHAR * status_text
void * optional
int receive_timeout
BOOL check_revocation
struct request::@595 creds[TARGET_MAX][SCHEME_MAX]
int connect_timeout
int resolve_timeout
WCHAR * raw_headers
CRITICAL_SECTION task_cs
struct connect * connect
DWORD read_pos
char read_buf[8192]
BOOL read_chunked
int receive_response_timeout
BOOL read_chunked_size
BOOL cred_handle_initialized
struct netconn * netconn
DWORD content_length
struct authinfo * proxy_authinfo
BOOL read_chunked_eof
DWORD_PTR context
WCHAR * agent
Definition: ps.c:97
Definition: parse.h:23
char * data
Definition: request.c:4379
LONG refs
Definition: request.c:4378
ULARGE_INTEGER pos
Definition: request.c:4380
unsigned int size
Definition: parse.h:27
unsigned char * data
Definition: parse.h:26
IStream IStream_iface
Definition: request.c:4377
struct request * request
struct list entry
void(* proc)(struct task_header *)
Definition: dhcpd.h:245
VARIANT data
Definition: request.c:3184
DWORD bytes_read
Definition: request.c:3199
LONG send_timeout
Definition: request.c:3205
HANDLE cancel
Definition: request.c:3192
LONG receive_timeout
Definition: request.c:3206
HINTERNET hrequest
Definition: request.c:3183
IWinHttpRequest IWinHttpRequest_iface
Definition: request.c:3177
LONG resolve_timeout
Definition: request.c:3203
BOOL proc_running
Definition: request.c:3194
WCHAR * verb
Definition: request.c:3185
DWORD logon_policy
Definition: request.c:3201
HINTERNET hconnect
Definition: request.c:3182
DWORD bytes_available
Definition: request.c:3198
char * buffer
Definition: request.c:3196
HINTERNET hsession
Definition: request.c:3181
LONG connect_timeout
Definition: request.c:3204
CRITICAL_SECTION cs
Definition: request.c:3179
enum request_state state
Definition: request.c:3180
WINHTTP_PROXY_INFO proxy
Definition: request.c:3207
UINT url_codepage
Definition: request.c:3209
DWORD disable_feature
Definition: request.c:3202
DWORD * written
#define max(a, b)
Definition: svc.c:63
DWORD WINAPI WaitForMultipleObjects(IN DWORD nCount, IN CONST HANDLE *lpHandles, IN BOOL bWaitAll, IN DWORD dwMilliseconds)
Definition: synch.c:151
DWORD WINAPI WaitForSingleObject(IN HANDLE hHandle, IN DWORD dwMilliseconds)
Definition: synch.c:82
VOID WINAPI DECLSPEC_HOTPATCH Sleep(IN DWORD dwMilliseconds)
Definition: synch.c:790
VOID WINAPI InitializeCriticalSection(OUT LPCRITICAL_SECTION lpCriticalSection)
Definition: synch.c:751
HANDLE WINAPI DECLSPEC_HOTPATCH CreateEventW(IN LPSECURITY_ATTRIBUTES lpEventAttributes OPTIONAL, IN BOOL bManualReset, IN BOOL bInitialState, IN LPCWSTR lpName OPTIONAL)
Definition: synch.c:651
BOOL WINAPI DECLSPEC_HOTPATCH SetEvent(IN HANDLE hEvent)
Definition: synch.c:733
#define LIST_INIT(head)
Definition: queue.h:197
#define LIST_ENTRY(type)
Definition: queue.h:175
int read_line()
#define DWORD_PTR
Definition: treelist.c:76
TW_UINT32 TW_UINT16 TW_UINT16 MSG
Definition: twain.h:1829
uint32_t DWORD_PTR
Definition: typedefs.h:65
uint32_t * LPDWORD
Definition: typedefs.h:59
#define CONTAINING_RECORD(address, type, field)
Definition: typedefs.h:260
uint32_t ULONG
Definition: typedefs.h:59
uint64_t ULONGLONG
Definition: typedefs.h:67
static EFI_HANDLE * handles
Definition: uefidisk.c:62
LONGLONG QuadPart
Definition: typedefs.h:114
Definition: pdh_main.c:94
const char *WSAAPI inet_ntop(int af, const void *src, char *dst, size_t cnt)
Definition: unix_func.c:8
HRESULT WINAPI DECLSPEC_HOTPATCH VariantChangeType(VARIANTARG *pvargDest, VARIANTARG *pvargSrc, USHORT wFlags, VARTYPE vt)
Definition: variant.c:962
HRESULT WINAPI DECLSPEC_HOTPATCH VariantClear(VARIANTARG *pVarg)
Definition: variant.c:648
void WINAPI VariantInit(VARIANTARG *pVarg)
Definition: variant.c:568
HRESULT WINAPI VariantCopyInd(VARIANT *pvargDest, VARIANTARG *pvargSrc)
Definition: variant.c:847
int ret
char * host
Definition: whois.c:55
int codepage
Definition: win_iconv.c:156
DWORD WINAPI GetLastError(void)
Definition: except.c:1042
void WINAPI LeaveCriticalSection(LPCRITICAL_SECTION)
struct _SYSTEMTIME SYSTEMTIME
void WINAPI EnterCriticalSection(LPCRITICAL_SECTION)
void WINAPI DeleteCriticalSection(PCRITICAL_SECTION)
#define WAIT_OBJECT_0
Definition: winbase.h:406
CONST void * LPCVOID
Definition: windef.h:191
#define WINAPI
Definition: msvc.h:6
#define SEC_E_OK
Definition: winerror.h:2356
#define S_FALSE
Definition: winerror.h:2357
#define ERROR_INVALID_OPERATION
Definition: winerror.h:1261
#define E_NOINTERFACE
Definition: winerror.h:2364
#define DISP_E_UNKNOWNINTERFACE
Definition: winerror.h:2511
#define ERROR_CANCELLED
Definition: winerror.h:726
#define HRESULT_FROM_WIN32(x)
Definition: winerror.h:92
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
#define ERROR_TIMEOUT
Definition: winerror.h:941
BOOL add_cookie_headers(struct request *request)
Definition: cookie.c:324
BOOL set_cookies(struct request *request, const WCHAR *cookies)
Definition: cookie.c:263
#define WINHTTP_OPTION_PROXY
Definition: winhttp.h:110
#define WINHTTP_HANDLE_TYPE_REQUEST
Definition: winhttp.h:432
#define WINHTTP_DISABLE_AUTHENTICATION
Definition: winhttp.h:170
#define WINHTTP_CALLBACK_STATUS_RESPONSE_RECEIVED
Definition: winhttp.h:387
#define WINHTTP_QUERY_CONTENT_LENGTH
Definition: winhttp.h:303
WORD INTERNET_PORT
Definition: winhttp.h:38
#define WINHTTP_CALLBACK_STATUS_DATA_AVAILABLE
Definition: winhttp.h:397
#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_HIGH
Definition: winhttp.h:154
#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
Definition: winhttp.h:209
#define WINHTTP_OPTION_CONTEXT_VALUE
Definition: winhttp.h:112
#define WINHTTP_CALLBACK_STATUS_REDIRECT
Definition: winhttp.h:393
#define WINHTTP_FLAG_ESCAPE_DISABLE_QUERY
Definition: winhttp.h:57
#define WINHTTP_QUERY_WWW_AUTHENTICATE
Definition: winhttp.h:338
#define WINHTTP_QUERY_CONNECTION
Definition: winhttp.h:321
#define WINHTTP_CALLBACK_STATUS_SENDING_REQUEST
Definition: winhttp.h:384
#define WINHTTP_QUERY_VERSION
Definition: winhttp.h:316
#define HTTP_STATUS_NO_CONTENT
Definition: winhttp.h:244
#define WINHTTP_CALLBACK_STATUS_REQUEST_SENT
Definition: winhttp.h:385
#define WINHTTP_OPTION_REDIRECT_POLICY_NEVER
Definition: winhttp.h:157
#define WINHTTP_QUERY_FLAG_SYSTEMTIME
Definition: winhttp.h:376
#define WINHTTP_AUTH_SCHEME_BASIC
Definition: winhttp.h:452
#define WINHTTP_QUERY_PROXY_AUTHENTICATE
Definition: winhttp.h:339
#define ERROR_WINHTTP_INVALID_SERVER_RESPONSE
Definition: winhttp.h:214
#define WINHTTP_AUTH_SCHEME_PASSPORT
Definition: winhttp.h:454
#define WINHTTP_CALLBACK_STATUS_HEADERS_AVAILABLE
Definition: winhttp.h:396
#define API_QUERY_DATA_AVAILABLE
Definition: winhttp.h:425
#define WINHTTP_CALLBACK_STATUS_RECEIVING_RESPONSE
Definition: winhttp.h:386
#define WINHTTP_QUERY_PROXY_CONNECTION
Definition: winhttp.h:367
#define WINHTTP_OPTION_DISABLE_FEATURE
Definition: winhttp.h:116
#define HTTP_STATUS_PROXY_AUTH_REQ
Definition: winhttp.h:262
#define WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
Definition: winhttp.h:83
#define WINHTTP_DISABLE_KEEP_ALIVE
Definition: winhttp.h:171
#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
Definition: winhttp.h:86
#define WINHTTP_QUERY_STATUS_CODE
Definition: winhttp.h:317
#define WINHTTP_CALLBACK_STATUS_CLOSING_CONNECTION
Definition: winhttp.h:388
#define WINHTTP_QUERY_FLAG_REQUEST_HEADERS
Definition: winhttp.h:375
#define WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
Definition: winhttp.h:62
#define WINHTTP_ENABLE_PASSPORT_AUTH
Definition: winhttp.h:164
#define WINHTTP_ACCESS_TYPE_NAMED_PROXY
Definition: winhttp.h:64
#define API_WRITE_DATA
Definition: winhttp.h:427
#define WINHTTP_QUERY_CONTENT_TYPE
Definition: winhttp.h:299
#define WINHTTP_CALLBACK_STATUS_READ_COMPLETE
Definition: winhttp.h:398
#define WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
Definition: winhttp.h:158
#define WINHTTP_AUTH_SCHEME_NEGOTIATE
Definition: winhttp.h:456
#define WINHTTP_AUTH_TARGET_SERVER
Definition: winhttp.h:458
#define WINHTTP_QUERY_LOCATION
Definition: winhttp.h:331
#define ERROR_WINHTTP_INCORRECT_HANDLE_STATE
Definition: winhttp.h:200
#define WINHTTP_ADDREQ_FLAG_ADD
Definition: winhttp.h:84
#define WINHTTP_AUTH_SCHEME_DIGEST
Definition: winhttp.h:455
#define WINHTTP_QUERY_FLAG_NUMBER
Definition: winhttp.h:377
#define WINHTTP_CALLBACK_STATUS_CONNECTION_CLOSED
Definition: winhttp.h:389
#define HTTP_STATUS_REDIRECT_KEEP_VERB
Definition: winhttp.h:254
#define ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
Definition: winhttp.h:210
#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL2
Definition: winhttp.h:443
#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_MEDIUM
Definition: winhttp.h:152
#define WINHTTP_CALLBACK_STATUS_CONNECTING_TO_SERVER
Definition: winhttp.h:382
#define WINHTTP_OPTION_AUTOLOGON_POLICY
Definition: winhttp.h:120
#define WINHTTP_CALLBACK_STATUS_CONNECTED_TO_SERVER
Definition: winhttp.h:383
#define WINHTTP_QUERY_CUSTOM
Definition: winhttp.h:374
#define INTERNET_SCHEME_HTTP
Definition: winhttp.h:42
#define ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
Definition: winhttp.h:199
#define WINHTTP_ACCESS_TYPE_NO_PROXY
Definition: winhttp.h:63
#define WINHTTP_QUERY_STATUS_TEXT
Definition: winhttp.h:318
#define API_RECEIVE_RESPONSE
Definition: winhttp.h:424
#define WINHTTP_CALLBACK_STATUS_SENDREQUEST_COMPLETE
Definition: winhttp.h:401
#define WINHTTP_FLAG_ESCAPE_PERCENT
Definition: winhttp.h:54
#define WINHTTP_CALLBACK_STATUS_REQUEST_ERROR
Definition: winhttp.h:400
#define WINHTTP_FLAG_ASYNC
Definition: winhttp.h:51
#define WINHTTP_AUTH_TARGET_PROXY
Definition: winhttp.h:459
#define WINHTTP_FLAG_ESCAPE_DISABLE
Definition: winhttp.h:56
#define HTTP_STATUS_DENIED
Definition: winhttp.h:256
#define WINHTTP_AUTOLOGON_SECURITY_LEVEL_LOW
Definition: winhttp.h:153
#define WINHTTP_CALLBACK_STATUS_RESOLVING_NAME
Definition: winhttp.h:380
#define API_SEND_REQUEST
Definition: winhttp.h:428
#define WINHTTP_CALLBACK_STATUS_WRITE_COMPLETE
Definition: winhttp.h:399
#define WINHTTP_ADDREQ_FLAG_REPLACE
Definition: winhttp.h:88
#define ERROR_WINHTTP_HEADER_NOT_FOUND
Definition: winhttp.h:213
#define WINHTTP_CALLBACK_STATUS_NAME_RESOLVED
Definition: winhttp.h:381
#define WINHTTP_QUERY_TRANSFER_ENCODING
Definition: winhttp.h:361
#define HTTP_STATUS_NOT_MODIFIED
Definition: winhttp.h:252
#define WINHTTP_QUERY_RAW_HEADERS_CRLF
Definition: winhttp.h:320
#define WINHTTP_FLAG_SECURE
Definition: winhttp.h:60
#define INTERNET_DEFAULT_HTTP_PORT
Definition: winhttp.h:36
#define WINHTTP_QUERY_REQUEST_METHOD
Definition: winhttp.h:343
#define WINHTTP_DISABLE_REDIRECTS
Definition: winhttp.h:169
#define ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
Definition: winhttp.h:211
#define INTERNET_SCHEME_HTTPS
Definition: winhttp.h:43
#define WINHTTP_FLAG_REFRESH
Definition: winhttp.h:59
#define WINHTTP_FLAG_SECURE_PROTOCOL_SSL3
Definition: winhttp.h:444
#define HTTP_STATUS_REDIRECT
Definition: winhttp.h:250
#define HTTP_STATUS_MOVED
Definition: winhttp.h:249
#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2
Definition: winhttp.h:447
#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_1
Definition: winhttp.h:446
#define WINHTTP_AUTH_SCHEME_NTLM
Definition: winhttp.h:453
#define WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
Definition: winhttp.h:85
#define WINHTTP_DISABLE_COOKIES
Definition: winhttp.h:168
#define API_READ_DATA
Definition: winhttp.h:426
#define WINHTTP_QUERY_RAW_HEADERS
Definition: winhttp.h:319
#define INTERNET_DEFAULT_HTTPS_PORT
Definition: winhttp.h:37
#define WINHTTP_FLAG_SECURE_PROTOCOL_TLS1
Definition: winhttp.h:445
static const WCHAR http1_1[]
static const WCHAR postW[]
auth_target
@ TARGET_SERVER
@ TARGET_PROXY
static const WCHAR http1_0[]
auth_scheme
@ SCHEME_BASIC
@ SCHEME_DIGEST
@ SCHEME_INVALID
@ SCHEME_NTLM
@ SCHEME_NEGOTIATE
static const WCHAR chunkedW[]
DWORD set_cookie(substr_t domain, substr_t path, substr_t name, substr_t data, DWORD flags)
Definition: cookie.c:912
struct _TP_CALLBACK_INSTANCE TP_CALLBACK_INSTANCE
Definition: winnt_old.h:4453
#define AF_INET6
Definition: winsock.h:369
BOOL WINAPI TranslateMessage(_In_ const MSG *)
#define QS_ALLINPUT
Definition: winuser.h:903
DWORD WINAPI MsgWaitForMultipleObjects(_In_ DWORD nCount, _In_reads_opt_(nCount) CONST HANDLE *pHandles, _In_ BOOL fWaitAll, _In_ DWORD dwMilliseconds, _In_ DWORD dwWakeMask)
BOOL WINAPI PeekMessageW(_Out_ LPMSG, _In_opt_ HWND, _In_ UINT, _In_ UINT, _In_ UINT)
#define PM_REMOVE
Definition: winuser.h:1196
LRESULT WINAPI DispatchMessageW(_In_ const MSG *)
SECURITY_STATUS WINAPI AcquireCredentialsHandleW(SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialsUse, PLUID pvLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pvGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
Definition: wrapper.c:105
SECURITY_STATUS WINAPI InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: wrapper.c:301
SECURITY_STATUS WINAPI DeleteSecurityContext(PCtxtHandle phContext)
Definition: wrapper.c:450
SECURITY_STATUS WINAPI QuerySecurityPackageInfoW(SEC_WCHAR *pszPackageName, PSecPkgInfoW *ppPackageInfo)
Definition: wrapper.c:750
SECURITY_STATUS WINAPI FreeCredentialsHandle(PCredHandle phCredential)
Definition: wrapper.c:151
#define INET6_ADDRSTRLEN
Definition: ws2ipdef.h:132
static char * encoding
Definition: xmllint.c:155
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185