4 * Copyright 2008 Google (Zac Brown)
6 * This library is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU Lesser General Public
8 * License as published by the Free Software Foundation; either
9 * version 2.1 of the License, or (at your option) any later version.
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 * Lesser General Public License for more details.
16 * You should have received a copy of the GNU Lesser General Public
17 * License along with this library; if not, write to the Free Software
18 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
21 #define WIN32_NO_STATUS
23 #define COM_NO_WINDOWS_H
32 //#include <ws2tcpip.h>
36 //#include <winsock.h>
37 //#include "initguid.h"
38 #include <httprequest.h>
40 #include <wine/test.h>
42 static const WCHAR test_useragent
[] =
43 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
44 static const WCHAR test_winehq
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
45 static const WCHAR localhostW
[] = {'l','o','c','a','l','h','o','s','t',0};
47 static BOOL
proxy_active(void)
49 WINHTTP_PROXY_INFO proxy_info
;
52 if (WinHttpGetDefaultProxyConfiguration(&proxy_info
))
54 active
= (proxy_info
.lpszProxy
!= NULL
);
56 GlobalFree(proxy_info
.lpszProxy
);
57 if (proxy_info
.lpszProxyBypass
!= NULL
)
58 GlobalFree(proxy_info
.lpszProxyBypass
);
66 static void test_QueryOption(void)
69 HINTERNET session
, request
, connection
;
72 SetLastError(0xdeadbeef);
73 session
= WinHttpOpen(test_useragent
, 0, 0, 0, 0);
74 ok(session
!= NULL
, "WinHttpOpen failed to open session, error %u\n", GetLastError());
76 SetLastError(0xdeadbeef);
77 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, NULL
);
78 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
79 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
80 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
83 SetLastError(0xdeadbeef);
84 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, &size
);
85 ok(!ret
, "should fail to query option\n");
86 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
87 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
88 ok(size
== 4, "expected 4, got %u\n", size
);
91 size
= sizeof(feature
) - 1;
92 SetLastError(0xdeadbeef);
93 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
94 ok(!ret
, "should fail to query option\n");
95 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
96 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
97 ok(size
== 4, "expected 4, got %u\n", size
);
100 size
= sizeof(feature
) + 1;
101 SetLastError(0xdeadbeef);
102 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
103 ok(ret
, "failed to query option %u\n", GetLastError());
104 ok(size
== sizeof(feature
), "WinHttpQueryOption should set the size: %u\n", size
);
105 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP
,
106 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature
);
108 SetLastError(0xdeadbeef);
109 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, NULL
, sizeof(feature
));
110 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
111 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
112 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
114 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
115 SetLastError(0xdeadbeef);
116 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) - 1);
117 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
118 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
119 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
121 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
122 SetLastError(0xdeadbeef);
123 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
) + 1);
124 ok(!ret
, "should fail to set redirect policy %u\n", GetLastError());
125 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
126 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
128 feature
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
129 SetLastError(0xdeadbeef);
130 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, sizeof(feature
));
131 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
133 feature
= 0xdeadbeef;
134 size
= sizeof(feature
);
135 SetLastError(0xdeadbeef);
136 ret
= WinHttpQueryOption(session
, WINHTTP_OPTION_REDIRECT_POLICY
, &feature
, &size
);
137 ok(ret
, "failed to query option %u\n", GetLastError());
138 ok(feature
== WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
,
139 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature
);
141 feature
= WINHTTP_DISABLE_COOKIES
;
142 SetLastError(0xdeadbeef);
143 ret
= WinHttpSetOption(session
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
144 ok(!ret
, "should fail to set disable feature for a session\n");
145 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
146 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
148 SetLastError(0xdeadbeef);
149 connection
= WinHttpConnect(session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
150 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError());
152 feature
= WINHTTP_DISABLE_COOKIES
;
153 SetLastError(0xdeadbeef);
154 ret
= WinHttpSetOption(connection
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
155 ok(!ret
, "should fail to set disable feature for a connection\n");
156 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
157 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError());
159 SetLastError(0xdeadbeef);
160 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
161 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
162 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
164 skip("Network unreachable, skipping the test\n");
168 feature
= 0xdeadbeef;
169 size
= sizeof(feature
);
170 SetLastError(0xdeadbeef);
171 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, &size
);
172 ok(!ret
, "should fail to query disable feature for a request\n");
173 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
174 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
177 size
= sizeof(feature
);
178 SetLastError(0xdeadbeef);
179 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
180 ok(ret
, "failed to set feature %u\n", GetLastError());
182 feature
= 0xffffffff;
183 size
= sizeof(feature
);
184 SetLastError(0xdeadbeef);
185 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
186 ok(ret
, "failed to set feature %u\n", GetLastError());
188 feature
= WINHTTP_DISABLE_COOKIES
;
189 size
= sizeof(feature
);
190 SetLastError(0xdeadbeef);
191 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, &feature
, sizeof(feature
));
192 ok(ret
, "failed to set feature %u\n", GetLastError());
195 SetLastError(0xdeadbeef);
196 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_DISABLE_FEATURE
, NULL
, &size
);
197 ok(!ret
, "should fail to query disable feature for a request\n");
198 ok(GetLastError() == ERROR_INVALID_PARAMETER
,
199 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
201 SetLastError(0xdeadbeef);
202 ret
= WinHttpCloseHandle(request
);
203 ok(ret
, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError());
206 SetLastError(0xdeadbeef);
207 ret
= WinHttpCloseHandle(connection
);
208 ok(ret
, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError());
209 SetLastError(0xdeadbeef);
210 ret
= WinHttpCloseHandle(session
);
211 ok(ret
, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError());
214 static void test_OpenRequest (void)
217 HINTERNET session
, request
, connection
;
219 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
220 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
221 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
223 /* Test with a bad server name */
224 SetLastError(0xdeadbeef);
225 connection
= WinHttpConnect(session
, NULL
, INTERNET_DEFAULT_HTTP_PORT
, 0);
226 ok (connection
== NULL
, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
227 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
229 /* Test with a valid server name */
230 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
231 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
233 request
= WinHttpOpenRequest(connection
, NULL
, NULL
, NULL
, WINHTTP_NO_REFERER
,
234 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
235 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
237 skip("Network unreachable, skipping.\n");
240 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
242 ret
= WinHttpSendRequest(request
, WINHTTP_NO_ADDITIONAL_HEADERS
, 0, NULL
, 0, 0, 0);
243 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
245 skip("Connection failed, skipping.\n");
248 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
249 ret
= WinHttpCloseHandle(request
);
250 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
253 ret
= WinHttpCloseHandle(connection
);
254 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
255 ret
= WinHttpCloseHandle(session
);
256 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
260 static void test_empty_headers_param(void)
262 static const WCHAR empty
[] = {0};
263 HINTERNET ses
, con
, req
;
266 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
267 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
269 con
= WinHttpConnect(ses
, test_winehq
, 80, 0);
270 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
272 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
273 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
275 ret
= WinHttpSendRequest(req
, empty
, 0, NULL
, 0, 0, 0);
276 ok(ret
, "failed to send request %u\n", GetLastError());
278 WinHttpCloseHandle(req
);
279 WinHttpCloseHandle(con
);
280 WinHttpCloseHandle(ses
);
283 static void test_SendRequest (void)
285 static const WCHAR content_type
[] =
286 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
287 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
288 static const WCHAR test_file
[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
289 static const WCHAR test_verb
[] = {'P','O','S','T',0};
290 static CHAR post_data
[] = "mode=Test";
291 static const char test_post
[] = "mode => Test\0\n";
292 HINTERNET session
, request
, connection
;
293 DWORD header_len
, optional_len
, total_len
, bytes_rw
, size
;
300 total_len
= optional_len
= sizeof(post_data
);
301 memset(buffer
, 0xff, sizeof(buffer
));
303 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
304 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
305 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
307 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
308 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
310 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
311 WINHTTP_DEFAULT_ACCEPT_TYPES
, WINHTTP_FLAG_BYPASS_PROXY_CACHE
);
312 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
314 skip("Network unreachable, skipping.\n");
317 ok(request
!= NULL
, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
318 if (!request
) goto done
;
320 context
= 0xdeadbeef;
321 ret
= WinHttpSetOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, sizeof(context
));
322 ok(ret
, "WinHttpSetOption failed: %u\n", GetLastError());
325 ret
= WinHttpSendRequest(request
, content_type
, header_len
, post_data
, optional_len
, total_len
, context
);
326 ok(ret
== TRUE
, "WinHttpSendRequest failed: %u\n", GetLastError());
329 size
= sizeof(context
);
330 ret
= WinHttpQueryOption(request
, WINHTTP_OPTION_CONTEXT_VALUE
, &context
, &size
);
331 ok(ret
, "WinHttpQueryOption failed: %u\n", GetLastError());
332 ok(context
== 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context
);
334 for (i
= 3; post_data
[i
]; i
++)
337 ret
= WinHttpWriteData(request
, &post_data
[i
], 1, &bytes_rw
);
339 ok(bytes_rw
== 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw
);
340 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */
342 ok(GetLastError() == ERROR_INVALID_PARAMETER
, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError());
343 ok(bytes_rw
== -1, "Expected bytes_rw to remain unchanged.\n");
347 ret
= WinHttpReceiveResponse(request
, NULL
);
348 ok(ret
== TRUE
, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
351 ret
= WinHttpReadData(request
, buffer
, sizeof(buffer
) - 1, &bytes_rw
);
352 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
354 ok(bytes_rw
== sizeof(test_post
) - 1, "Read %u bytes\n", bytes_rw
);
355 ok(!memcmp(buffer
, test_post
, sizeof(test_post
) - 1), "Data read did not match.\n");
357 ret
= WinHttpCloseHandle(request
);
358 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
360 ret
= WinHttpCloseHandle(connection
);
361 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
362 ret
= WinHttpCloseHandle(session
);
363 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
366 static void test_WinHttpTimeFromSystemTime(void)
369 static const SYSTEMTIME time
= {2008, 7, 1, 28, 10, 5, 52, 0};
370 static const WCHAR expected_string
[] =
371 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
372 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
373 WCHAR time_string
[WINHTTP_TIME_FORMAT_BUFSIZE
+1];
375 ret
= WinHttpTimeFromSystemTime(&time
, time_string
);
376 ok(ret
== TRUE
, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
377 ok(memcmp(time_string
, expected_string
, sizeof(expected_string
)) == 0,
378 "Time string returned did not match expected time string.\n");
381 static void test_WinHttpTimeToSystemTime(void)
385 static const SYSTEMTIME expected_time
= {2008, 7, 1, 28, 10, 5, 52, 0};
386 static const WCHAR time_string1
[] =
387 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
388 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
389 static const WCHAR time_string2
[] =
390 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
391 '1','0',' ','0','5',' ','5','2','\n',0};
393 ret
= WinHttpTimeToSystemTime(time_string1
, &time
);
394 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
395 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
396 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
398 ret
= WinHttpTimeToSystemTime(time_string2
, &time
);
399 ok(ret
== TRUE
, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
400 ok(memcmp(&time
, &expected_time
, sizeof(SYSTEMTIME
)) == 0,
401 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
404 static void test_WinHttpAddHeaders(void)
406 HINTERNET session
, request
, connection
;
408 WCHAR buffer
[MAX_PATH
];
409 WCHAR check_buffer
[MAX_PATH
];
410 DWORD index
, len
, oldlen
;
412 static const WCHAR test_file
[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
413 static const WCHAR test_verb
[] = {'P','O','S','T',0};
414 static const WCHAR test_header_begin
[] =
415 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
416 static const WCHAR full_path_test_header_begin
[] =
417 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0','/','p','o','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
418 static const WCHAR test_header_end
[] = {'\r','\n','\r','\n',0};
419 static const WCHAR test_header_name
[] = {'W','a','r','n','i','n','g',0};
421 static const WCHAR test_flag_coalesce
[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
422 static const WCHAR test_flag_coalesce_reverse
[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0};
423 static const WCHAR test_flag_coalesce_comma
[] =
424 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
425 static const WCHAR test_flag_coalesce_comma_reverse
[] =
426 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
427 static const WCHAR test_flag_coalesce_semicolon
[] =
428 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
429 static const WCHAR test_flag_coalesce_semicolon_reverse
[] =
430 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
432 static const WCHAR field
[] = {'f','i','e','l','d',0};
433 static const WCHAR value
[] = {'v','a','l','u','e',' ',0};
434 static const WCHAR value_nospace
[] = {'v','a','l','u','e',0};
436 static const WCHAR test_headers
[][14] =
438 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
439 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
440 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
441 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
442 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
443 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
444 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
450 {' ','e',' ',':','f',0},
451 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
453 static const WCHAR test_indices
[][6] =
455 {'t','e','s','t','1',0},
456 {'t','e','s','t','2',0},
457 {'t','e','s','t','3',0},
458 {'t','e','s','t','4',0}
461 session
= WinHttpOpen(test_useragent
, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY
,
462 WINHTTP_NO_PROXY_NAME
, WINHTTP_NO_PROXY_BYPASS
, 0);
463 ok(session
!= NULL
, "WinHttpOpen failed to open session.\n");
465 connection
= WinHttpConnect (session
, test_winehq
, INTERNET_DEFAULT_HTTP_PORT
, 0);
466 ok(connection
!= NULL
, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
468 request
= WinHttpOpenRequest(connection
, test_verb
, test_file
, NULL
, WINHTTP_NO_REFERER
,
469 WINHTTP_DEFAULT_ACCEPT_TYPES
, 0);
470 if (request
== NULL
&& GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
)
472 skip("Network unreachable, skipping.\n");
475 ok(request
!= NULL
, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
478 len
= sizeof(buffer
);
479 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
480 test_header_name
, buffer
, &len
, &index
);
481 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
482 ret
= WinHttpAddRequestHeaders(request
, test_headers
[0], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
483 ok(ret
== TRUE
, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret
, GetLastError());
486 len
= sizeof(buffer
);
487 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
488 test_header_name
, buffer
, &len
, &index
);
489 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
490 ok(index
== 1, "WinHttpQueryHeaders failed: header index not incremented\n");
491 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
492 ok(len
== 5*sizeof(WCHAR
), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len
);
494 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
495 test_header_name
, buffer
, &len
, &index
);
496 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
498 /* Try to fetch the header info with a buffer that's big enough to fit the
499 * string but not the NULL terminator.
502 len
= 5*sizeof(WCHAR
);
503 memset(check_buffer
, 0xab, sizeof(check_buffer
));
504 memcpy(buffer
, check_buffer
, sizeof(buffer
));
505 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
506 test_header_name
, buffer
, &len
, &index
);
507 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
508 ok(memcmp(buffer
, check_buffer
, sizeof(buffer
)) == 0,
509 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
510 ok(len
== 6*sizeof(WCHAR
), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len
);
512 /* Try with a NULL buffer */
514 len
= sizeof(buffer
);
515 SetLastError(0xdeadbeef);
516 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
517 test_header_name
, NULL
, &len
, &index
);
518 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
519 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
520 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
521 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
523 /* Try with a NULL buffer and a length that's too small */
526 SetLastError(0xdeadbeef);
527 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
528 test_header_name
, NULL
, &len
, &index
);
529 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
530 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
531 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
532 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
533 ok(index
== 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
537 SetLastError(0xdeadbeef);
538 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
539 test_header_name
, NULL
, &len
, &index
);
540 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
541 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
542 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
543 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
544 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
549 len
= sizeof(buffer
);
550 memset(buffer
, 0xff, sizeof(buffer
));
551 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS_CRLF
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
552 test_header_name
, buffer
, &len
, &index
);
553 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: got %d\n", ret
);
554 ok(len
+ sizeof(WCHAR
) <= oldlen
, "WinHttpQueryHeaders resulting length longer than advertized.\n");
555 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && buffer
[len
/ sizeof(WCHAR
)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
556 ok(len
== lstrlenW(buffer
) * sizeof(WCHAR
), "WinHttpQueryHeaders returned incorrect length.\n");
557 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
558 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
559 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
560 ok(memcmp(buffer
+ lstrlenW(buffer
) - 4, test_header_end
, sizeof(test_header_end
)) == 0,
561 "WinHttpQueryHeaders returned invalid end of header string.\n");
562 ok(index
== 0, "WinHttpQueryHeaders incremented header index.\n");
566 SetLastError(0xdeadbeef);
567 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
568 test_header_name
, NULL
, &len
, &index
);
569 ok(ret
== FALSE
, "WinHttpQueryHeaders unexpectedly succeeded.\n");
570 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER
,
571 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
572 ok(len
> 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len
);
573 ok(index
== 0, "WinHttpQueryHeaders failed: index was incremented.\n");
577 len
= sizeof(buffer
);
578 memset(buffer
, 0xff, sizeof(buffer
));
579 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_RAW_HEADERS
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
580 test_header_name
, buffer
, &len
, &index
);
581 ok(ret
== TRUE
, "WinHttpQueryHeaders failed %u\n", GetLastError());
582 ok(len
+ sizeof(WCHAR
) <= oldlen
, "resulting length longer than advertized\n");
583 ok((len
< sizeof(buffer
) - sizeof(WCHAR
)) && !buffer
[len
/ sizeof(WCHAR
)] && !buffer
[len
/ sizeof(WCHAR
) - 1],
584 "no double NULL terminator\n");
585 ok(memcmp(buffer
, test_header_begin
, sizeof(test_header_begin
)) == 0 ||
586 memcmp(buffer
, full_path_test_header_begin
, sizeof(full_path_test_header_begin
)) == 0,
587 "invalid beginning of header string.\n");
588 ok(index
== 0, "header index was incremented\n");
590 /* tests for more indices */
591 ret
= WinHttpAddRequestHeaders(request
, test_headers
[1], -1L, WINHTTP_ADDREQ_FLAG_ADD
);
592 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret
);
595 len
= sizeof(buffer
);
596 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
597 test_header_name
, buffer
, &len
, &index
);
598 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
599 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
600 ok(memcmp(buffer
, test_indices
[0], sizeof(test_indices
[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
602 len
= sizeof(buffer
);
603 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
604 test_header_name
, buffer
, &len
, &index
);
605 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
606 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
607 ok(memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
609 ret
= WinHttpAddRequestHeaders(request
, test_headers
[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE
);
610 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
613 len
= sizeof(buffer
);
614 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
615 test_header_name
, buffer
, &len
, &index
);
616 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
617 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
618 reverse
= (memcmp(buffer
, test_indices
[1], sizeof(test_indices
[1])) != 0); /* Win7 returns values in reverse order of adding */
619 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
621 len
= sizeof(buffer
);
622 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
623 test_header_name
, buffer
, &len
, &index
);
624 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
625 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
626 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
628 /* add if new flag */
629 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW
);
630 ok(ret
== FALSE
, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
633 len
= sizeof(buffer
);
634 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
635 test_header_name
, buffer
, &len
, &index
);
636 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
637 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
638 ok(memcmp(buffer
, test_indices
[reverse
? 2 : 1], sizeof(test_indices
[reverse
? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
640 len
= sizeof(buffer
);
641 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
642 test_header_name
, buffer
, &len
, &index
);
643 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
644 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
645 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
647 len
= sizeof(buffer
);
648 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
649 test_header_name
, buffer
, &len
, &index
);
650 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
653 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE
);
654 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
657 len
= sizeof(buffer
);
658 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
659 test_header_name
, buffer
, &len
, &index
);
660 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
661 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
662 ok(memcmp(buffer
, reverse
? test_flag_coalesce_reverse
: test_flag_coalesce
,
663 reverse
? sizeof(test_flag_coalesce_reverse
) : sizeof(test_flag_coalesce
)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
665 len
= sizeof(buffer
);
666 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
667 test_header_name
, buffer
, &len
, &index
);
668 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
669 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
670 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
672 len
= sizeof(buffer
);
673 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
674 test_header_name
, buffer
, &len
, &index
);
675 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
677 /* coalesce with comma flag */
678 ret
= WinHttpAddRequestHeaders(request
, test_headers
[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA
);
679 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
682 len
= sizeof(buffer
);
683 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
684 test_header_name
, buffer
, &len
, &index
);
685 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
686 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
687 ok(memcmp(buffer
, reverse
? test_flag_coalesce_comma_reverse
: test_flag_coalesce_comma
,
688 reverse
? sizeof(test_flag_coalesce_comma_reverse
) : sizeof(test_flag_coalesce_comma
)) == 0,
689 "WinHttpQueryHeaders returned incorrect string.\n");
691 len
= sizeof(buffer
);
692 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
693 test_header_name
, buffer
, &len
, &index
);
694 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
695 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
696 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
698 len
= sizeof(buffer
);
699 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
700 test_header_name
, buffer
, &len
, &index
);
701 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
704 /* coalesce with semicolon flag */
705 ret
= WinHttpAddRequestHeaders(request
, test_headers
[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON
);
706 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
709 len
= sizeof(buffer
);
710 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
711 test_header_name
, buffer
, &len
, &index
);
712 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
713 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
714 ok(memcmp(buffer
, reverse
? test_flag_coalesce_semicolon_reverse
: test_flag_coalesce_semicolon
,
715 reverse
? sizeof(test_flag_coalesce_semicolon_reverse
) : sizeof(test_flag_coalesce_semicolon
)) == 0,
716 "WinHttpQueryHeaders returned incorrect string.\n");
718 len
= sizeof(buffer
);
719 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
720 test_header_name
, buffer
, &len
, &index
);
721 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
722 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
723 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 2], sizeof(test_indices
[reverse
? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
725 len
= sizeof(buffer
);
726 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
727 test_header_name
, buffer
, &len
, &index
);
728 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
730 /* add and replace flags */
731 ret
= WinHttpAddRequestHeaders(request
, test_headers
[3], -1L, WINHTTP_ADDREQ_FLAG_ADD
| WINHTTP_ADDREQ_FLAG_REPLACE
);
732 ok(ret
== TRUE
, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
735 len
= sizeof(buffer
);
736 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
737 test_header_name
, buffer
, &len
, &index
);
738 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
739 ok(index
== 1, "WinHttpQueryHeaders failed to increment index.\n");
740 ok(memcmp(buffer
, test_indices
[reverse
? 3 : 2], sizeof(test_indices
[reverse
? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
742 len
= sizeof(buffer
);
743 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
744 test_header_name
, buffer
, &len
, &index
);
745 ok(ret
== TRUE
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
746 ok(index
== 2, "WinHttpQueryHeaders failed to increment index.\n");
747 ok(memcmp(buffer
, test_indices
[reverse
? 1 : 3], sizeof(test_indices
[reverse
? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
749 len
= sizeof(buffer
);
750 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
751 test_header_name
, buffer
, &len
, &index
);
752 ok(ret
== FALSE
, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
754 ret
= WinHttpAddRequestHeaders(request
, test_headers
[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
755 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
757 ret
= WinHttpAddRequestHeaders(request
, test_headers
[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
758 ok(ret
, "WinHttpAddRequestHeaders failed\n");
760 ret
= WinHttpAddRequestHeaders(request
, test_headers
[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
761 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
763 ret
= WinHttpAddRequestHeaders(request
, test_headers
[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
764 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
766 ret
= WinHttpAddRequestHeaders(request
, test_headers
[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
767 ok(!ret
, "WinHttpAddRequestHeaders failed\n");
769 ret
= WinHttpAddRequestHeaders(request
, test_headers
[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
770 ok(ret
, "WinHttpAddRequestHeaders failed\n");
774 len
= sizeof(buffer
);
775 ret
= WinHttpQueryHeaders(request
, WINHTTP_QUERY_CUSTOM
| WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
776 field
, buffer
, &len
, &index
);
777 ok(ret
, "WinHttpQueryHeaders failed: %u\n", GetLastError());
778 ok(!memcmp(buffer
, value
, sizeof(value
)) || ! memcmp(buffer
, value_nospace
, sizeof(value_nospace
)), "unexpected result\n");
780 ret
= WinHttpCloseHandle(request
);
781 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing request, got %d.\n", ret
);
783 ret
= WinHttpCloseHandle(connection
);
784 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret
);
785 ret
= WinHttpCloseHandle(session
);
786 ok(ret
== TRUE
, "WinHttpCloseHandle failed on closing session, got %d.\n", ret
);
790 static void CALLBACK
cert_error(HINTERNET handle
, DWORD_PTR ctx
, DWORD status
, LPVOID buf
, DWORD len
)
792 DWORD flags
= *(DWORD
*)buf
;
796 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n");
799 #define X(x) if (flags & x) trace("%s\n", #x);
800 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED
)
801 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT
)
802 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED
)
803 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA
)
804 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID
)
805 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID
)
806 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE
)
810 static void test_secure_connection(void)
812 HINTERNET ses
, con
, req
;
813 DWORD size
, status
, policy
, bitness
, read_size
;
816 WINHTTP_CERTIFICATE_INFO info
;
819 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
820 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
822 policy
= WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS
;
823 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_REDIRECT_POLICY
, &policy
, sizeof(policy
));
824 ok(ret
, "failed to set redirect policy %u\n", GetLastError());
826 con
= WinHttpConnect(ses
, test_winehq
, 443, 0);
827 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
829 /* try without setting WINHTTP_FLAG_SECURE */
830 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
831 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
833 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
834 if (!ret
&& GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT
)
836 skip("Connection failed, skipping.\n");
839 ok(ret
, "failed to send request %u\n", GetLastError());
841 ret
= WinHttpReceiveResponse(req
, NULL
);
842 ok(!ret
|| proxy_active(), "succeeded unexpectedly\n");
845 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
846 ok(!ret
, "succeeded unexpectedly\n");
848 WinHttpCloseHandle(req
);
850 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, WINHTTP_FLAG_SECURE
);
851 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
853 WinHttpSetStatusCallback(req
, cert_error
, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE
, 0);
855 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
856 ok(ret
, "failed to send request %u\n", GetLastError());
859 skip("secure connection failed, skipping remaining secure tests\n");
864 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SERVER_CERT_CONTEXT
, &cert
, &size
);
865 ok(ret
, "failed to retrieve certificate context %u\n", GetLastError());
867 CertFreeCertificateContext(cert
);
869 size
= sizeof(bitness
);
870 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_KEY_BITNESS
, &bitness
, &size
);
871 ok(ret
, "failed to retrieve key bitness %u\n", GetLastError());
874 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT
, &info
, &size
);
875 ok(ret
, "failed to retrieve certificate info %u\n", GetLastError());
877 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info
.lpszSubjectInfo
));
878 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info
.lpszIssuerInfo
));
879 trace("lpszProtocolName %s\n", wine_dbgstr_w(info
.lpszProtocolName
));
880 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info
.lpszSignatureAlgName
));
881 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info
.lpszEncryptionAlgName
));
882 trace("dwKeySize %u\n", info
.dwKeySize
);
884 ret
= WinHttpReceiveResponse(req
, NULL
);
885 ok(ret
, "failed to receive response %u\n", GetLastError());
887 size
= sizeof(status
);
888 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
889 ok(ret
, "failed unexpectedly %u\n", GetLastError());
890 ok(status
== 200, "request failed unexpectedly %u\n", status
);
893 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_RAW_HEADERS_CRLF
, NULL
, NULL
, &size
, NULL
);
894 ok(!ret
, "succeeded unexpectedly\n");
900 ret
= WinHttpReadData(req
, buffer
, sizeof(buffer
), &size
);
901 ok(ret
== TRUE
, "WinHttpReadData failed: %u.\n", GetLastError());
905 ok(read_size
> 2014, "read_size = %u\n", read_size
);
908 WinHttpCloseHandle(req
);
909 WinHttpCloseHandle(con
);
910 WinHttpCloseHandle(ses
);
913 static void test_request_parameter_defaults(void)
915 static const WCHAR empty
[] = {0};
916 HINTERNET ses
, con
, req
;
917 DWORD size
, status
, error
;
921 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
922 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
924 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
925 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
927 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
928 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
930 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
931 ok(ret
, "failed to send request %u\n", GetLastError());
933 ret
= WinHttpReceiveResponse(req
, NULL
);
934 ok(ret
, "failed to receive response %u\n", GetLastError());
936 size
= sizeof(status
);
937 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
938 ok(ret
, "failed unexpectedly %u\n", GetLastError());
939 ok(status
== 200, "request failed unexpectedly %u\n", status
);
941 WinHttpCloseHandle(req
);
943 req
= WinHttpOpenRequest(con
, empty
, empty
, empty
, NULL
, NULL
, 0);
944 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
946 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
947 ok(ret
, "failed to send request %u\n", GetLastError());
949 ret
= WinHttpReceiveResponse(req
, NULL
);
950 ok(ret
, "failed to receive response %u\n", GetLastError());
953 SetLastError(0xdeadbeef);
954 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, NULL
, &size
, NULL
);
955 error
= GetLastError();
956 ok(!ret
, "succeeded unexpectedly\n");
957 ok(error
== ERROR_INSUFFICIENT_BUFFER
, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error
);
959 version
= HeapAlloc(GetProcessHeap(), 0, size
);
960 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_VERSION
, NULL
, version
, &size
, NULL
);
961 ok(ret
, "failed unexpectedly %u\n", GetLastError());
962 ok(lstrlenW(version
) == size
/ sizeof(WCHAR
), "unexpected size %u\n", size
);
963 HeapFree(GetProcessHeap(), 0, version
);
965 size
= sizeof(status
);
966 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
| WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
967 ok(ret
, "failed unexpectedly %u\n", GetLastError());
968 ok(status
== 200, "request failed unexpectedly %u\n", status
);
970 WinHttpCloseHandle(req
);
971 WinHttpCloseHandle(con
);
972 WinHttpCloseHandle(ses
);
975 static const WCHAR Connections
[] = {
976 'S','o','f','t','w','a','r','e','\\',
977 'M','i','c','r','o','s','o','f','t','\\',
978 'W','i','n','d','o','w','s','\\',
979 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\',
980 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\',
981 'C','o','n','n','e','c','t','i','o','n','s',0 };
982 static const WCHAR WinHttpSettings
[] = {
983 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 };
985 static DWORD
get_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD
*type
)
991 l
= RegOpenKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, KEY_READ
, &key
);
996 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, NULL
, &size
);
1000 l
= RegQueryValueExW( key
, WinHttpSettings
, NULL
, type
, buf
,
1010 static void set_default_proxy_reg_value( BYTE
*buf
, DWORD len
, DWORD type
)
1015 l
= RegCreateKeyExW( HKEY_LOCAL_MACHINE
, Connections
, 0, NULL
, 0,
1016 KEY_WRITE
, NULL
, &key
, NULL
);
1020 RegSetValueExW( key
, WinHttpSettings
, 0, type
, buf
, len
);
1022 RegDeleteValueW( key
, WinHttpSettings
);
1027 static void test_set_default_proxy_config(void)
1029 static WCHAR wideString
[] = { 0x226f, 0x575b, 0 };
1030 static WCHAR normalString
[] = { 'f','o','o',0 };
1032 BYTE
*saved_proxy_settings
= NULL
;
1033 WINHTTP_PROXY_INFO info
;
1036 /* FIXME: it would be simpler to read the current settings using
1037 * WinHttpGetDefaultProxyConfiguration and save them using
1038 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug.
1040 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"',
1041 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1,
1042 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be
1043 * WINHTTP_ACCESS_TYPE_NAMED_PROXY.
1044 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1,
1045 * the lpszProxy and lpszProxyBypass values are ignored.
1046 * Thus, if a proxy is set with proxycfg, then calling
1047 * WinHttpGetDefaultProxyConfiguration followed by
1048 * WinHttpSetDefaultProxyConfiguration results in the proxy settings
1049 * getting deleted from the registry.
1051 * Instead I read the current registry value and restore it directly.
1053 len
= get_default_proxy_reg_value( NULL
, 0, &type
);
1056 saved_proxy_settings
= HeapAlloc( GetProcessHeap(), 0, len
);
1057 len
= get_default_proxy_reg_value( saved_proxy_settings
, len
, &type
);
1062 /* Crashes on Vista and higher */
1063 SetLastError(0xdeadbeef);
1064 ret
= WinHttpSetDefaultProxyConfiguration(NULL
);
1065 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1066 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1069 /* test with invalid access type */
1070 info
.dwAccessType
= 0xdeadbeef;
1071 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1072 SetLastError(0xdeadbeef);
1073 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1074 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1075 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1077 /* at a minimum, the proxy server must be set */
1078 info
.dwAccessType
= WINHTTP_ACCESS_TYPE_NAMED_PROXY
;
1079 info
.lpszProxy
= info
.lpszProxyBypass
= NULL
;
1080 SetLastError(0xdeadbeef);
1081 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1082 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1083 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1084 info
.lpszProxyBypass
= normalString
;
1085 SetLastError(0xdeadbeef);
1086 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1087 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1088 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1090 /* the proxy server can't have wide characters */
1091 info
.lpszProxy
= wideString
;
1092 SetLastError(0xdeadbeef);
1093 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1094 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1095 skip("couldn't set default proxy configuration: access denied\n");
1097 ok((!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
) ||
1098 broken(ret
), /* Earlier winhttp versions on W2K/XP */
1099 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError());
1101 info
.lpszProxy
= normalString
;
1102 SetLastError(0xdeadbeef);
1103 ret
= WinHttpSetDefaultProxyConfiguration(&info
);
1104 if (!ret
&& GetLastError() == ERROR_ACCESS_DENIED
)
1105 skip("couldn't set default proxy configuration: access denied\n");
1107 ok(ret
, "WinHttpSetDefaultProxyConfiguration failed: %d\n",
1110 set_default_proxy_reg_value( saved_proxy_settings
, len
, type
);
1113 static void test_Timeouts (void)
1117 HINTERNET ses
, req
, con
;
1119 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1120 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1122 SetLastError(0xdeadbeef);
1123 ret
= WinHttpSetTimeouts(ses
, -2, 0, 0, 0);
1124 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1125 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1127 SetLastError(0xdeadbeef);
1128 ret
= WinHttpSetTimeouts(ses
, 0, -2, 0, 0);
1129 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1130 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1132 SetLastError(0xdeadbeef);
1133 ret
= WinHttpSetTimeouts(ses
, 0, 0, -2, 0);
1134 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1135 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1137 SetLastError(0xdeadbeef);
1138 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, -2);
1139 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1140 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1142 SetLastError(0xdeadbeef);
1143 ret
= WinHttpSetTimeouts(ses
, -1, -1, -1, -1);
1144 ok(ret
, "%u\n", GetLastError());
1146 SetLastError(0xdeadbeef);
1147 ret
= WinHttpSetTimeouts(ses
, 0, 0, 0, 0);
1148 ok(ret
, "%u\n", GetLastError());
1150 SetLastError(0xdeadbeef);
1151 ret
= WinHttpSetTimeouts(ses
, 0x0123, 0x4567, 0x89ab, 0xcdef);
1152 ok(ret
, "%u\n", GetLastError());
1154 SetLastError(0xdeadbeef);
1156 size
= sizeof(DWORD
);
1157 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1158 ok(ret
, "%u\n", GetLastError());
1159 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1161 SetLastError(0xdeadbeef);
1163 size
= sizeof(DWORD
);
1164 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1165 ok(ret
, "%u\n", GetLastError());
1166 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1168 SetLastError(0xdeadbeef);
1170 size
= sizeof(DWORD
);
1171 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1172 ok(ret
, "%u\n", GetLastError());
1173 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1175 SetLastError(0xdeadbeef);
1177 size
= sizeof(DWORD
);
1178 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1179 ok(ret
, "%u\n", GetLastError());
1180 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1182 SetLastError(0xdeadbeef);
1184 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1185 ok(ret
, "%u\n", GetLastError());
1187 SetLastError(0xdeadbeef);
1189 size
= sizeof(DWORD
);
1190 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1191 ok(ret
, "%u\n", GetLastError());
1192 ok(value
== 0, "Expected 0, got %u\n", value
);
1194 SetLastError(0xdeadbeef);
1196 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1197 ok(ret
, "%u\n", GetLastError());
1199 SetLastError(0xdeadbeef);
1201 size
= sizeof(DWORD
);
1202 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1203 ok(ret
, "%u\n", GetLastError());
1204 ok(value
== 0, "Expected 0, got %u\n", value
);
1206 SetLastError(0xdeadbeef);
1208 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1209 ok(ret
, "%u\n", GetLastError());
1211 SetLastError(0xdeadbeef);
1213 size
= sizeof(DWORD
);
1214 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1215 ok(ret
, "%u\n", GetLastError());
1216 ok(value
== 0, "Expected 0, got %u\n", value
);
1218 SetLastError(0xdeadbeef);
1220 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1221 ok(ret
, "%u\n", GetLastError());
1223 SetLastError(0xdeadbeef);
1225 size
= sizeof(DWORD
);
1226 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1227 ok(ret
, "%u\n", GetLastError());
1228 ok(value
== 0, "Expected 0, got %u\n", value
);
1230 SetLastError(0xdeadbeef);
1232 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1233 ok(ret
, "%u\n", GetLastError());
1235 SetLastError(0xdeadbeef);
1237 size
= sizeof(DWORD
);
1238 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1239 ok(ret
, "%u\n", GetLastError());
1240 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1242 SetLastError(0xdeadbeef);
1244 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1245 ok(ret
, "%u\n", GetLastError());
1247 SetLastError(0xdeadbeef);
1249 size
= sizeof(DWORD
);
1250 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1251 ok(ret
, "%u\n", GetLastError());
1252 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1254 SetLastError(0xdeadbeef);
1256 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1257 ok(ret
, "%u\n", GetLastError());
1259 SetLastError(0xdeadbeef);
1261 size
= sizeof(DWORD
);
1262 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1263 ok(ret
, "%u\n", GetLastError());
1264 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1266 SetLastError(0xdeadbeef);
1268 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1269 ok(ret
, "%u\n", GetLastError());
1271 SetLastError(0xdeadbeef);
1273 size
= sizeof(DWORD
);
1274 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1275 ok(ret
, "%u\n", GetLastError());
1276 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1278 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1279 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1281 /* Timeout values should match the last one set for session */
1282 SetLastError(0xdeadbeef);
1284 size
= sizeof(DWORD
);
1285 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1286 ok(ret
, "%u\n", GetLastError());
1287 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1289 SetLastError(0xdeadbeef);
1291 size
= sizeof(DWORD
);
1292 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1293 ok(ret
, "%u\n", GetLastError());
1294 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1296 SetLastError(0xdeadbeef);
1298 size
= sizeof(DWORD
);
1299 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1300 ok(ret
, "%u\n", GetLastError());
1301 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1303 SetLastError(0xdeadbeef);
1305 size
= sizeof(DWORD
);
1306 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1307 ok(ret
, "%u\n", GetLastError());
1308 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1310 SetLastError(0xdeadbeef);
1311 ret
= WinHttpSetTimeouts(con
, -2, 0, 0, 0);
1312 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1313 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1315 SetLastError(0xdeadbeef);
1316 ret
= WinHttpSetTimeouts(con
, 0, -2, 0, 0);
1317 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1318 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1320 SetLastError(0xdeadbeef);
1321 ret
= WinHttpSetTimeouts(con
, 0, 0, -2, 0);
1322 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1323 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1325 SetLastError(0xdeadbeef);
1326 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, -2);
1327 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1328 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1330 SetLastError(0xdeadbeef);
1331 ret
= WinHttpSetTimeouts(con
, -1, -1, -1, -1);
1332 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1333 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1335 SetLastError(0xdeadbeef);
1336 ret
= WinHttpSetTimeouts(con
, 0, 0, 0, 0);
1337 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1338 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1340 SetLastError(0xdeadbeef);
1342 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1343 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1344 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1346 SetLastError(0xdeadbeef);
1348 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1349 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1350 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1352 SetLastError(0xdeadbeef);
1354 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1355 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1356 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1358 SetLastError(0xdeadbeef);
1360 ret
= WinHttpSetOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1361 ok(!ret
&& GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE
,
1362 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError());
1364 /* Changing timeout values for session should affect the values for connection */
1365 SetLastError(0xdeadbeef);
1367 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1368 ok(ret
, "%u\n", GetLastError());
1370 SetLastError(0xdeadbeef);
1372 size
= sizeof(DWORD
);
1373 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1374 ok(ret
, "%u\n", GetLastError());
1375 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1377 SetLastError(0xdeadbeef);
1379 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1380 ok(ret
, "%u\n", GetLastError());
1382 SetLastError(0xdeadbeef);
1384 size
= sizeof(DWORD
);
1385 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1386 ok(ret
, "%u\n", GetLastError());
1387 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1389 SetLastError(0xdeadbeef);
1391 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1392 ok(ret
, "%u\n", GetLastError());
1394 SetLastError(0xdeadbeef);
1396 size
= sizeof(DWORD
);
1397 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1398 ok(ret
, "%u\n", GetLastError());
1399 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1401 SetLastError(0xdeadbeef);
1403 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1404 ok(ret
, "%u\n", GetLastError());
1406 SetLastError(0xdeadbeef);
1408 size
= sizeof(DWORD
);
1409 ret
= WinHttpQueryOption(con
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1410 ok(ret
, "%u\n", GetLastError());
1411 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1413 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1414 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1416 /* Timeout values should match the last one set for session */
1417 SetLastError(0xdeadbeef);
1419 size
= sizeof(DWORD
);
1420 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1421 ok(ret
, "%u\n", GetLastError());
1422 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1424 SetLastError(0xdeadbeef);
1426 size
= sizeof(DWORD
);
1427 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1428 ok(ret
, "%u\n", GetLastError());
1429 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1431 SetLastError(0xdeadbeef);
1433 size
= sizeof(DWORD
);
1434 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1435 ok(ret
, "%u\n", GetLastError());
1436 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1438 SetLastError(0xdeadbeef);
1440 size
= sizeof(DWORD
);
1441 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1442 ok(ret
, "%u\n", GetLastError());
1443 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1445 SetLastError(0xdeadbeef);
1446 ret
= WinHttpSetTimeouts(req
, -2, 0, 0, 0);
1447 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1448 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1450 SetLastError(0xdeadbeef);
1451 ret
= WinHttpSetTimeouts(req
, 0, -2, 0, 0);
1452 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1453 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1455 SetLastError(0xdeadbeef);
1456 ret
= WinHttpSetTimeouts(req
, 0, 0, -2, 0);
1457 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1458 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1460 SetLastError(0xdeadbeef);
1461 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, -2);
1462 ok(!ret
&& GetLastError() == ERROR_INVALID_PARAMETER
,
1463 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError());
1465 SetLastError(0xdeadbeef);
1466 ret
= WinHttpSetTimeouts(req
, -1, -1, -1, -1);
1467 ok(ret
, "%u\n", GetLastError());
1469 SetLastError(0xdeadbeef);
1470 ret
= WinHttpSetTimeouts(req
, 0, 0, 0, 0);
1471 ok(ret
, "%u\n", GetLastError());
1473 SetLastError(0xdeadbeef);
1474 ret
= WinHttpSetTimeouts(req
, 0xcdef, 0x89ab, 0x4567, 0x0123);
1475 ok(ret
, "%u\n", GetLastError());
1477 SetLastError(0xdeadbeef);
1479 size
= sizeof(DWORD
);
1480 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1481 ok(ret
, "%u\n", GetLastError());
1482 ok(value
== 0xcdef, "Expected 0xcdef, got %u\n", value
);
1484 SetLastError(0xdeadbeef);
1486 size
= sizeof(DWORD
);
1487 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1488 ok(ret
, "%u\n", GetLastError());
1489 ok(value
== 0x89ab, "Expected 0x89ab, got %u\n", value
);
1491 SetLastError(0xdeadbeef);
1493 size
= sizeof(DWORD
);
1494 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1495 ok(ret
, "%u\n", GetLastError());
1496 ok(value
== 0x4567, "Expected 0x4567, got %u\n", value
);
1498 SetLastError(0xdeadbeef);
1500 size
= sizeof(DWORD
);
1501 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1502 ok(ret
, "%u\n", GetLastError());
1503 ok(value
== 0x0123, "Expected 0x0123, got %u\n", value
);
1505 SetLastError(0xdeadbeef);
1507 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1508 ok(ret
, "%u\n", GetLastError());
1510 SetLastError(0xdeadbeef);
1512 size
= sizeof(DWORD
);
1513 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1514 ok(ret
, "%u\n", GetLastError());
1515 ok(value
== 0, "Expected 0, got %u\n", value
);
1517 SetLastError(0xdeadbeef);
1519 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1520 ok(ret
, "%u\n", GetLastError());
1522 SetLastError(0xdeadbeef);
1524 size
= sizeof(DWORD
);
1525 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1526 ok(ret
, "%u\n", GetLastError());
1527 ok(value
== 0, "Expected 0, got %u\n", value
);
1529 SetLastError(0xdeadbeef);
1531 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1532 ok(ret
, "%u\n", GetLastError());
1534 SetLastError(0xdeadbeef);
1536 size
= sizeof(DWORD
);
1537 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1538 ok(ret
, "%u\n", GetLastError());
1539 ok(value
== 0, "Expected 0, got %u\n", value
);
1541 SetLastError(0xdeadbeef);
1543 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1544 ok(ret
, "%u\n", GetLastError());
1546 SetLastError(0xdeadbeef);
1548 size
= sizeof(DWORD
);
1549 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1550 ok(ret
, "%u\n", GetLastError());
1551 ok(value
== 0, "Expected 0, got %u\n", value
);
1553 SetLastError(0xdeadbeef);
1555 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1556 ok(ret
, "%u\n", GetLastError());
1558 SetLastError(0xdeadbeef);
1560 size
= sizeof(DWORD
);
1561 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1562 ok(ret
, "%u\n", GetLastError());
1563 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1565 SetLastError(0xdeadbeef);
1567 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1568 ok(ret
, "%u\n", GetLastError());
1570 SetLastError(0xdeadbeef);
1572 size
= sizeof(DWORD
);
1573 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1574 ok(ret
, "%u\n", GetLastError());
1575 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1577 SetLastError(0xdeadbeef);
1579 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1580 ok(ret
, "%u\n", GetLastError());
1582 SetLastError(0xdeadbeef);
1584 size
= sizeof(DWORD
);
1585 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1586 ok(ret
, "%u\n", GetLastError());
1587 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1589 SetLastError(0xdeadbeef);
1591 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1592 ok(ret
, "%u\n", GetLastError());
1594 SetLastError(0xdeadbeef);
1596 size
= sizeof(DWORD
);
1597 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1598 ok(ret
, "%u\n", GetLastError());
1599 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1601 /* Changing timeout values for session should not affect the values for a request,
1602 * neither should the other way around.
1604 SetLastError(0xdeadbeef);
1606 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1607 ok(ret
, "%u\n", GetLastError());
1609 SetLastError(0xdeadbeef);
1611 size
= sizeof(DWORD
);
1612 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1613 ok(ret
, "%u\n", GetLastError());
1614 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1616 SetLastError(0xdeadbeef);
1618 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1619 ok(ret
, "%u\n", GetLastError());
1621 SetLastError(0xdeadbeef);
1623 size
= sizeof(DWORD
);
1624 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1625 ok(ret
, "%u\n", GetLastError());
1626 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1628 SetLastError(0xdeadbeef);
1630 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1631 ok(ret
, "%u\n", GetLastError());
1633 SetLastError(0xdeadbeef);
1635 size
= sizeof(DWORD
);
1636 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1637 ok(ret
, "%u\n", GetLastError());
1638 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1640 SetLastError(0xdeadbeef);
1642 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1643 ok(ret
, "%u\n", GetLastError());
1645 SetLastError(0xdeadbeef);
1647 size
= sizeof(DWORD
);
1648 ret
= WinHttpQueryOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1649 ok(ret
, "%u\n", GetLastError());
1650 ok(value
== 0xdead, "Expected 0xdead, got %u\n", value
);
1652 SetLastError(0xdeadbeef);
1654 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, sizeof(value
));
1655 ok(ret
, "%u\n", GetLastError());
1657 SetLastError(0xdeadbeef);
1659 size
= sizeof(DWORD
);
1660 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &value
, &size
);
1661 ok(ret
, "%u\n", GetLastError());
1662 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1664 SetLastError(0xdeadbeef);
1666 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, sizeof(value
));
1667 ok(ret
, "%u\n", GetLastError());
1669 SetLastError(0xdeadbeef);
1671 size
= sizeof(DWORD
);
1672 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_CONNECT_TIMEOUT
, &value
, &size
);
1673 ok(ret
, "%u\n", GetLastError());
1674 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1676 SetLastError(0xdeadbeef);
1678 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, sizeof(value
));
1679 ok(ret
, "%u\n", GetLastError());
1681 SetLastError(0xdeadbeef);
1683 size
= sizeof(DWORD
);
1684 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_SEND_TIMEOUT
, &value
, &size
);
1685 ok(ret
, "%u\n", GetLastError());
1686 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1688 SetLastError(0xdeadbeef);
1690 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, sizeof(value
));
1691 ok(ret
, "%u\n", GetLastError());
1693 SetLastError(0xdeadbeef);
1695 size
= sizeof(DWORD
);
1696 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_RECEIVE_TIMEOUT
, &value
, &size
);
1697 ok(ret
, "%u\n", GetLastError());
1698 ok(value
== 0xbeefdead, "Expected 0xbeefdead, got %u\n", value
);
1700 WinHttpCloseHandle(req
);
1701 WinHttpCloseHandle(con
);
1702 WinHttpCloseHandle(ses
);
1705 static void test_resolve_timeout(void)
1707 static const WCHAR nxdomain
[] =
1708 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0};
1709 HINTERNET ses
, con
, req
;
1713 if (! proxy_active())
1715 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1716 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1719 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1720 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1722 con
= WinHttpConnect(ses
, nxdomain
, 0, 0);
1723 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1725 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1726 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1728 SetLastError(0xdeadbeef);
1729 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1732 skip("nxdomain returned success. Broken ISP redirects?\n");
1735 ok(!ret
, "sent request\n");
1736 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED
,
1737 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError());
1739 WinHttpCloseHandle(req
);
1740 WinHttpCloseHandle(con
);
1741 WinHttpCloseHandle(ses
);
1744 skip("Skipping host resolution tests, host resolution preformed by proxy\n");
1746 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1747 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1750 ret
= WinHttpSetOption(ses
, WINHTTP_OPTION_RESOLVE_TIMEOUT
, &timeout
, sizeof(timeout
));
1751 ok(ret
, "failed to set resolve timeout %u\n", GetLastError());
1753 con
= WinHttpConnect(ses
, test_winehq
, 0, 0);
1754 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1756 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
1757 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1759 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1760 ok(ret
, "failed to send request\n");
1762 WinHttpCloseHandle(req
);
1763 WinHttpCloseHandle(con
);
1764 WinHttpCloseHandle(ses
);
1767 static const char page1
[] =
1769 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n"
1770 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n"
1773 static const char okmsg
[] =
1774 "HTTP/1.1 200 OK\r\n"
1775 "Server: winetest\r\n"
1778 static const char noauthmsg
[] =
1779 "HTTP/1.1 401 Unauthorized\r\n"
1780 "Server: winetest\r\n"
1781 "Connection: close\r\n"
1782 "WWW-Authenticate: Basic realm=\"placebo\"\r\n"
1785 static const char proxymsg
[] =
1786 "HTTP/1.1 407 Proxy Authentication Required\r\n"
1787 "Server: winetest\r\n"
1788 "Proxy-Connection: close\r\n"
1789 "Proxy-Authenticate: Basic realm=\"placebo\"\r\n"
1798 #define BIG_BUFFER_LEN 0x2250
1800 static DWORD CALLBACK
server_thread(LPVOID param
)
1802 struct server_info
*si
= param
;
1805 struct sockaddr_in sa
;
1808 int last_request
= 0;
1810 WSAStartup(MAKEWORD(1,1), &wsaData
);
1812 s
= socket(AF_INET
, SOCK_STREAM
, 0);
1813 if (s
== INVALID_SOCKET
)
1817 setsockopt(s
, SOL_SOCKET
, SO_REUSEADDR
, (char*)&on
, sizeof on
);
1819 memset(&sa
, 0, sizeof sa
);
1820 sa
.sin_family
= AF_INET
;
1821 sa
.sin_port
= htons(si
->port
);
1822 sa
.sin_addr
.S_un
.S_addr
= inet_addr("127.0.0.1");
1824 r
= bind(s
, (struct sockaddr
*)&sa
, sizeof(sa
));
1829 SetEvent(si
->event
);
1832 c
= accept(s
, NULL
, NULL
);
1834 memset(buffer
, 0, sizeof buffer
);
1835 for(i
= 0; i
< sizeof buffer
- 1; i
++)
1837 r
= recv(c
, &buffer
[i
], 1, 0);
1840 if (i
< 4) continue;
1841 if (buffer
[i
- 2] == '\n' && buffer
[i
] == '\n' &&
1842 buffer
[i
- 3] == '\r' && buffer
[i
- 1] == '\r')
1845 if (strstr(buffer
, "GET /basic"))
1847 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1848 send(c
, page1
, sizeof page1
- 1, 0);
1850 if (strstr(buffer
, "/auth"))
1852 if (strstr(buffer
, "Authorization: Basic dXNlcjpwd2Q="))
1853 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1855 send(c
, noauthmsg
, sizeof noauthmsg
- 1, 0);
1857 if (strstr(buffer
, "/big"))
1859 char msg
[BIG_BUFFER_LEN
];
1860 memset(msg
, 'm', sizeof(msg
));
1861 send(c
, okmsg
, sizeof(okmsg
) - 1, 0);
1862 send(c
, msg
, sizeof(msg
), 0);
1864 if (strstr(buffer
, "/no_headers"))
1866 send(c
, page1
, sizeof page1
- 1, 0);
1868 if (strstr(buffer
, "GET /quit"))
1870 send(c
, okmsg
, sizeof okmsg
- 1, 0);
1871 send(c
, page1
, sizeof page1
- 1, 0);
1877 } while (!last_request
);
1883 static void test_basic_request(int port
, const WCHAR
*verb
, const WCHAR
*path
)
1885 HINTERNET ses
, con
, req
;
1887 DWORD count
, status
, size
, error
, supported
, first
, target
;
1890 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1891 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1893 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1894 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1896 req
= WinHttpOpenRequest(con
, verb
, path
, NULL
, NULL
, NULL
, 0);
1897 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1899 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
1900 ok(ret
, "failed to send request %u\n", GetLastError());
1902 ret
= WinHttpReceiveResponse(req
, NULL
);
1903 ok(ret
, "failed to receive response %u\n", GetLastError());
1905 size
= sizeof(status
);
1906 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
1907 ok(ret
, "failed to query status code %u\n", GetLastError());
1908 ok(status
== 200, "request failed unexpectedly %u\n", status
);
1910 supported
= first
= target
= 0xdeadbeef;
1911 SetLastError(0xdeadbeef);
1912 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
1913 error
= GetLastError();
1914 ok(!ret
, "unexpected success\n");
1915 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
1916 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1917 ok(first
== 0xdeadbeef, "got %x\n", first
);
1918 ok(target
== 0xdeadbeef, "got %x\n", target
);
1921 memset(buffer
, 0, sizeof(buffer
));
1922 ret
= WinHttpReadData(req
, buffer
, sizeof buffer
, &count
);
1923 ok(ret
, "failed to read data %u\n", GetLastError());
1924 ok(count
== sizeof page1
- 1, "count was wrong\n");
1925 ok(!memcmp(buffer
, page1
, sizeof page1
), "http data wrong\n");
1927 WinHttpCloseHandle(req
);
1928 WinHttpCloseHandle(con
);
1929 WinHttpCloseHandle(ses
);
1932 static void test_basic_authentication(int port
)
1934 static const WCHAR authW
[] = {'/','a','u','t','h',0};
1935 static const WCHAR userW
[] = {'u','s','e','r',0};
1936 static const WCHAR passW
[] = {'p','w','d',0};
1937 HINTERNET ses
, con
, req
;
1938 DWORD status
, size
, error
, supported
, first
, target
;
1941 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
1942 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
1944 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
1945 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
1947 req
= WinHttpOpenRequest(con
, NULL
, authW
, NULL
, NULL
, NULL
, 0);
1948 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
1950 SetLastError(0xdeadbeef);
1951 ret
= WinHttpQueryAuthSchemes(NULL
, NULL
, NULL
, NULL
);
1952 error
= GetLastError();
1953 ok(!ret
, "expected failure\n");
1954 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
1956 SetLastError(0xdeadbeef);
1957 ret
= WinHttpQueryAuthSchemes(req
, NULL
, NULL
, NULL
);
1958 error
= GetLastError();
1959 ok(!ret
, "expected failure\n");
1960 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
1962 supported
= 0xdeadbeef;
1963 SetLastError(0xdeadbeef);
1964 ret
= WinHttpQueryAuthSchemes(req
, &supported
, NULL
, NULL
);
1965 error
= GetLastError();
1966 ok(!ret
, "expected failure\n");
1967 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
1968 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1970 supported
= first
= 0xdeadbeef;
1971 SetLastError(0xdeadbeef);
1972 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, NULL
);
1973 error
= GetLastError();
1974 ok(!ret
, "expected failure\n");
1975 ok(error
== ERROR_INVALID_PARAMETER
|| error
== ERROR_INVALID_OPERATION
, "got %u\n", error
);
1976 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1977 ok(first
== 0xdeadbeef, "got %x\n", first
);
1979 supported
= first
= target
= 0xdeadbeef;
1980 SetLastError(0xdeadbeef);
1981 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
1982 error
= GetLastError();
1983 ok(!ret
, "expected failure\n");
1984 todo_wine
ok(error
== ERROR_INVALID_OPERATION
, "expected ERROR_INVALID_OPERATION, got %u\n", error
);
1985 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1986 ok(first
== 0xdeadbeef, "got %x\n", first
);
1987 ok(target
== 0xdeadbeef, "got %x\n", target
);
1989 supported
= first
= target
= 0xdeadbeef;
1990 SetLastError(0xdeadbeef);
1991 ret
= WinHttpQueryAuthSchemes(NULL
, &supported
, &first
, &target
);
1992 error
= GetLastError();
1993 ok(!ret
, "expected failure\n");
1994 ok(error
== ERROR_INVALID_HANDLE
, "expected ERROR_INVALID_HANDLE, got %u\n", error
);
1995 ok(supported
== 0xdeadbeef, "got %x\n", supported
);
1996 ok(first
== 0xdeadbeef, "got %x\n", first
);
1997 ok(target
== 0xdeadbeef, "got %x\n", target
);
1999 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2000 ok(ret
, "failed to send request %u\n", GetLastError());
2002 ret
= WinHttpReceiveResponse(req
, NULL
);
2003 ok(ret
, "failed to receive response %u\n", GetLastError());
2005 size
= sizeof(status
);
2006 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2007 ok(ret
, "failed to query status code %u\n", GetLastError());
2008 ok(status
== 401, "request failed unexpectedly %u\n", status
);
2010 supported
= first
= target
= 0xdeadbeef;
2011 ret
= WinHttpQueryAuthSchemes(req
, &supported
, &first
, &target
);
2012 ok(ret
, "failed to query authentication schemes %u\n", GetLastError());
2013 ok(supported
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", supported
);
2014 ok(first
== WINHTTP_AUTH_SCHEME_BASIC
, "got %x\n", first
);
2015 ok(target
== WINHTTP_AUTH_TARGET_SERVER
, "got %x\n", target
);
2017 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NTLM
, NULL
, NULL
, NULL
);
2018 ok(ret
, "failed to set credentials %u\n", GetLastError());
2020 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_PASSPORT
, NULL
, NULL
, NULL
);
2021 ok(ret
, "failed to set credentials %u\n", GetLastError());
2023 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_NEGOTIATE
, NULL
, NULL
, NULL
);
2024 ok(ret
, "failed to set credentials %u\n", GetLastError());
2026 SetLastError(0xdeadbeef);
2027 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_DIGEST
, NULL
, NULL
, NULL
);
2028 error
= GetLastError();
2029 ok(!ret
, "expected failure\n");
2030 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2032 SetLastError(0xdeadbeef);
2033 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, NULL
, NULL
);
2034 error
= GetLastError();
2035 ok(!ret
, "expected failure\n");
2036 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2038 SetLastError(0xdeadbeef);
2039 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2040 error
= GetLastError();
2041 ok(!ret
, "expected failure\n");
2042 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2044 SetLastError(0xdeadbeef);
2045 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2046 error
= GetLastError();
2047 ok(!ret
, "expected failure\n");
2048 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2050 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2051 ok(ret
, "failed to set credentials %u\n", GetLastError());
2053 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2054 ok(ret
, "failed to send request %u\n", GetLastError());
2056 ret
= WinHttpReceiveResponse(req
, NULL
);
2057 ok(ret
, "failed to receive response %u\n", GetLastError());
2059 size
= sizeof(status
);
2060 ret
= WinHttpQueryHeaders(req
, WINHTTP_QUERY_STATUS_CODE
|WINHTTP_QUERY_FLAG_NUMBER
, NULL
, &status
, &size
, NULL
);
2061 ok(ret
, "failed to query status code %u\n", GetLastError());
2062 ok(status
== 200, "request failed unexpectedly %u\n", status
);
2064 WinHttpCloseHandle(req
);
2065 WinHttpCloseHandle(con
);
2066 WinHttpCloseHandle(ses
);
2069 static void test_no_headers(int port
)
2071 static const WCHAR no_headersW
[] = {'/','n','o','_','h','e','a','d','e','r','s',0};
2072 HINTERNET ses
, con
, req
;
2076 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
2077 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2079 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2080 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2082 req
= WinHttpOpenRequest(con
, NULL
, no_headersW
, NULL
, NULL
, NULL
, 0);
2083 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2085 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2088 error
= GetLastError();
2089 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2093 SetLastError(0xdeadbeef);
2094 ret
= WinHttpReceiveResponse(req
, NULL
);
2095 error
= GetLastError();
2096 ok(!ret
, "expected failure\n");
2097 ok(error
== ERROR_WINHTTP_INVALID_SERVER_RESPONSE
, "got %u\n", error
);
2100 WinHttpCloseHandle(req
);
2101 WinHttpCloseHandle(con
);
2102 WinHttpCloseHandle(ses
);
2105 static void test_bad_header( int port
)
2107 static const WCHAR bad_headerW
[] =
2108 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',
2109 't','e','x','t','/','h','t','m','l','\n','\r',0};
2110 static const WCHAR text_htmlW
[] = {'t','e','x','t','/','h','t','m','l',0};
2111 static const WCHAR content_typeW
[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0};
2113 HINTERNET ses
, con
, req
;
2117 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2118 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2120 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2121 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2123 req
= WinHttpOpenRequest( con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0 );
2124 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2126 ret
= WinHttpAddRequestHeaders( req
, bad_headerW
, ~0u, WINHTTP_ADDREQ_FLAG_ADD
);
2127 ok( ret
, "failed to add header %u\n", GetLastError() );
2131 len
= sizeof(buffer
);
2132 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CUSTOM
|WINHTTP_QUERY_FLAG_REQUEST_HEADERS
,
2133 content_typeW
, buffer
, &len
, &index
);
2134 ok( ret
, "failed to query headers %u\n", GetLastError() );
2135 ok( !lstrcmpW( buffer
, text_htmlW
), "got %s\n", wine_dbgstr_w(buffer
) );
2137 WinHttpCloseHandle( req
);
2138 WinHttpCloseHandle( con
);
2139 WinHttpCloseHandle( ses
);
2142 static void test_multiple_reads(int port
)
2144 static const WCHAR bigW
[] = {'b','i','g',0};
2145 HINTERNET ses
, con
, req
;
2146 DWORD total_len
= 0;
2149 ses
= WinHttpOpen(test_useragent
, 0, NULL
, NULL
, 0);
2150 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2152 con
= WinHttpConnect(ses
, localhostW
, port
, 0);
2153 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2155 req
= WinHttpOpenRequest(con
, NULL
, bigW
, NULL
, NULL
, NULL
, 0);
2156 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2158 ret
= WinHttpSendRequest(req
, NULL
, 0, NULL
, 0, 0, 0);
2159 ok(ret
, "failed to send request %u\n", GetLastError());
2161 ret
= WinHttpReceiveResponse(req
, NULL
);
2162 ok(ret
== TRUE
, "expected success\n");
2166 DWORD len
= 0xdeadbeef;
2167 ret
= WinHttpQueryDataAvailable( req
, &len
);
2168 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
2169 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
2173 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
2175 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
2176 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
2178 HeapFree( GetProcessHeap(), 0, buf
);
2179 if (!bytes_read
) break;
2180 total_len
+= bytes_read
;
2184 ok(total_len
== BIG_BUFFER_LEN
, "got wrong length: 0x%x\n", total_len
);
2186 WinHttpCloseHandle(req
);
2187 WinHttpCloseHandle(con
);
2188 WinHttpCloseHandle(ses
);
2191 static void test_connection_info( int port
)
2193 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
2194 HINTERNET ses
, con
, req
;
2195 WINHTTP_CONNECTION_INFO info
;
2199 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2200 ok( ses
!= NULL
, "failed to open session %u\n", GetLastError() );
2202 con
= WinHttpConnect( ses
, localhostW
, port
, 0 );
2203 ok( con
!= NULL
, "failed to open a connection %u\n", GetLastError() );
2205 req
= WinHttpOpenRequest( con
, NULL
, basicW
, NULL
, NULL
, NULL
, 0 );
2206 ok( req
!= NULL
, "failed to open a request %u\n", GetLastError() );
2208 size
= sizeof(info
);
2209 SetLastError( 0xdeadbeef );
2210 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2211 error
= GetLastError();
2212 if (!ret
&& error
== ERROR_INVALID_PARAMETER
)
2214 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" );
2217 ok( !ret
, "unexpected success\n" );
2218 ok( error
== ERROR_WINHTTP_INCORRECT_HANDLE_STATE
, "got %u\n", error
);
2220 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
2221 ok( ret
, "failed to send request %u\n", GetLastError() );
2224 SetLastError( 0xdeadbeef );
2225 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2226 error
= GetLastError();
2227 ok( !ret
, "unexpected success\n" );
2228 ok( error
== ERROR_INSUFFICIENT_BUFFER
, "got %u\n", error
);
2230 size
= sizeof(info
);
2231 memset( &info
, 0, sizeof(info
) );
2232 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2233 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2234 ok( info
.cbSize
== sizeof(info
), "wrong size %u\n", info
.cbSize
);
2236 ret
= WinHttpReceiveResponse( req
, NULL
);
2237 ok( ret
, "failed to receive response %u\n", GetLastError() );
2239 size
= sizeof(info
);
2240 memset( &info
, 0, sizeof(info
) );
2241 ret
= WinHttpQueryOption( req
, WINHTTP_OPTION_CONNECTION_INFO
, &info
, &size
);
2242 ok( ret
, "failed to retrieve connection info %u\n", GetLastError() );
2243 ok( info
.cbSize
== sizeof(info
), "wrong size %u\n", info
.cbSize
);
2245 WinHttpCloseHandle( req
);
2246 WinHttpCloseHandle( con
);
2247 WinHttpCloseHandle( ses
);
2250 static void test_credentials(void)
2252 static WCHAR userW
[] = {'u','s','e','r',0};
2253 static WCHAR passW
[] = {'p','a','s','s',0};
2254 static WCHAR proxy_userW
[] = {'p','r','o','x','y','u','s','e','r',0};
2255 static WCHAR proxy_passW
[] = {'p','r','o','x','y','p','a','s','s',0};
2256 HINTERNET ses
, con
, req
;
2261 ses
= WinHttpOpen(test_useragent
, 0, proxy_userW
, proxy_passW
, 0);
2262 ok(ses
!= NULL
, "failed to open session %u\n", GetLastError());
2264 con
= WinHttpConnect(ses
, localhostW
, 0, 0);
2265 ok(con
!= NULL
, "failed to open a connection %u\n", GetLastError());
2267 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2268 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2270 size
= sizeof(buffer
)/sizeof(WCHAR
);
2271 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
2272 ok(ret
, "failed to query proxy username %u\n", GetLastError());
2273 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2274 ok(!size
, "expected 0, got %u\n", size
);
2276 size
= sizeof(buffer
)/sizeof(WCHAR
);
2277 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
2278 ok(ret
, "failed to query proxy password %u\n", GetLastError());
2279 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2280 ok(!size
, "expected 0, got %u\n", size
);
2282 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, proxy_userW
, lstrlenW(proxy_userW
));
2283 ok(ret
, "failed to set username %u\n", GetLastError());
2285 size
= sizeof(buffer
)/sizeof(WCHAR
);
2286 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_USERNAME
, &buffer
, &size
);
2287 ok(ret
, "failed to query proxy username %u\n", GetLastError());
2288 ok(!winetest_strcmpW(buffer
, proxy_userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2289 ok(size
== lstrlenW(proxy_userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2291 size
= sizeof(buffer
)/sizeof(WCHAR
);
2292 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2293 ok(ret
, "failed to query username %u\n", GetLastError());
2294 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2295 ok(!size
, "expected 0, got %u\n", size
);
2297 size
= sizeof(buffer
)/sizeof(WCHAR
);
2298 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2299 ok(ret
, "failed to query password %u\n", GetLastError());
2300 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2301 ok(!size
, "expected 0, got %u\n", size
);
2303 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, proxy_passW
, lstrlenW(proxy_passW
));
2304 ok(ret
, "failed to set proxy password %u\n", GetLastError());
2306 size
= sizeof(buffer
)/sizeof(WCHAR
);
2307 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PROXY_PASSWORD
, &buffer
, &size
);
2308 ok(ret
, "failed to query proxy password %u\n", GetLastError());
2309 ok(!winetest_strcmpW(buffer
, proxy_passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2310 ok(size
== lstrlenW(proxy_passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2312 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_USERNAME
, userW
, lstrlenW(userW
));
2313 ok(ret
, "failed to set username %u\n", GetLastError());
2315 size
= sizeof(buffer
)/sizeof(WCHAR
);
2316 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2317 ok(ret
, "failed to query username %u\n", GetLastError());
2318 ok(!winetest_strcmpW(buffer
, userW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2319 ok(size
== lstrlenW(userW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2321 ret
= WinHttpSetOption(req
, WINHTTP_OPTION_PASSWORD
, passW
, lstrlenW(passW
));
2322 ok(ret
, "failed to set password %u\n", GetLastError());
2324 size
= sizeof(buffer
)/sizeof(WCHAR
);
2325 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2326 ok(ret
, "failed to query password %u\n", GetLastError());
2327 ok(!winetest_strcmpW(buffer
, passW
), "unexpected result %s\n", wine_dbgstr_w(buffer
));
2328 ok(size
== lstrlenW(passW
) * sizeof(WCHAR
), "unexpected result %u\n", size
);
2330 WinHttpCloseHandle(req
);
2332 req
= WinHttpOpenRequest(con
, NULL
, NULL
, NULL
, NULL
, NULL
, 0);
2333 ok(req
!= NULL
, "failed to open a request %u\n", GetLastError());
2335 SetLastError(0xdeadbeef);
2336 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, NULL
, NULL
);
2337 error
= GetLastError();
2338 ok(!ret
, "expected failure\n");
2339 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2341 SetLastError(0xdeadbeef);
2342 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, NULL
, passW
, NULL
);
2343 error
= GetLastError();
2344 ok(!ret
, "expected failure\n");
2345 ok(error
== ERROR_INVALID_PARAMETER
, "expected ERROR_INVALID_PARAMETER, got %u\n", error
);
2347 ret
= WinHttpSetCredentials(req
, WINHTTP_AUTH_TARGET_SERVER
, WINHTTP_AUTH_SCHEME_BASIC
, userW
, passW
, NULL
);
2348 ok(ret
, "failed to set credentials %u\n", GetLastError());
2350 size
= sizeof(buffer
)/sizeof(WCHAR
);
2351 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_USERNAME
, &buffer
, &size
);
2352 ok(ret
, "failed to query username %u\n", GetLastError());
2354 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2355 ok(!size
, "expected 0, got %u\n", size
);
2358 size
= sizeof(buffer
)/sizeof(WCHAR
);
2359 ret
= WinHttpQueryOption(req
, WINHTTP_OPTION_PASSWORD
, &buffer
, &size
);
2360 ok(ret
, "failed to query password %u\n", GetLastError());
2362 ok(!buffer
[0], "unexpected result %s\n", wine_dbgstr_w(buffer
));
2363 ok(!size
, "expected 0, got %u\n", size
);
2366 WinHttpCloseHandle(req
);
2367 WinHttpCloseHandle(con
);
2368 WinHttpCloseHandle(ses
);
2371 static void test_IWinHttpRequest(void)
2373 static const WCHAR usernameW
[] = {'u','s','e','r','n','a','m','e',0};
2374 static const WCHAR passwordW
[] = {'p','a','s','s','w','o','r','d',0};
2375 static const WCHAR url1W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2376 static const WCHAR url2W
[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0};
2377 static const WCHAR url3W
[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.',
2378 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0};
2379 static const WCHAR method1W
[] = {'G','E','T',0};
2380 static const WCHAR method2W
[] = {'I','N','V','A','L','I','D',0};
2381 static const WCHAR method3W
[] = {'P','O','S','T',0};
2382 static const WCHAR proxy_serverW
[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
2383 static const WCHAR bypas_listW
[] = {'b','y','p','a','s','s','l','i','s','t',0};
2384 static const WCHAR connectionW
[] = {'C','o','n','n','e','c','t','i','o','n',0};
2385 static const WCHAR dateW
[] = {'D','a','t','e',0};
2386 static const WCHAR test_dataW
[] = {'t','e','s','t','d','a','t','a',128,0};
2388 IWinHttpRequest
*req
;
2389 BSTR method
, url
, username
, password
, response
= NULL
, status_text
= NULL
, headers
= NULL
;
2390 BSTR date
, today
, connection
, value
= NULL
;
2391 VARIANT async
, empty
, timeout
, body
, proxy_server
, bypass_list
, data
;
2392 VARIANT_BOOL succeeded
;
2394 WCHAR todayW
[WINHTTP_TIME_FORMAT_BUFSIZE
];
2397 GetSystemTime( &st
);
2398 WinHttpTimeFromSystemTime( &st
, todayW
);
2400 CoInitialize( NULL
);
2401 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
2402 ok( hr
== S_OK
, "got %08x\n", hr
);
2404 V_VT( &empty
) = VT_ERROR
;
2405 V_ERROR( &empty
) = 0xdeadbeef;
2407 V_VT( &async
) = VT_BOOL
;
2408 V_BOOL( &async
) = VARIANT_FALSE
;
2410 method
= SysAllocString( method3W
);
2411 url
= SysAllocString( url3W
);
2412 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2413 ok( hr
== S_OK
, "got %08x\n", hr
);
2414 SysFreeString( method
);
2415 SysFreeString( url
);
2417 V_VT( &data
) = VT_BSTR
;
2418 V_BSTR( &data
) = SysAllocString( test_dataW
);
2419 hr
= IWinHttpRequest_Send( req
, data
);
2420 ok( hr
== S_OK
|| broken(hr
== HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE
)),
2422 SysFreeString( V_BSTR( &data
) );
2424 hr
= IWinHttpRequest_Open( req
, NULL
, NULL
, empty
);
2425 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2427 method
= SysAllocString( method1W
);
2428 hr
= IWinHttpRequest_Open( req
, method
, NULL
, empty
);
2429 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2431 hr
= IWinHttpRequest_Open( req
, method
, NULL
, async
);
2432 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2434 url
= SysAllocString( url1W
);
2435 hr
= IWinHttpRequest_Open( req
, NULL
, url
, empty
);
2436 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2438 hr
= IWinHttpRequest_Abort( req
);
2439 ok( hr
== S_OK
, "got %08x\n", hr
);
2441 hr
= IWinHttpRequest_Open( req
, method
, url
, empty
);
2442 ok( hr
== S_OK
, "got %08x\n", hr
);
2444 hr
= IWinHttpRequest_Abort( req
);
2445 ok( hr
== S_OK
, "got %08x\n", hr
);
2447 hr
= IWinHttpRequest_Release( req
);
2448 ok( hr
== S_OK
, "got %08x\n", hr
);
2450 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
2451 ok( hr
== S_OK
, "got %08x\n", hr
);
2453 SysFreeString( url
);
2454 url
= SysAllocString( url2W
);
2455 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2456 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
2458 SysFreeString( method
);
2459 method
= SysAllocString( method2W
);
2460 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2461 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME
), "got %08x\n", hr
);
2463 SysFreeString( method
);
2464 method
= SysAllocString( method1W
);
2465 SysFreeString( url
);
2466 url
= SysAllocString( url1W
);
2467 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2468 ok( hr
== S_OK
, "got %08x\n", hr
);
2470 hr
= IWinHttpRequest_Abort( req
);
2471 ok( hr
== S_OK
, "got %08x\n", hr
);
2473 hr
= IWinHttpRequest_Send( req
, empty
);
2474 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2476 hr
= IWinHttpRequest_Abort( req
);
2477 ok( hr
== S_OK
, "got %08x\n", hr
);
2479 hr
= IWinHttpRequest_Release( req
);
2480 ok( hr
== S_OK
, "got %08x\n", hr
);
2482 hr
= CoCreateInstance( &CLSID_WinHttpRequest
, NULL
, CLSCTX_INPROC_SERVER
, &IID_IWinHttpRequest
, (void **)&req
);
2483 ok( hr
== S_OK
, "got %08x\n", hr
);
2485 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2486 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2488 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2489 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2491 hr
= IWinHttpRequest_get_Status( req
, NULL
);
2492 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2494 hr
= IWinHttpRequest_get_Status( req
, &status
);
2495 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2497 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
2498 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2500 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2501 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2503 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2504 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2506 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
2507 ok( hr
== S_OK
, "got %08x\n", hr
);
2509 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
2510 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2512 VariantInit( &proxy_server
);
2513 V_VT( &proxy_server
) = VT_ERROR
;
2514 VariantInit( &bypass_list
);
2515 V_VT( &bypass_list
) = VT_ERROR
;
2516 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2517 ok( hr
== S_OK
, "got %08x\n", hr
);
2519 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2520 ok( hr
== S_OK
, "got %08x\n", hr
);
2522 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2523 ok( hr
== S_OK
, "got %08x\n", hr
);
2525 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
2526 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2528 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2529 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2531 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
2532 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2534 connection
= SysAllocString( connectionW
);
2535 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
2536 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2538 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2539 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2541 hr
= IWinHttpRequest_SetRequestHeader( req
, NULL
, NULL
);
2542 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2544 date
= SysAllocString( dateW
);
2545 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
2546 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2548 today
= SysAllocString( todayW
);
2549 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2550 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN
), "got %08x\n", hr
);
2552 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, 0xdeadbeef );
2553 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2555 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2556 ok( hr
== S_OK
, "got %08x\n", hr
);
2558 SysFreeString( method
);
2559 method
= SysAllocString( method1W
);
2560 SysFreeString( url
);
2561 url
= SysAllocString( url1W
);
2562 hr
= IWinHttpRequest_Open( req
, method
, url
, async
);
2563 ok( hr
== S_OK
, "got %08x\n", hr
);
2565 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2566 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2568 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2569 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2571 hr
= IWinHttpRequest_get_Status( req
, &status
);
2572 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2574 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2575 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2577 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2578 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2580 hr
= IWinHttpRequest_SetTimeouts( req
, 10000, 10000, 10000, 10000 );
2581 ok( hr
== S_OK
, "got %08x\n", hr
);
2583 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, NULL
, 0xdeadbeef );
2584 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2586 username
= SysAllocString( usernameW
);
2587 hr
= IWinHttpRequest_SetCredentials( req
, username
, NULL
, 0xdeadbeef );
2588 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2590 password
= SysAllocString( passwordW
);
2591 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, 0xdeadbeef );
2592 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2594 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, 0xdeadbeef );
2595 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2597 hr
= IWinHttpRequest_SetCredentials( req
, NULL
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2598 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2600 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2601 ok( hr
== S_OK
, "got %08x\n", hr
);
2603 V_VT( &proxy_server
) = VT_BSTR
;
2604 V_BSTR( &proxy_server
) = SysAllocString( proxy_serverW
);
2605 V_VT( &bypass_list
) = VT_BSTR
;
2606 V_BSTR( &bypass_list
) = SysAllocString( bypas_listW
);
2607 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2608 ok( hr
== S_OK
, "got %08x\n", hr
);
2610 hr
= IWinHttpRequest_SetProxy( req
, 0xdeadbeef, proxy_server
, bypass_list
);
2611 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2613 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2614 ok( hr
== S_OK
, "got %08x\n", hr
);
2616 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2617 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2619 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2620 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND
), "got %08x\n", hr
);
2622 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2623 ok( hr
== S_OK
, "got %08x\n", hr
);
2625 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, NULL
);
2626 ok( hr
== S_OK
, "got %08x\n", hr
);
2628 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2629 ok( hr
== S_OK
, "got %08x\n", hr
);
2631 hr
= IWinHttpRequest_Send( req
, empty
);
2632 ok( hr
== S_OK
, "got %08x\n", hr
);
2634 hr
= IWinHttpRequest_Send( req
, empty
);
2635 ok( hr
== S_OK
, "got %08x\n", hr
);
2637 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2638 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2640 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2641 ok( hr
== S_OK
, "got %08x\n", hr
);
2642 SysFreeString( response
);
2644 hr
= IWinHttpRequest_get_Status( req
, NULL
);
2645 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2648 hr
= IWinHttpRequest_get_Status( req
, &status
);
2649 ok( hr
== S_OK
, "got %08x\n", hr
);
2650 trace("Status=%d\n", status
);
2652 hr
= IWinHttpRequest_get_StatusText( req
, NULL
);
2653 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2655 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2656 ok( hr
== S_OK
, "got %08x\n", hr
);
2657 trace("StatusText=%s\n", wine_dbgstr_w(status_text
));
2658 SysFreeString( status_text
);
2660 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2661 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2663 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2664 ok( hr
== S_OK
, "got %08x\n", hr
);
2666 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2667 ok( hr
== S_OK
, "got %08x\n", hr
);
2669 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2670 ok( hr
== S_OK
, "got %08x\n", hr
);
2672 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, NULL
);
2673 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2675 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2676 ok( hr
== S_OK
, "got %08x\n", hr
);
2677 SysFreeString( headers
);
2679 hr
= IWinHttpRequest_GetResponseHeader( req
, NULL
, NULL
);
2680 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2682 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, NULL
);
2683 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2685 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2686 ok( hr
== S_OK
, "got %08x\n", hr
);
2687 SysFreeString( value
);
2689 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2690 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
2692 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2693 ok( hr
== S_OK
, "got %08x\n", hr
);
2695 VariantInit( &timeout
);
2696 V_VT( &timeout
) = VT_I4
;
2697 V_I4( &timeout
) = 10;
2698 hr
= IWinHttpRequest_WaitForResponse( req
, timeout
, &succeeded
);
2699 ok( hr
== S_OK
, "got %08x\n", hr
);
2701 hr
= IWinHttpRequest_get_Status( req
, &status
);
2702 ok( hr
== S_OK
, "got %08x\n", hr
);
2704 hr
= IWinHttpRequest_get_StatusText( req
, &status_text
);
2705 ok( hr
== S_OK
, "got %08x\n", hr
);
2706 SysFreeString( status_text
);
2708 hr
= IWinHttpRequest_SetCredentials( req
, username
, password
, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER
);
2709 ok( hr
== S_OK
, "got %08x\n", hr
);
2711 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2712 ok( hr
== S_OK
, "got %08x\n", hr
);
2714 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2715 ok( hr
== S_OK
, "got %08x\n", hr
);
2717 hr
= IWinHttpRequest_Send( req
, empty
);
2718 ok( hr
== S_OK
, "got %08x\n", hr
);
2720 hr
= IWinHttpRequest_get_ResponseText( req
, NULL
);
2721 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2723 hr
= IWinHttpRequest_get_ResponseText( req
, &response
);
2724 ok( hr
== S_OK
, "got %08x\n", hr
);
2725 SysFreeString( response
);
2727 hr
= IWinHttpRequest_get_ResponseBody( req
, NULL
);
2728 ok( hr
== E_INVALIDARG
, "got %08x\n", hr
);
2730 VariantInit( &body
);
2731 V_VT( &body
) = VT_ERROR
;
2732 hr
= IWinHttpRequest_get_ResponseBody( req
, &body
);
2733 ok( hr
== S_OK
, "got %08x\n", hr
);
2734 ok( V_VT( &body
) == (VT_ARRAY
|VT_UI1
), "got %08x\n", V_VT( &body
) );
2736 hr
= VariantClear( &body
);
2737 ok( hr
== S_OK
, "got %08x\n", hr
);
2739 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_PROXY
, proxy_server
, bypass_list
);
2740 ok( hr
== S_OK
, "got %08x\n", hr
);
2742 hr
= IWinHttpRequest_SetProxy( req
, HTTPREQUEST_PROXYSETTING_DIRECT
, proxy_server
, bypass_list
);
2743 ok( hr
== S_OK
, "got %08x\n", hr
);
2745 hr
= IWinHttpRequest_GetAllResponseHeaders( req
, &headers
);
2746 ok( hr
== S_OK
, "got %08x\n", hr
);
2747 SysFreeString( headers
);
2749 hr
= IWinHttpRequest_GetResponseHeader( req
, connection
, &value
);
2750 ok( hr
== S_OK
, "got %08x\n", hr
);
2751 SysFreeString( value
);
2753 hr
= IWinHttpRequest_SetRequestHeader( req
, date
, today
);
2754 ok( hr
== HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND
), "got %08x\n", hr
);
2756 hr
= IWinHttpRequest_SetAutoLogonPolicy( req
, AutoLogonPolicy_OnlyIfBypassProxy
);
2757 ok( hr
== S_OK
, "got %08x\n", hr
);
2759 hr
= IWinHttpRequest_Send( req
, empty
);
2760 ok( hr
== S_OK
, "got %08x\n", hr
);
2762 hr
= IWinHttpRequest_Abort( req
);
2763 ok( hr
== S_OK
, "got %08x\n", hr
);
2765 hr
= IWinHttpRequest_Abort( req
);
2766 ok( hr
== S_OK
, "got %08x\n", hr
);
2768 hr
= IWinHttpRequest_Release( req
);
2769 ok( hr
== S_OK
, "got %08x\n", hr
);
2771 SysFreeString( method
);
2772 SysFreeString( url
);
2773 SysFreeString( username
);
2774 SysFreeString( password
);
2775 SysFreeString( connection
);
2776 SysFreeString( date
);
2777 SysFreeString( today
);
2778 VariantClear( &proxy_server
);
2779 VariantClear( &bypass_list
);
2783 static void test_WinHttpDetectAutoProxyConfigUrl(void)
2789 if (0) /* crashes on some win2k systems */
2791 SetLastError(0xdeadbeef);
2792 ret
= WinHttpDetectAutoProxyConfigUrl( 0, NULL
);
2793 error
= GetLastError();
2794 ok( !ret
, "expected failure\n" );
2795 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2798 SetLastError(0xdeadbeef);
2799 ret
= WinHttpDetectAutoProxyConfigUrl( 0, &url
);
2800 error
= GetLastError();
2801 ok( !ret
, "expected failure\n" );
2802 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2804 if (0) /* crashes on some win2k systems */
2806 SetLastError(0xdeadbeef);
2807 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, NULL
);
2808 error
= GetLastError();
2809 ok( !ret
, "expected failure\n" );
2810 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2812 url
= (WCHAR
*)0xdeadbeef;
2813 SetLastError(0xdeadbeef);
2814 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A
, &url
);
2815 error
= GetLastError();
2818 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
2819 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
2823 trace("%s\n", wine_dbgstr_w(url
));
2827 url
= (WCHAR
*)0xdeadbeef;
2828 SetLastError(0xdeadbeef);
2829 ret
= WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP
, &url
);
2830 error
= GetLastError();
2833 ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
, "got %u\n", error
);
2834 ok( !url
|| broken(url
== (WCHAR
*)0xdeadbeef), "got %p\n", url
);
2838 trace("%s\n", wine_dbgstr_w(url
));
2843 static void test_WinHttpGetIEProxyConfigForCurrentUser(void)
2847 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg
;
2849 memset( &cfg
, 0, sizeof(cfg
) );
2851 SetLastError(0xdeadbeef);
2852 ret
= WinHttpGetIEProxyConfigForCurrentUser( NULL
);
2853 error
= GetLastError();
2854 ok( !ret
, "expected failure\n" );
2855 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2857 ret
= WinHttpGetIEProxyConfigForCurrentUser( &cfg
);
2858 ok( ret
, "expected success\n" );
2859 trace("IEProxy.AutoDetect=%d\n", cfg
.fAutoDetect
);
2860 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg
.lpszAutoConfigUrl
));
2861 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg
.lpszProxy
));
2862 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg
.lpszProxyBypass
));
2863 GlobalFree( cfg
.lpszAutoConfigUrl
);
2864 GlobalFree( cfg
.lpszProxy
);
2865 GlobalFree( cfg
.lpszProxyBypass
);
2868 static void test_WinHttpGetProxyForUrl(void)
2870 static const WCHAR urlW
[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
2871 static const WCHAR wpadW
[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0};
2872 static const WCHAR emptyW
[] = {0};
2876 WINHTTP_AUTOPROXY_OPTIONS options
;
2877 WINHTTP_PROXY_INFO info
;
2879 memset( &options
, 0, sizeof(options
) );
2881 SetLastError(0xdeadbeef);
2882 ret
= WinHttpGetProxyForUrl( NULL
, NULL
, NULL
, NULL
);
2883 error
= GetLastError();
2884 ok( !ret
, "expected failure\n" );
2885 ok( error
== ERROR_INVALID_HANDLE
, "got %u\n", error
);
2887 session
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2888 ok( session
!= NULL
, "failed to open session %u\n", GetLastError() );
2890 SetLastError(0xdeadbeef);
2891 ret
= WinHttpGetProxyForUrl( session
, NULL
, NULL
, NULL
);
2892 error
= GetLastError();
2893 ok( !ret
, "expected failure\n" );
2894 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2896 SetLastError(0xdeadbeef);
2897 ret
= WinHttpGetProxyForUrl( session
, emptyW
, NULL
, NULL
);
2898 error
= GetLastError();
2899 ok( !ret
, "expected failure\n" );
2900 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2902 SetLastError(0xdeadbeef);
2903 ret
= WinHttpGetProxyForUrl( session
, urlW
, NULL
, NULL
);
2904 error
= GetLastError();
2905 ok( !ret
, "expected failure\n" );
2906 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2908 SetLastError(0xdeadbeef);
2909 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2910 error
= GetLastError();
2911 ok( !ret
, "expected failure\n" );
2912 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2914 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
2915 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
2917 SetLastError(0xdeadbeef);
2918 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, NULL
);
2919 error
= GetLastError();
2920 ok( !ret
, "expected failure\n" );
2921 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2923 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
2924 options
.dwAutoDetectFlags
= 0;
2926 SetLastError(0xdeadbeef);
2927 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2928 error
= GetLastError();
2929 ok( !ret
, "expected failure\n" );
2930 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2932 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
| WINHTTP_AUTOPROXY_CONFIG_URL
;
2933 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
2935 SetLastError(0xdeadbeef);
2936 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2937 error
= GetLastError();
2938 ok( !ret
, "expected failure\n" );
2939 ok( error
== ERROR_INVALID_PARAMETER
, "got %u\n", error
);
2941 options
.dwFlags
= WINHTTP_AUTOPROXY_AUTO_DETECT
;
2942 options
.dwAutoDetectFlags
= WINHTTP_AUTO_DETECT_TYPE_DNS_A
;
2944 memset( &info
, 0, sizeof(info
) );
2945 SetLastError(0xdeadbeef);
2946 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2947 error
= GetLastError();
2948 if (!ret
) ok( error
== ERROR_WINHTTP_AUTODETECTION_FAILED
||
2949 error
== ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT
, "got %u\n", error
);
2952 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
2953 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
2954 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
2955 GlobalFree( info
.lpszProxy
);
2956 GlobalFree( info
.lpszProxyBypass
);
2959 options
.dwFlags
= WINHTTP_AUTOPROXY_CONFIG_URL
;
2960 options
.dwAutoDetectFlags
= 0;
2961 options
.lpszAutoConfigUrl
= wpadW
;
2963 memset( &info
, 0, sizeof(info
) );
2964 SetLastError(0xdeadbeef);
2965 ret
= WinHttpGetProxyForUrl( session
, urlW
, &options
, &info
);
2966 error
= GetLastError();
2967 if (!ret
) ok( error
== ERROR_WINHTTP_UNABLE_TO_DOWNLOAD_SCRIPT
, "got %u\n", error
);
2970 trace("Proxy.AccessType=%u\n", info
.dwAccessType
);
2971 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info
.lpszProxy
));
2972 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info
.lpszProxyBypass
));
2973 GlobalFree( info
.lpszProxy
);
2974 GlobalFree( info
.lpszProxyBypass
);
2976 WinHttpCloseHandle( session
);
2979 static void test_chunked_read(void)
2981 static const WCHAR verb
[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0};
2982 static const WCHAR chunked
[] = {'c','h','u','n','k','e','d',0};
2985 HINTERNET ses
, con
= NULL
, req
= NULL
;
2988 trace( "starting chunked read test\n" );
2990 ses
= WinHttpOpen( test_useragent
, 0, NULL
, NULL
, 0 );
2991 ok( ses
!= NULL
, "WinHttpOpen failed with error %u\n", GetLastError() );
2992 if (!ses
) goto done
;
2994 con
= WinHttpConnect( ses
, test_winehq
, 0, 0 );
2995 ok( con
!= NULL
, "WinHttpConnect failed with error %u\n", GetLastError() );
2996 if (!con
) goto done
;
2998 req
= WinHttpOpenRequest( con
, NULL
, verb
, NULL
, NULL
, NULL
, 0 );
2999 ok( req
!= NULL
, "WinHttpOpenRequest failed with error %u\n", GetLastError() );
3000 if (!req
) goto done
;
3002 ret
= WinHttpSendRequest( req
, NULL
, 0, NULL
, 0, 0, 0 );
3003 ok( ret
, "WinHttpSendRequest failed with error %u\n", GetLastError() );
3005 ret
= WinHttpReceiveResponse( req
, NULL
);
3006 ok( ret
, "WinHttpReceiveResponse failed with error %u\n", GetLastError() );
3009 len
= sizeof(header
);
3010 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_TRANSFER_ENCODING
, NULL
, header
, &len
, 0 );
3011 ok( ret
, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() );
3012 ok( !lstrcmpW( header
, chunked
), "wrong transfer encoding %s\n", wine_dbgstr_w(header
) );
3013 trace( "transfer encoding: %s\n", wine_dbgstr_w(header
) );
3016 len
= sizeof(header
);
3017 SetLastError( 0xdeadbeef );
3018 ret
= WinHttpQueryHeaders( req
, WINHTTP_QUERY_CONTENT_LENGTH
, NULL
, &header
, &len
, 0 );
3019 ok( !ret
, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header
) );
3020 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND
, "wrong error %u\n", GetLastError() );
3022 trace( "entering query loop\n" );
3026 ret
= WinHttpQueryDataAvailable( req
, &len
);
3027 ok( ret
, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() );
3028 if (ret
) ok( len
!= 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" );
3029 trace( "got %u available\n", len
);
3033 char *buf
= HeapAlloc( GetProcessHeap(), 0, len
+ 1 );
3035 ret
= WinHttpReadData( req
, buf
, len
, &bytes_read
);
3037 buf
[bytes_read
] = 0;
3038 trace( "WinHttpReadData -> %d %u\n", ret
, bytes_read
);
3039 ok( len
== bytes_read
, "only got %u of %u available\n", bytes_read
, len
);
3040 ok( buf
[bytes_read
- 1] == '\n', "received partial line '%s'\n", buf
);
3042 HeapFree( GetProcessHeap(), 0, buf
);
3043 if (!bytes_read
) break;
3050 if (req
) WinHttpCloseHandle( req
);
3051 if (con
) WinHttpCloseHandle( con
);
3052 if (ses
) WinHttpCloseHandle( ses
);
3055 START_TEST (winhttp
)
3057 static const WCHAR basicW
[] = {'/','b','a','s','i','c',0};
3058 static const WCHAR quitW
[] = {'/','q','u','i','t',0};
3059 struct server_info si
;
3065 test_WinHttpTimeFromSystemTime();
3066 test_WinHttpTimeToSystemTime();
3067 test_WinHttpAddHeaders();
3068 test_secure_connection();
3069 test_request_parameter_defaults();
3071 test_set_default_proxy_config();
3072 test_empty_headers_param();
3074 test_resolve_timeout();
3076 test_IWinHttpRequest();
3077 test_WinHttpDetectAutoProxyConfigUrl();
3078 test_WinHttpGetIEProxyConfigForCurrentUser();
3079 test_WinHttpGetProxyForUrl();
3080 test_chunked_read();
3082 si
.event
= CreateEventW(NULL
, 0, 0, NULL
);
3085 thread
= CreateThread(NULL
, 0, server_thread
, (LPVOID
)&si
, 0, NULL
);
3086 ok(thread
!= NULL
, "failed to create thread %u\n", GetLastError());
3088 ret
= WaitForSingleObject(si
.event
, 10000);
3089 ok(ret
== WAIT_OBJECT_0
, "failed to start winhttp test server %u\n", GetLastError());
3090 if (ret
!= WAIT_OBJECT_0
)
3093 test_connection_info(si
.port
);
3094 test_basic_request(si
.port
, NULL
, basicW
);
3095 test_no_headers(si
.port
);
3096 test_basic_authentication(si
.port
);
3097 test_bad_header(si
.port
);
3098 test_multiple_reads(si
.port
);
3100 /* send the basic request again to shutdown the server thread */
3101 test_basic_request(si
.port
, NULL
, quitW
);
3103 WaitForSingleObject(thread
, 3000);