winhttp: Option WINHTTP_OPTION_SERVER_CERT_CONTEXT must return a pointer.
[wine/multimedia.git] / dlls / winhttp / tests / winhttp.c
blob79148053309971fd0554701dc5b7f0a69de7825e
1 /*
2 * WinHTTP - tests
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 #include <stdarg.h>
22 #include <stdlib.h>
23 #include <windef.h>
24 #include <winbase.h>
25 #include <winhttp.h>
26 #include <wincrypt.h>
28 #include "wine/test.h"
30 static const WCHAR test_useragent[] =
31 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0};
32 static const WCHAR test_server[] = {'w','i','n','e','h','q','.','o','r','g',0};
34 static void test_OpenRequest (void)
36 BOOL ret;
37 HINTERNET session, request, connection;
39 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
40 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
41 ok(session != NULL, "WinHttpOpen failed to open session.\n");
43 /* Test with a bad server name */
44 SetLastError(0xdeadbeef);
45 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0);
46 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n");
47 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", GetLastError());
49 /* Test with a valid server name */
50 connection = WinHttpConnect (session, test_server, INTERNET_DEFAULT_HTTP_PORT, 0);
51 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
53 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER,
54 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
55 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
57 skip("Network unreachable, skipping.\n");
58 goto done;
60 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
62 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0);
63 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
64 ret = WinHttpCloseHandle(request);
65 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
67 done:
68 ret = WinHttpCloseHandle(connection);
69 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
70 ret = WinHttpCloseHandle(session);
71 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
75 static void test_SendRequest (void)
77 HINTERNET session, request, connection;
78 DWORD header_len, optional_len, total_len;
79 DWORD bytes_rw;
80 BOOL ret;
81 CHAR buffer[256];
82 int i;
84 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
85 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
86 static const WCHAR content_type[] =
87 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n',
88 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0};
89 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
90 static const WCHAR test_verb[] = {'P','O','S','T',0};
91 static CHAR post_data[] = "mode=Test";
92 static CHAR test_post[] = "mode => Test\\0\n";
94 header_len = -1L;
95 total_len = optional_len = sizeof(post_data);
96 memset(buffer, 0xff, sizeof(buffer));
98 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
99 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
100 ok(session != NULL, "WinHttpOpen failed to open session.\n");
102 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
103 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
105 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
106 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE);
107 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
109 skip("Network unreachable, skipping.\n");
110 goto done;
112 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError());
114 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, 0);
115 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError());
117 for (i = 3; post_data[i]; i++)
119 bytes_rw = -1;
120 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw);
121 ok(ret == TRUE, "WinHttpWriteData failed: %u.\n", GetLastError());
122 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw);
125 ret = WinHttpReceiveResponse(request, NULL);
126 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError());
128 bytes_rw = -1;
129 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw);
130 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError());
132 ok(bytes_rw == strlen(test_post), "Read %u bytes instead of %d.\n", bytes_rw, lstrlen(test_post));
133 ok(strncmp(buffer, test_post, bytes_rw) == 0, "Data read did not match, got '%s'.\n", buffer);
135 ret = WinHttpCloseHandle(request);
136 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
137 done:
138 ret = WinHttpCloseHandle(connection);
139 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
140 ret = WinHttpCloseHandle(session);
141 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
144 static void test_WinHttpTimeFromSystemTime(void)
146 BOOL ret;
147 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0};
148 static const WCHAR expected_string[] =
149 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
150 '1','0',':','0','5',':','5','2',' ','G','M','T',0};
151 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1];
153 ret = WinHttpTimeFromSystemTime(&time, time_string);
154 ok(ret == TRUE, "WinHttpTimeFromSystemTime failed: %u\n", GetLastError());
155 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0,
156 "Time string returned did not match expected time string.\n");
159 static void test_WinHttpTimeToSystemTime(void)
161 BOOL ret;
162 SYSTEMTIME time;
163 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0};
164 static const WCHAR time_string1[] =
165 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ',
166 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0};
167 static const WCHAR time_string2[] =
168 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ',
169 '1','0',' ','0','5',' ','5','2','\n',0};
171 ret = WinHttpTimeToSystemTime(time_string1, &time);
172 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
173 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
174 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
176 ret = WinHttpTimeToSystemTime(time_string2, &time);
177 ok(ret == TRUE, "WinHttpTimeToSystemTime failed: %u\n", GetLastError());
178 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0,
179 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n");
182 static void test_WinHttpAddHeaders(void)
184 HINTERNET session, request, connection;
185 BOOL ret;
186 WCHAR buffer[MAX_PATH];
187 WCHAR check_buffer[MAX_PATH];
188 DWORD index, len, oldlen;
190 static const WCHAR test_site[] = {'c','r','o','s','s','o','v','e','r','.',
191 'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
192 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0};
193 static const WCHAR test_verb[] = {'P','O','S','T',0};
195 static const WCHAR test_header_begin[] =
196 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'};
197 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0};
198 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0};
200 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0};
201 static const WCHAR test_flag_coalesce_comma[] =
202 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0};
203 static const WCHAR test_flag_coalesce_semicolon[] =
204 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0};
206 static const WCHAR field[] = {'f','i','e','l','d',0};
207 static const WCHAR value[] = {'v','a','l','u','e',' ',0};
209 static const WCHAR test_headers[][14] =
211 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0},
212 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0},
213 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0},
214 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0},
215 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0},
216 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0},
217 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0},
218 {0},
219 {':',0},
220 {'a',':',0},
221 {':','b',0},
222 {'c','d',0},
223 {' ','e',' ',':','f',0},
224 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}
226 static const WCHAR test_indices[][6] =
228 {'t','e','s','t','1',0},
229 {'t','e','s','t','2',0},
230 {'t','e','s','t','3',0},
231 {'t','e','s','t','4',0}
234 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY,
235 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0);
236 ok(session != NULL, "WinHttpOpen failed to open session.\n");
238 connection = WinHttpConnect (session, test_site, INTERNET_DEFAULT_HTTP_PORT, 0);
239 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError());
241 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER,
242 WINHTTP_DEFAULT_ACCEPT_TYPES, 0);
243 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED)
245 skip("Network unreachable, skipping.\n");
246 goto done;
248 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError());
250 index = 0;
251 len = sizeof(buffer);
252 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
253 test_header_name, buffer, &len, &index);
254 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n");
255 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD);
256 ok(ret == TRUE, "WinHttpAddRequestHeader failed to add new header, got %d with error %u.\n", ret, GetLastError());
258 index = 0;
259 len = sizeof(buffer);
260 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
261 test_header_name, buffer, &len, &index);
262 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
263 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n");
264 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n");
265 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len);
267 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
268 test_header_name, buffer, &len, &index);
269 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n");
271 /* Try to fetch the header info with a buffer that's big enough to fit the
272 * string but not the NULL terminator.
274 index = 0;
275 len = 5*sizeof(WCHAR);
276 memcpy(buffer, check_buffer, sizeof(buffer));
277 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
278 test_header_name, buffer, &len, &index);
279 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n");
280 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0,
281 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n");
282 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len);
284 /* Try with a NULL buffer */
285 index = 0;
286 len = sizeof(buffer);
287 SetLastError(0xdeadbeef);
288 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
289 test_header_name, NULL, &len, &index);
290 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
291 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
292 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
293 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
295 /* Try with a NULL buffer and a length that's too small */
296 index = 0;
297 len = 10;
298 SetLastError(0xdeadbeef);
299 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
300 test_header_name, NULL, &len, &index);
301 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
302 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
303 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, go %u\n", GetLastError());
304 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
305 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n");
307 index = 0;
308 len = 0;
309 SetLastError(0xdeadbeef);
310 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
311 test_header_name, NULL, &len, &index);
312 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
313 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
314 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
315 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
316 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
318 /* valid query */
319 oldlen = len;
320 index = 0;
321 len = sizeof(buffer);
322 memset(buffer, 0xff, sizeof(buffer));
323 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
324 test_header_name, buffer, &len, &index);
325 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret);
326 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n");
327 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n");
328 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n");
329 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0,
330 "WinHttpQueryHeaders returned invalid beginning of header string.\n");
331 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0,
332 "WinHttpQueryHeaders returned invalid end of header string.\n");
333 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n");
335 index = 0;
336 len = 0;
337 SetLastError(0xdeadbeef);
338 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
339 test_header_name, NULL, &len, &index);
340 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n");
341 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER,
342 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError());
343 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len);
344 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n");
346 oldlen = len;
347 index = 0;
348 len = sizeof(buffer);
349 memset(buffer, 0xff, sizeof(buffer));
350 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
351 test_header_name, buffer, &len, &index);
352 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError());
353 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n");
354 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1],
355 "no double NULL terminator\n");
356 ok(!memcmp(buffer, test_header_begin, sizeof(test_header_begin)), "invalid beginning of header string\n");
357 ok(index == 0, "header index was incremented\n");
359 /* tests for more indices */
360 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD);
361 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret);
363 index = 0;
364 len = sizeof(buffer);
365 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
366 test_header_name, buffer, &len, &index);
367 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
368 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
369 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
371 len = sizeof(buffer);
372 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
373 test_header_name, buffer, &len, &index);
374 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
375 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
376 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
378 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE);
379 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n");
381 index = 0;
382 len = sizeof(buffer);
383 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
384 test_header_name, buffer, &len, &index);
385 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
386 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
387 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
389 len = sizeof(buffer);
390 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
391 test_header_name, buffer, &len, &index);
392 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
393 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
394 ok(memcmp(buffer, test_indices[2], sizeof(test_indices[2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
396 /* add if new flag */
397 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW);
398 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n");
400 index = 0;
401 len = sizeof(buffer);
402 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
403 test_header_name, buffer, &len, &index);
404 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
405 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
406 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
408 len = sizeof(buffer);
409 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
410 test_header_name, buffer, &len, &index);
411 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
412 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
413 ok(memcmp(buffer, test_indices[2], sizeof(test_indices[2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
415 len = sizeof(buffer);
416 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
417 test_header_name, buffer, &len, &index);
418 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
420 /* coalesce flag */
421 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE);
422 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n");
424 index = 0;
425 len = sizeof(buffer);
426 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
427 test_header_name, buffer, &len, &index);
428 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
429 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
430 ok(memcmp(buffer, test_flag_coalesce, sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
432 len = sizeof(buffer);
433 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
434 test_header_name, buffer, &len, &index);
435 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
436 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
437 ok(memcmp(buffer, test_indices[2], sizeof(test_indices[2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
439 len = sizeof(buffer);
440 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
441 test_header_name, buffer, &len, &index);
442 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
444 /* coalesce with comma flag */
445 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA);
446 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n");
448 index = 0;
449 len = sizeof(buffer);
450 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
451 test_header_name, buffer, &len, &index);
452 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
453 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
454 ok(memcmp(buffer, test_flag_coalesce_comma, sizeof(test_flag_coalesce_comma)) == 0,
455 "WinHttpQueryHeaders returned incorrect string.\n");
457 len = sizeof(buffer);
458 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
459 test_header_name, buffer, &len, &index);
460 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
461 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
462 ok(memcmp(buffer, test_indices[2], sizeof(test_indices[2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
464 len = sizeof(buffer);
465 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
466 test_header_name, buffer, &len, &index);
467 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
470 /* coalesce with semicolon flag */
471 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON);
472 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n");
474 index = 0;
475 len = sizeof(buffer);
476 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
477 test_header_name, buffer, &len, &index);
478 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
479 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
480 ok(memcmp(buffer, test_flag_coalesce_semicolon, sizeof(test_flag_coalesce_semicolon)) == 0,
481 "WinHttpQueryHeaders returned incorrect string.\n");
483 len = sizeof(buffer);
484 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
485 test_header_name, buffer, &len, &index);
486 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
487 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
488 ok(memcmp(buffer, test_indices[2], sizeof(test_indices[2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
490 len = sizeof(buffer);
491 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
492 test_header_name, buffer, &len, &index);
493 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
495 /* add and replace flags */
496 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE);
497 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n");
499 index = 0;
500 len = sizeof(buffer);
501 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
502 test_header_name, buffer, &len, &index);
503 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
504 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n");
505 ok(memcmp(buffer, test_indices[2], sizeof(test_indices[2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
507 len = sizeof(buffer);
508 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
509 test_header_name, buffer, &len, &index);
510 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError());
511 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n");
512 ok(memcmp(buffer, test_indices[3], sizeof(test_indices[2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n");
514 len = sizeof(buffer);
515 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
516 test_header_name, buffer, &len, &index);
517 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n");
519 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0UL, WINHTTP_ADDREQ_FLAG_ADD);
520 ok(!ret, "WinHttpAddRequestHeaders failed\n");
522 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0UL, WINHTTP_ADDREQ_FLAG_ADD);
523 ok(ret, "WinHttpAddRequestHeaders failed\n");
525 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0UL, WINHTTP_ADDREQ_FLAG_ADD);
526 ok(!ret, "WinHttpAddRequestHeaders failed\n");
528 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0UL, WINHTTP_ADDREQ_FLAG_ADD);
529 ok(!ret, "WinHttpAddRequestHeaders failed\n");
531 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0UL, WINHTTP_ADDREQ_FLAG_ADD);
532 ok(!ret, "WinHttpAddRequestHeaders failed\n");
534 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0UL, WINHTTP_ADDREQ_FLAG_ADD);
535 ok(ret, "WinHttpAddRequestHeaders failed\n");
537 index = 0;
538 buffer[0] = 0;
539 len = sizeof(buffer);
540 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS,
541 field, buffer, &len, &index);
542 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError());
543 ok(!memcmp(buffer, value, sizeof(value)), "unexpected result\n");
545 ret = WinHttpCloseHandle(request);
546 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret);
547 done:
548 ret = WinHttpCloseHandle(connection);
549 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret);
550 ret = WinHttpCloseHandle(session);
551 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret);
555 static void test_secure_connection(void)
557 static const WCHAR google[] = {'w','w','w','.','g','o','o','g','l','e','.','c','o','m',0};
559 HANDLE ses, con, req;
560 DWORD size, status, policy, bitness;
561 BOOL ret;
562 CERT_CONTEXT *cert;
564 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
565 ok(ses != NULL, "failed to open session %u\n", GetLastError());
567 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS;
568 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy));
569 ok(ret, "failed to set redirect policy %u\n", GetLastError());
571 con = WinHttpConnect(ses, google, 443, 0);
572 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
574 /* try without setting WINHTTP_FLAG_SECURE */
575 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
576 ok(req != NULL, "failed to open a request %u\n", GetLastError());
578 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
579 ok(ret, "failed to send request %u\n", GetLastError());
581 ret = WinHttpReceiveResponse(req, NULL);
582 ok(!ret, "succeeded unexpectedly\n");
584 size = 0;
585 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
586 ok(!ret, "succeeded unexpectedly\n");
588 WinHttpCloseHandle(req);
590 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE);
591 ok(req != NULL, "failed to open a request %u\n", GetLastError());
593 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
594 ok(ret, "failed to send request %u\n", GetLastError());
596 size = sizeof(cert);
597 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size );
598 ok(ret, "failed to retrieve certificate context %u\n", GetLastError());
600 size = sizeof(bitness);
601 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size );
602 ok(ret, "failed to retrieve key bitness %u\n", GetLastError());
604 ret = WinHttpReceiveResponse(req, NULL);
605 ok(ret, "failed to receive response %u\n", GetLastError());
607 size = sizeof(status);
608 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
609 ok(ret, "failed unexpectedly %u\n", GetLastError());
610 ok(status == 200, "request failed unexpectedly %u\n", status);
612 size = 0;
613 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL);
614 ok(!ret, "succeeded unexpectedly\n");
616 WinHttpCloseHandle(req);
617 WinHttpCloseHandle(con);
618 WinHttpCloseHandle(ses);
621 static void test_request_parameter_defaults(void)
623 static const WCHAR empty[] = {0};
624 static const WCHAR codeweavers[] = {'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m',0};
626 HANDLE ses, con, req;
627 DWORD size, status;
628 BOOL ret;
630 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0);
631 ok(ses != NULL, "failed to open session %u\n", GetLastError());
633 con = WinHttpConnect(ses, codeweavers, 0, 0);
634 ok(con != NULL, "failed to open a connection %u\n", GetLastError());
636 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0);
637 ok(req != NULL, "failed to open a request %u\n", GetLastError());
639 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
640 ok(ret, "failed to send request %u\n", GetLastError());
642 ret = WinHttpReceiveResponse(req, NULL);
643 ok(ret, "failed to receive response %u\n", GetLastError());
645 size = sizeof(status);
646 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
647 ok(ret, "failed unexpectedly %u\n", GetLastError());
648 ok(status == 200, "request failed unexpectedly %u\n", status);
650 WinHttpCloseHandle(req);
652 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0);
653 ok(req != NULL, "failed to open a request %u\n", GetLastError());
655 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0);
656 ok(ret, "failed to send request %u\n", GetLastError());
658 ret = WinHttpReceiveResponse(req, NULL);
659 ok(ret, "failed to receive response %u\n", GetLastError());
661 size = sizeof(status);
662 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL);
663 ok(ret, "failed unexpectedly %u\n", GetLastError());
664 ok(status == 200, "request failed unexpectedly %u\n", status);
666 WinHttpCloseHandle(req);
667 WinHttpCloseHandle(con);
668 WinHttpCloseHandle(ses);
671 START_TEST (winhttp)
673 test_OpenRequest();
674 test_SendRequest();
675 test_WinHttpTimeFromSystemTime();
676 test_WinHttpTimeToSystemTime();
677 test_WinHttpAddHeaders();
678 test_secure_connection();
679 test_request_parameter_defaults();