1 /* 2 * WinHTTP - tests 3 * 4 * Copyright 2008 Google (Zac Brown) 5 * Copyright 2015 Dmitry Timoshkov 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #define COBJMACROS 23 #include <stdarg.h> 24 #include <windef.h> 25 #include <winsock2.h> 26 #include <ws2tcpip.h> 27 #include <winhttp.h> 28 #include <wincrypt.h> 29 #include <winreg.h> 30 #include <stdio.h> 31 #include <initguid.h> 32 #include <httprequest.h> 33 #include <httprequestid.h> 34 35 #include "wine/test.h" 36 37 DEFINE_GUID(GUID_NULL,0,0,0,0,0,0,0,0,0,0,0); 38 39 static const WCHAR test_useragent[] = 40 {'W','i','n','e',' ','R','e','g','r','e','s','s','i','o','n',' ','T','e','s','t',0}; 41 static const WCHAR test_winehq[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0}; 42 static const WCHAR test_winehq_https[] = {'h','t','t','p','s',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','4','4','3',0}; 43 static const WCHAR localhostW[] = {'l','o','c','a','l','h','o','s','t',0}; 44 45 static BOOL proxy_active(void) 46 { 47 WINHTTP_PROXY_INFO proxy_info; 48 BOOL active = FALSE; 49 50 SetLastError(0xdeadbeef); 51 if (WinHttpGetDefaultProxyConfiguration(&proxy_info)) 52 { 53 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 54 "got %u\n", GetLastError()); 55 active = (proxy_info.lpszProxy != NULL); 56 if (active) 57 GlobalFree(proxy_info.lpszProxy); 58 if (proxy_info.lpszProxyBypass != NULL) 59 GlobalFree(proxy_info.lpszProxyBypass); 60 } 61 else 62 active = FALSE; 63 64 return active; 65 } 66 67 static void test_QueryOption(void) 68 { 69 BOOL ret; 70 HINTERNET session, request, connection; 71 DWORD feature, size; 72 73 SetLastError(0xdeadbeef); 74 session = WinHttpOpen(test_useragent, 0, 0, 0, 0); 75 ok(session != NULL, "WinHttpOpen failed to open session, error %u\n", GetLastError()); 76 77 SetLastError(0xdeadbeef); 78 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, NULL); 79 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 80 ok(GetLastError() == ERROR_INVALID_PARAMETER, 81 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 82 83 size = 0xdeadbeef; 84 SetLastError(0xdeadbeef); 85 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, &size); 86 ok(!ret, "should fail to query option\n"); 87 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 88 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 89 ok(size == 4, "expected 4, got %u\n", size); 90 91 feature = 0xdeadbeef; 92 size = sizeof(feature) - 1; 93 SetLastError(0xdeadbeef); 94 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size); 95 ok(!ret, "should fail to query option\n"); 96 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 97 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 98 ok(size == 4, "expected 4, got %u\n", size); 99 100 feature = 0xdeadbeef; 101 size = sizeof(feature) + 1; 102 SetLastError(0xdeadbeef); 103 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size); 104 ok(ret, "failed to query option %u\n", GetLastError()); 105 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 106 "got %u\n", GetLastError()); 107 ok(size == sizeof(feature), "WinHttpQueryOption should set the size: %u\n", size); 108 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, 109 "expected WINHTTP_OPTION_REDIRECT_POLICY_DISALLOW_HTTPS_TO_HTTP, got %#x\n", feature); 110 111 SetLastError(0xdeadbeef); 112 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, NULL, sizeof(feature)); 113 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 114 ok(GetLastError() == ERROR_INVALID_PARAMETER, 115 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 116 117 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 118 SetLastError(0xdeadbeef); 119 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) - 1); 120 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 121 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 122 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 123 124 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 125 SetLastError(0xdeadbeef); 126 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature) + 1); 127 ok(!ret, "should fail to set redirect policy %u\n", GetLastError()); 128 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 129 "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 130 131 feature = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 132 SetLastError(0xdeadbeef); 133 ret = WinHttpSetOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, sizeof(feature)); 134 ok(ret, "failed to set redirect policy %u\n", GetLastError()); 135 136 feature = 0xdeadbeef; 137 size = sizeof(feature); 138 SetLastError(0xdeadbeef); 139 ret = WinHttpQueryOption(session, WINHTTP_OPTION_REDIRECT_POLICY, &feature, &size); 140 ok(ret, "failed to query option %u\n", GetLastError()); 141 ok(feature == WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, 142 "expected WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS, got %#x\n", feature); 143 144 feature = WINHTTP_DISABLE_COOKIES; 145 SetLastError(0xdeadbeef); 146 ret = WinHttpSetOption(session, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 147 ok(!ret, "should fail to set disable feature for a session\n"); 148 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 149 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError()); 150 151 SetLastError(0xdeadbeef); 152 connection = WinHttpConnect(session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 153 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u\n", GetLastError()); 154 155 feature = WINHTTP_DISABLE_COOKIES; 156 SetLastError(0xdeadbeef); 157 ret = WinHttpSetOption(connection, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 158 ok(!ret, "should fail to set disable feature for a connection\n"); 159 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 160 "expected ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, got %u\n", GetLastError()); 161 162 SetLastError(0xdeadbeef); 163 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER, 164 WINHTTP_DEFAULT_ACCEPT_TYPES, 0); 165 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED) 166 { 167 skip("Network unreachable, skipping the test\n"); 168 goto done; 169 } 170 171 feature = 0xdeadbeef; 172 size = sizeof(feature); 173 SetLastError(0xdeadbeef); 174 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, &size); 175 ok(!ret, "should fail to query disable feature for a request\n"); 176 ok(GetLastError() == ERROR_INVALID_PARAMETER, 177 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 178 179 feature = 0; 180 size = sizeof(feature); 181 SetLastError(0xdeadbeef); 182 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 183 ok(ret, "failed to set feature %u\n", GetLastError()); 184 185 feature = 0xffffffff; 186 size = sizeof(feature); 187 SetLastError(0xdeadbeef); 188 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 189 ok(ret, "failed to set feature %u\n", GetLastError()); 190 191 feature = WINHTTP_DISABLE_COOKIES; 192 size = sizeof(feature); 193 SetLastError(0xdeadbeef); 194 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &feature, sizeof(feature)); 195 ok(ret, "failed to set feature %u\n", GetLastError()); 196 197 size = 0; 198 SetLastError(0xdeadbeef); 199 ret = WinHttpQueryOption(request, WINHTTP_OPTION_DISABLE_FEATURE, NULL, &size); 200 ok(!ret, "should fail to query disable feature for a request\n"); 201 ok(GetLastError() == ERROR_INVALID_PARAMETER, 202 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 203 204 SetLastError(0xdeadbeef); 205 ret = WinHttpCloseHandle(request); 206 ok(ret, "WinHttpCloseHandle failed on closing request: %u\n", GetLastError()); 207 208 done: 209 SetLastError(0xdeadbeef); 210 ret = WinHttpCloseHandle(connection); 211 ok(ret, "WinHttpCloseHandle failed on closing connection: %u\n", GetLastError()); 212 SetLastError(0xdeadbeef); 213 ret = WinHttpCloseHandle(session); 214 ok(ret, "WinHttpCloseHandle failed on closing session: %u\n", GetLastError()); 215 } 216 217 static void test_OpenRequest (void) 218 { 219 BOOL ret; 220 HINTERNET session, request, connection; 221 DWORD err; 222 223 SetLastError(0xdeadbeef); 224 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 225 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 226 err = GetLastError(); 227 ok(session != NULL, "WinHttpOpen failed to open session.\n"); 228 ok(err == ERROR_SUCCESS, "got %u\n", err); 229 230 /* Test with a bad server name */ 231 SetLastError(0xdeadbeef); 232 connection = WinHttpConnect(session, NULL, INTERNET_DEFAULT_HTTP_PORT, 0); 233 err = GetLastError(); 234 ok (connection == NULL, "WinHttpConnect succeeded in opening connection to NULL server argument.\n"); 235 ok(err == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER, got %u.\n", err); 236 237 /* Test with a valid server name */ 238 SetLastError(0xdeadbeef); 239 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 240 err = GetLastError(); 241 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", err); 242 ok(err == ERROR_SUCCESS || broken(err == WSAEINVAL) /* < win7 */, "got %u\n", err); 243 244 SetLastError(0xdeadbeef); 245 request = WinHttpOpenRequest(connection, NULL, NULL, NULL, WINHTTP_NO_REFERER, 246 WINHTTP_DEFAULT_ACCEPT_TYPES, 0); 247 err = GetLastError(); 248 if (request == NULL && err == ERROR_WINHTTP_NAME_NOT_RESOLVED) 249 { 250 skip("Network unreachable, skipping.\n"); 251 goto done; 252 } 253 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", err); 254 ok(err == ERROR_SUCCESS, "got %u\n", err); 255 256 SetLastError(0xdeadbeef); 257 ret = WinHttpSendRequest(request, WINHTTP_NO_ADDITIONAL_HEADERS, 0, NULL, 0, 0, 0); 258 err = GetLastError(); 259 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 260 { 261 skip("Connection failed, skipping.\n"); 262 goto done; 263 } 264 ok(ret, "WinHttpSendRequest failed: %u\n", err); 265 ok(err == ERROR_SUCCESS, "got %u\n", err); 266 267 SetLastError(0xdeadbeef); 268 ret = WinHttpCloseHandle(request); 269 err = GetLastError(); 270 ok(ret, "WinHttpCloseHandle failed on closing request, got %u.\n", err); 271 ok(err == ERROR_SUCCESS, "got %u\n", err); 272 273 done: 274 ret = WinHttpCloseHandle(connection); 275 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret); 276 ret = WinHttpCloseHandle(session); 277 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret); 278 279 } 280 281 static void test_empty_headers_param(void) 282 { 283 static const WCHAR empty[] = {0}; 284 HINTERNET ses, con, req; 285 DWORD err; 286 BOOL ret; 287 288 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 289 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 290 291 con = WinHttpConnect(ses, test_winehq, 80, 0); 292 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 293 294 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 295 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 296 297 ret = WinHttpSendRequest(req, empty, 0, NULL, 0, 0, 0); 298 err = GetLastError(); 299 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 300 { 301 skip("connection failed, skipping\n"); 302 goto done; 303 } 304 ok(ret, "failed to send request %u\n", GetLastError()); 305 306 done: 307 WinHttpCloseHandle(req); 308 WinHttpCloseHandle(con); 309 WinHttpCloseHandle(ses); 310 } 311 312 static void test_SendRequest (void) 313 { 314 static const WCHAR content_type[] = 315 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ','a','p','p','l','i','c','a','t','i','o','n', 316 '/','x','-','w','w','w','-','f','o','r','m','-','u','r','l','e','n','c','o','d','e','d',0}; 317 static const WCHAR test_file[] = {'t','e','s','t','s','/','p','o','s','t','.','p','h','p',0}; 318 static const WCHAR test_verb[] = {'P','O','S','T',0}; 319 static CHAR post_data[] = "mode=Test"; 320 static const char test_post[] = "mode => Test\0\n"; 321 HINTERNET session, request, connection; 322 DWORD header_len, optional_len, total_len, bytes_rw, size, err, disable; 323 DWORD_PTR context; 324 BOOL ret; 325 CHAR buffer[256]; 326 int i; 327 328 header_len = -1L; 329 total_len = optional_len = sizeof(post_data); 330 memset(buffer, 0xff, sizeof(buffer)); 331 332 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 333 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 334 ok(session != NULL, "WinHttpOpen failed to open session.\n"); 335 336 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 337 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError()); 338 339 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER, 340 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE); 341 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED) 342 { 343 skip("Network unreachable, skipping.\n"); 344 goto done; 345 } 346 ok(request != NULL, "WinHttpOpenrequest failed to open a request, error: %u.\n", GetLastError()); 347 if (!request) goto done; 348 349 context = 0xdeadbeef; 350 ret = WinHttpSetOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, sizeof(context)); 351 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError()); 352 353 /* writing more data than promised by the content-length header causes an error when the connection 354 is resued, so disable keep-alive */ 355 disable = WINHTTP_DISABLE_KEEP_ALIVE; 356 ret = WinHttpSetOption(request, WINHTTP_OPTION_DISABLE_FEATURE, &disable, sizeof(disable)); 357 ok(ret, "WinHttpSetOption failed: %u\n", GetLastError()); 358 359 context++; 360 ret = WinHttpSendRequest(request, content_type, header_len, post_data, optional_len, total_len, context); 361 err = GetLastError(); 362 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 363 { 364 skip("connection failed, skipping\n"); 365 goto done; 366 } 367 ok(ret == TRUE, "WinHttpSendRequest failed: %u\n", GetLastError()); 368 369 context = 0; 370 size = sizeof(context); 371 ret = WinHttpQueryOption(request, WINHTTP_OPTION_CONTEXT_VALUE, &context, &size); 372 ok(ret, "WinHttpQueryOption failed: %u\n", GetLastError()); 373 ok(context == 0xdeadbef0, "expected 0xdeadbef0, got %lx\n", context); 374 375 for (i = 3; post_data[i]; i++) 376 { 377 bytes_rw = -1; 378 SetLastError(0xdeadbeef); 379 ret = WinHttpWriteData(request, &post_data[i], 1, &bytes_rw); 380 if (ret) 381 { 382 ok(GetLastError() == ERROR_SUCCESS, "Expected ERROR_SUCCESS got %u.\n", GetLastError()); 383 ok(bytes_rw == 1, "WinHttpWriteData failed, wrote %u bytes instead of 1 byte.\n", bytes_rw); 384 } 385 else /* Since we already passed all optional data in WinHttpSendRequest Win7 fails our WinHttpWriteData call */ 386 { 387 ok(GetLastError() == ERROR_INVALID_PARAMETER, "Expected ERROR_INVALID_PARAMETER got %u.\n", GetLastError()); 388 ok(bytes_rw == -1, "Expected bytes_rw to remain unchanged.\n"); 389 } 390 } 391 392 SetLastError(0xdeadbeef); 393 ret = WinHttpReceiveResponse(request, NULL); 394 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == ERROR_NO_TOKEN) /* < win7 */, 395 "Expected ERROR_SUCCESS got %u.\n", GetLastError()); 396 ok(ret == TRUE, "WinHttpReceiveResponse failed: %u.\n", GetLastError()); 397 398 bytes_rw = -1; 399 ret = WinHttpReadData(request, buffer, sizeof(buffer) - 1, &bytes_rw); 400 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError()); 401 402 ok(bytes_rw == sizeof(test_post) - 1, "Read %u bytes\n", bytes_rw); 403 ok(!memcmp(buffer, test_post, sizeof(test_post) - 1), "Data read did not match.\n"); 404 405 done: 406 ret = WinHttpCloseHandle(request); 407 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret); 408 ret = WinHttpCloseHandle(connection); 409 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret); 410 ret = WinHttpCloseHandle(session); 411 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret); 412 } 413 414 static void test_WinHttpTimeFromSystemTime(void) 415 { 416 BOOL ret; 417 static const SYSTEMTIME time = {2008, 7, 1, 28, 10, 5, 52, 0}; 418 static const WCHAR expected_string[] = 419 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ', 420 '1','0',':','0','5',':','5','2',' ','G','M','T',0}; 421 WCHAR time_string[WINHTTP_TIME_FORMAT_BUFSIZE+1]; 422 DWORD err; 423 424 SetLastError(0xdeadbeef); 425 ret = WinHttpTimeFromSystemTime(&time, NULL); 426 err = GetLastError(); 427 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n"); 428 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 429 430 SetLastError(0xdeadbeef); 431 ret = WinHttpTimeFromSystemTime(NULL, time_string); 432 err = GetLastError(); 433 ok(!ret, "WinHttpTimeFromSystemTime succeeded\n"); 434 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 435 436 SetLastError(0xdeadbeef); 437 ret = WinHttpTimeFromSystemTime(&time, time_string); 438 err = GetLastError(); 439 ok(ret, "WinHttpTimeFromSystemTime failed: %u\n", err); 440 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 441 ok(memcmp(time_string, expected_string, sizeof(expected_string)) == 0, 442 "Time string returned did not match expected time string.\n"); 443 } 444 445 static void test_WinHttpTimeToSystemTime(void) 446 { 447 BOOL ret; 448 SYSTEMTIME time; 449 static const SYSTEMTIME expected_time = {2008, 7, 1, 28, 10, 5, 52, 0}; 450 static const WCHAR time_string1[] = 451 {'M','o','n',',',' ','2','8',' ','J','u','l',' ','2','0','0','8',' ', 452 + '1','0',':','0','5',':','5','2',' ','G','M','T','\n',0}; 453 static const WCHAR time_string2[] = 454 {' ','m','o','n',' ','2','8',' ','j','u','l',' ','2','0','0','8',' ', 455 '1','0',' ','0','5',' ','5','2','\n',0}; 456 DWORD err; 457 458 SetLastError(0xdeadbeef); 459 ret = WinHttpTimeToSystemTime(time_string1, NULL); 460 err = GetLastError(); 461 ok(!ret, "WinHttpTimeToSystemTime succeeded\n"); 462 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 463 464 SetLastError(0xdeadbeef); 465 ret = WinHttpTimeToSystemTime(NULL, &time); 466 err = GetLastError(); 467 ok(!ret, "WinHttpTimeToSystemTime succeeded\n"); 468 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 469 470 SetLastError(0xdeadbeef); 471 ret = WinHttpTimeToSystemTime(time_string1, &time); 472 err = GetLastError(); 473 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err); 474 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 475 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0, 476 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n"); 477 478 SetLastError(0xdeadbeef); 479 ret = WinHttpTimeToSystemTime(time_string2, &time); 480 err = GetLastError(); 481 ok(ret, "WinHttpTimeToSystemTime failed: %u\n", err); 482 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 483 ok(memcmp(&time, &expected_time, sizeof(SYSTEMTIME)) == 0, 484 "Returned SYSTEMTIME structure did not match expected SYSTEMTIME structure.\n"); 485 } 486 487 static void test_WinHttpAddHeaders(void) 488 { 489 HINTERNET session, request, connection; 490 BOOL ret, reverse; 491 WCHAR buffer[MAX_PATH]; 492 WCHAR check_buffer[MAX_PATH]; 493 DWORD err, index, len, oldlen; 494 495 static const WCHAR test_file[] = {'/','p','o','s','t','t','e','s','t','.','p','h','p',0}; 496 static const WCHAR test_verb[] = {'P','O','S','T',0}; 497 static const WCHAR test_header_begin[] = 498 {'P','O','S','T',' ','/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'}; 499 static const WCHAR full_path_test_header_begin[] = 500 {'P','O','S','T',' ','h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',':','8','0', 501 '/','p','o','s','t','t','e','s','t','.','p','h','p',' ','H','T','T','P','/','1'}; 502 static const WCHAR test_header_end[] = {'\r','\n','\r','\n',0}; 503 static const WCHAR test_header_name[] = {'W','a','r','n','i','n','g',0}; 504 static const WCHAR test_header_name2[] = {'n','a','m','e',0}; 505 static const WCHAR test_header_name3[] = {'a',0}; 506 static const WCHAR test_header_range[] = {'R','a','n','g','e',0}; 507 static const WCHAR test_header_range_bytes[] = {'R','a','n','g','e',':',' ','b','y','t','e','s','=','0','-','7','7','3','\r','\n',0}; 508 static const WCHAR test_header_bytes[] = {'b','y','t','e','s','=','0','-','7','7','3',0}; 509 510 static const WCHAR test_flag_coalesce[] = {'t','e','s','t','2',',',' ','t','e','s','t','4',0}; 511 static const WCHAR test_flag_coalesce_reverse[] = {'t','e','s','t','3',',',' ','t','e','s','t','4',0}; 512 static const WCHAR test_flag_coalesce_comma[] = 513 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0}; 514 static const WCHAR test_flag_coalesce_comma_reverse[] = 515 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',0}; 516 static const WCHAR test_flag_coalesce_semicolon[] = 517 {'t','e','s','t','2',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0}; 518 static const WCHAR test_flag_coalesce_semicolon_reverse[] = 519 {'t','e','s','t','3',',',' ','t','e','s','t','4',',',' ','t','e','s','t','5',';',' ','t','e','s','t','6',0}; 520 521 static const WCHAR field[] = {'f','i','e','l','d',0}; 522 static const WCHAR value[] = {'v','a','l','u','e',' ',0}; 523 static const WCHAR value_nospace[] = {'v','a','l','u','e',0}; 524 static const WCHAR empty[] = {0}; 525 526 static const WCHAR test_headers[][14] = 527 { 528 {'W','a','r','n','i','n','g',':','t','e','s','t','1',0}, 529 {'W','a','r','n','i','n','g',':','t','e','s','t','2',0}, 530 {'W','a','r','n','i','n','g',':','t','e','s','t','3',0}, 531 {'W','a','r','n','i','n','g',':','t','e','s','t','4',0}, 532 {'W','a','r','n','i','n','g',':','t','e','s','t','5',0}, 533 {'W','a','r','n','i','n','g',':','t','e','s','t','6',0}, 534 {'W','a','r','n','i','n','g',':','t','e','s','t','7',0}, 535 {0}, 536 {':',0}, 537 {'a',':',0}, 538 {':','b',0}, 539 {'c','d',0}, 540 {' ','e',' ',':','f',0}, 541 {'f','i','e','l','d',':',' ','v','a','l','u','e',' ',0}, 542 {'n','a','m','e',':',' ','v','a','l','u','e',0}, 543 {'n','a','m','e',':',0} 544 }; 545 static const WCHAR test_indices[][6] = 546 { 547 {'t','e','s','t','1',0}, 548 {'t','e','s','t','2',0}, 549 {'t','e','s','t','3',0}, 550 {'t','e','s','t','4',0} 551 }; 552 553 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_DEFAULT_PROXY, 554 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 555 ok(session != NULL, "WinHttpOpen failed to open session.\n"); 556 557 connection = WinHttpConnect (session, test_winehq, INTERNET_DEFAULT_HTTP_PORT, 0); 558 ok(connection != NULL, "WinHttpConnect failed to open a connection, error: %u.\n", GetLastError()); 559 560 request = WinHttpOpenRequest(connection, test_verb, test_file, NULL, WINHTTP_NO_REFERER, 561 WINHTTP_DEFAULT_ACCEPT_TYPES, 0); 562 if (request == NULL && GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED) 563 { 564 skip("Network unreachable, skipping.\n"); 565 goto done; 566 } 567 ok(request != NULL, "WinHttpOpenRequest failed to open a request, error: %u.\n", GetLastError()); 568 569 index = 0; 570 len = sizeof(buffer); 571 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 572 test_header_name, buffer, &len, &index); 573 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, found 'Warning' header.\n"); 574 SetLastError(0xdeadbeef); 575 ret = WinHttpAddRequestHeaders(request, test_headers[0], -1L, WINHTTP_ADDREQ_FLAG_ADD); 576 err = GetLastError(); 577 ok(ret, "WinHttpAddRequestHeaders failed to add new header, got %d with error %u.\n", ret, err); 578 ok(err == ERROR_SUCCESS || broken(err == 0xdeadbeef) /* < win7 */, "got %u\n", err); 579 580 index = 0; 581 len = sizeof(buffer); 582 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 583 test_header_name, buffer, &len, &index); 584 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 585 ok(index == 1, "WinHttpQueryHeaders failed: header index not incremented\n"); 586 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders failed: incorrect string returned\n"); 587 ok(len == 5*sizeof(WCHAR), "WinHttpQueryHeaders failed: invalid length returned, expected 5, got %d\n", len); 588 589 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 590 test_header_name, buffer, &len, &index); 591 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded, second index should not exist.\n"); 592 593 /* Try to fetch the header info with a buffer that's big enough to fit the 594 * string but not the NULL terminator. 595 */ 596 index = 0; 597 len = 5*sizeof(WCHAR); 598 memset(check_buffer, 0xab, sizeof(check_buffer)); 599 memcpy(buffer, check_buffer, sizeof(buffer)); 600 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 601 test_header_name, buffer, &len, &index); 602 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded with a buffer that's too small.\n"); 603 ok(memcmp(buffer, check_buffer, sizeof(buffer)) == 0, 604 "WinHttpQueryHeaders failed, modified the buffer when it should not have.\n"); 605 ok(len == 6*sizeof(WCHAR), "WinHttpQueryHeaders returned invalid length, expected 12, got %d\n", len); 606 607 /* Try with a NULL buffer */ 608 index = 0; 609 len = sizeof(buffer); 610 SetLastError(0xdeadbeef); 611 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 612 test_header_name, NULL, &len, &index); 613 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 614 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "Expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 615 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 616 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n"); 617 618 /* Try with a NULL buffer and a length that's too small */ 619 index = 0; 620 len = 10; 621 SetLastError(0xdeadbeef); 622 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 623 test_header_name, NULL, &len, &index); 624 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 625 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 626 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICENT_BUFFER, got %u\n", GetLastError()); 627 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 628 ok(index == 0, "WinHttpQueryHeaders incorrectly incremented header index.\n"); 629 630 index = 0; 631 len = 0; 632 SetLastError(0xdeadbeef); 633 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 634 test_header_name, NULL, &len, &index); 635 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 636 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 637 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 638 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 639 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n"); 640 641 /* valid query */ 642 oldlen = len; 643 index = 0; 644 len = sizeof(buffer); 645 memset(buffer, 0xff, sizeof(buffer)); 646 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS_CRLF | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 647 test_header_name, buffer, &len, &index); 648 ok(ret == TRUE, "WinHttpQueryHeaders failed: got %d\n", ret); 649 ok(len + sizeof(WCHAR) <= oldlen, "WinHttpQueryHeaders resulting length longer than advertized.\n"); 650 ok((len < sizeof(buffer) - sizeof(WCHAR)) && buffer[len / sizeof(WCHAR)] == 0, "WinHttpQueryHeaders did not append NULL terminator\n"); 651 ok(len == lstrlenW(buffer) * sizeof(WCHAR), "WinHttpQueryHeaders returned incorrect length.\n"); 652 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 || 653 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0, 654 "WinHttpQueryHeaders returned invalid beginning of header string.\n"); 655 ok(memcmp(buffer + lstrlenW(buffer) - 4, test_header_end, sizeof(test_header_end)) == 0, 656 "WinHttpQueryHeaders returned invalid end of header string.\n"); 657 ok(index == 0, "WinHttpQueryHeaders incremented header index.\n"); 658 659 index = 0; 660 len = 0; 661 SetLastError(0xdeadbeef); 662 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 663 test_header_name, NULL, &len, &index); 664 ok(ret == FALSE, "WinHttpQueryHeaders unexpectedly succeeded.\n"); 665 ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, 666 "WinHttpQueryHeaders set incorrect error: expected ERROR_INSUFFICIENT_BUFFER, got %u\n", GetLastError()); 667 ok(len > 40, "WinHttpQueryHeaders returned invalid length: expected greater than 40, got %d\n", len); 668 ok(index == 0, "WinHttpQueryHeaders failed: index was incremented.\n"); 669 670 oldlen = len; 671 index = 0; 672 len = sizeof(buffer); 673 memset(buffer, 0xff, sizeof(buffer)); 674 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_RAW_HEADERS | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 675 test_header_name, buffer, &len, &index); 676 ok(ret == TRUE, "WinHttpQueryHeaders failed %u\n", GetLastError()); 677 ok(len + sizeof(WCHAR) <= oldlen, "resulting length longer than advertized\n"); 678 ok((len < sizeof(buffer) - sizeof(WCHAR)) && !buffer[len / sizeof(WCHAR)] && !buffer[len / sizeof(WCHAR) - 1], 679 "no double NULL terminator\n"); 680 ok(memcmp(buffer, test_header_begin, sizeof(test_header_begin)) == 0 || 681 memcmp(buffer, full_path_test_header_begin, sizeof(full_path_test_header_begin)) == 0, 682 "invalid beginning of header string.\n"); 683 ok(index == 0, "header index was incremented\n"); 684 685 /* tests for more indices */ 686 ret = WinHttpAddRequestHeaders(request, test_headers[1], -1L, WINHTTP_ADDREQ_FLAG_ADD); 687 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header: %d\n", ret); 688 689 index = 0; 690 len = sizeof(buffer); 691 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 692 test_header_name, buffer, &len, &index); 693 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 694 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 695 ok(memcmp(buffer, test_indices[0], sizeof(test_indices[0])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 696 697 len = sizeof(buffer); 698 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 699 test_header_name, buffer, &len, &index); 700 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 701 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 702 ok(memcmp(buffer, test_indices[1], sizeof(test_indices[1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 703 704 ret = WinHttpAddRequestHeaders(request, test_headers[2], -1L, WINHTTP_ADDREQ_FLAG_REPLACE); 705 ok(ret == TRUE, "WinHttpAddRequestHeaders failed to add duplicate header.\n"); 706 707 index = 0; 708 len = sizeof(buffer); 709 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 710 test_header_name, buffer, &len, &index); 711 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 712 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 713 reverse = (memcmp(buffer, test_indices[1], sizeof(test_indices[1])) != 0); /* Win7 returns values in reverse order of adding */ 714 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 715 716 len = sizeof(buffer); 717 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 718 test_header_name, buffer, &len, &index); 719 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 720 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 721 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 722 723 /* add if new flag */ 724 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW); 725 ok(ret == FALSE, "WinHttpAddRequestHeaders incorrectly replaced existing header.\n"); 726 727 index = 0; 728 len = sizeof(buffer); 729 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 730 test_header_name, buffer, &len, &index); 731 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 732 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 733 ok(memcmp(buffer, test_indices[reverse ? 2 : 1], sizeof(test_indices[reverse ? 2 : 1])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 734 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 == 2, "WinHttpQueryHeaders failed to increment index.\n"); 740 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 741 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 == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 746 747 /* coalesce flag */ 748 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_COALESCE); 749 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE.\n"); 750 751 index = 0; 752 len = sizeof(buffer); 753 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 754 test_header_name, buffer, &len, &index); 755 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 756 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 757 ok(memcmp(buffer, reverse ? test_flag_coalesce_reverse : test_flag_coalesce, 758 reverse ? sizeof(test_flag_coalesce_reverse) : sizeof(test_flag_coalesce)) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 759 760 len = sizeof(buffer); 761 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 762 test_header_name, buffer, &len, &index); 763 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 764 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 765 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 766 767 len = sizeof(buffer); 768 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 769 test_header_name, buffer, &len, &index); 770 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 771 772 /* coalesce with comma flag */ 773 ret = WinHttpAddRequestHeaders(request, test_headers[4], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA); 774 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_COMMA.\n"); 775 776 index = 0; 777 len = sizeof(buffer); 778 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 779 test_header_name, buffer, &len, &index); 780 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 781 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 782 ok(memcmp(buffer, reverse ? test_flag_coalesce_comma_reverse : test_flag_coalesce_comma, 783 reverse ? sizeof(test_flag_coalesce_comma_reverse) : sizeof(test_flag_coalesce_comma)) == 0, 784 "WinHttpQueryHeaders returned incorrect string.\n"); 785 786 len = sizeof(buffer); 787 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 788 test_header_name, buffer, &len, &index); 789 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 790 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 791 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 792 793 len = sizeof(buffer); 794 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 795 test_header_name, buffer, &len, &index); 796 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 797 798 799 /* coalesce with semicolon flag */ 800 ret = WinHttpAddRequestHeaders(request, test_headers[5], -1L, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON); 801 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON.\n"); 802 803 index = 0; 804 len = sizeof(buffer); 805 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 806 test_header_name, buffer, &len, &index); 807 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 808 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 809 ok(memcmp(buffer, reverse ? test_flag_coalesce_semicolon_reverse : test_flag_coalesce_semicolon, 810 reverse ? sizeof(test_flag_coalesce_semicolon_reverse) : sizeof(test_flag_coalesce_semicolon)) == 0, 811 "WinHttpQueryHeaders returned incorrect string.\n"); 812 813 len = sizeof(buffer); 814 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 815 test_header_name, buffer, &len, &index); 816 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 817 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 818 ok(memcmp(buffer, test_indices[reverse ? 1 : 2], sizeof(test_indices[reverse ? 1 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 819 820 len = sizeof(buffer); 821 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 822 test_header_name, buffer, &len, &index); 823 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 824 825 /* add and replace flags */ 826 ret = WinHttpAddRequestHeaders(request, test_headers[3], -1L, WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE); 827 ok(ret == TRUE, "WinHttpAddRequestHeaders failed with flag WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE.\n"); 828 829 index = 0; 830 len = sizeof(buffer); 831 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 832 test_header_name, buffer, &len, &index); 833 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 834 ok(index == 1, "WinHttpQueryHeaders failed to increment index.\n"); 835 ok(memcmp(buffer, test_indices[reverse ? 3 : 2], sizeof(test_indices[reverse ? 3 : 2])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 836 837 len = sizeof(buffer); 838 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 839 test_header_name, buffer, &len, &index); 840 ok(ret == TRUE, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 841 ok(index == 2, "WinHttpQueryHeaders failed to increment index.\n"); 842 ok(memcmp(buffer, test_indices[reverse ? 1 : 3], sizeof(test_indices[reverse ? 1 : 3])) == 0, "WinHttpQueryHeaders returned incorrect string.\n"); 843 844 len = sizeof(buffer); 845 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 846 test_header_name, buffer, &len, &index); 847 ok(ret == FALSE, "WinHttpQueryHeaders succeeded unexpectedly, found third header.\n"); 848 849 ret = WinHttpAddRequestHeaders(request, test_headers[8], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 850 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 851 852 ret = WinHttpAddRequestHeaders(request, test_headers[9], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 853 ok(ret, "WinHttpAddRequestHeaders failed\n"); 854 855 index = 0; 856 memset(buffer, 0xff, sizeof(buffer)); 857 len = sizeof(buffer); 858 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 859 test_header_name3, buffer, &len, &index); 860 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 861 ok(!memcmp(buffer, empty, sizeof(empty)), "unexpected result\n"); 862 863 ret = WinHttpAddRequestHeaders(request, test_headers[10], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 864 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 865 866 ret = WinHttpAddRequestHeaders(request, test_headers[11], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 867 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 868 869 ret = WinHttpAddRequestHeaders(request, test_headers[12], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 870 ok(!ret, "WinHttpAddRequestHeaders failed\n"); 871 872 ret = WinHttpAddRequestHeaders(request, test_headers[13], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 873 ok(ret, "WinHttpAddRequestHeaders failed\n"); 874 875 index = 0; 876 buffer[0] = 0; 877 len = sizeof(buffer); 878 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 879 field, buffer, &len, &index); 880 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 881 ok(!memcmp(buffer, value, sizeof(value)) || ! memcmp(buffer, value_nospace, sizeof(value_nospace)), "unexpected result\n"); 882 883 SetLastError(0xdeadbeef); 884 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, 0, 885 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE); 886 err = GetLastError(); 887 ok(!ret, "unexpected success\n"); 888 ok(err == ERROR_INVALID_PARAMETER, "got %u\n", err); 889 890 ret = WinHttpAddRequestHeaders(request, test_header_range_bytes, ~0u, 891 WINHTTP_ADDREQ_FLAG_ADD | WINHTTP_ADDREQ_FLAG_REPLACE); 892 ok(ret, "failed to add header: %u\n", GetLastError()); 893 894 index = 0; 895 len = sizeof(buffer); 896 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 897 test_header_range, buffer, &len, &index); 898 ok(ret, "failed to get range header %u\n", GetLastError()); 899 ok(!memcmp(buffer, test_header_bytes, sizeof(test_header_bytes)), "incorrect string returned\n"); 900 ok(len == lstrlenW(test_header_bytes) * sizeof(WCHAR), "wrong length %u\n", len); 901 ok(index == 1, "wrong index %u\n", index); 902 903 index = 0; 904 len = sizeof(buffer); 905 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 906 test_header_name2, buffer, &len, &index); 907 ok(!ret, "unexpected success\n"); 908 909 SetLastError(0xdeadbeef); 910 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE); 911 err = GetLastError(); 912 ok(!ret, "unexpected success\n"); 913 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err); 914 915 ret = WinHttpAddRequestHeaders(request, test_headers[14], ~0u, WINHTTP_ADDREQ_FLAG_ADD); 916 ok(ret, "got %u\n", GetLastError()); 917 918 index = 0; 919 len = sizeof(buffer); 920 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 921 test_header_name2, buffer, &len, &index); 922 ok(ret, "got %u\n", GetLastError()); 923 ok(index == 1, "wrong index %u\n", index); 924 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n"); 925 926 ret = WinHttpAddRequestHeaders(request, test_headers[15], ~0u, WINHTTP_ADDREQ_FLAG_REPLACE); 927 ok(ret, "got %u\n", GetLastError()); 928 929 index = 0; 930 len = sizeof(buffer); 931 SetLastError(0xdeadbeef); 932 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 933 test_header_name2, buffer, &len, &index); 934 err = GetLastError(); 935 ok(!ret, "unexpected success\n"); 936 ok(err == ERROR_WINHTTP_HEADER_NOT_FOUND, "got %u\n", err); 937 938 ret = WinHttpAddRequestHeaders(request, test_headers[14], -1L, 0); 939 ok(ret, "got %u\n", GetLastError()); 940 941 index = 0; 942 len = sizeof(buffer); 943 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 944 test_header_name2, buffer, &len, &index); 945 ok(ret, "got %u\n", GetLastError()); 946 ok(index == 1, "wrong index %u\n", index); 947 ok(!memcmp(buffer, value_nospace, sizeof(value_nospace)), "incorrect string\n"); 948 949 ret = WinHttpCloseHandle(request); 950 ok(ret == TRUE, "WinHttpCloseHandle failed on closing request, got %d.\n", ret); 951 done: 952 ret = WinHttpCloseHandle(connection); 953 ok(ret == TRUE, "WinHttpCloseHandle failed on closing connection, got %d.\n", ret); 954 ret = WinHttpCloseHandle(session); 955 ok(ret == TRUE, "WinHttpCloseHandle failed on closing session, got %d.\n", ret); 956 957 } 958 959 static void CALLBACK cert_error(HINTERNET handle, DWORD_PTR ctx, DWORD status, LPVOID buf, DWORD len) 960 { 961 DWORD flags = *(DWORD *)buf; 962 963 if (!flags) 964 { 965 trace("WINHTTP_CALLBACK_STATUS_FLAG_SECURITY_CHANNEL_ERROR\n"); 966 return; 967 } 968 #define X(x) if (flags & x) trace("%s\n", #x); 969 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REV_FAILED) 970 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CERT) 971 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_REVOKED) 972 X(WINHTTP_CALLBACK_STATUS_FLAG_INVALID_CA) 973 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_CN_INVALID) 974 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_DATE_INVALID) 975 X(WINHTTP_CALLBACK_STATUS_FLAG_CERT_WRONG_USAGE) 976 #undef X 977 } 978 979 static void test_secure_connection(void) 980 { 981 static const char data_start[] = "<!DOCTYPE html PUBLIC"; 982 HINTERNET ses, con, req; 983 DWORD size, status, policy, bitness, read_size, err, available_size, protocols; 984 BOOL ret; 985 CERT_CONTEXT *cert; 986 WINHTTP_CERTIFICATE_INFO info; 987 char buffer[32]; 988 989 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 990 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 991 992 policy = WINHTTP_OPTION_REDIRECT_POLICY_ALWAYS; 993 ret = WinHttpSetOption(ses, WINHTTP_OPTION_REDIRECT_POLICY, &policy, sizeof(policy)); 994 ok(ret, "failed to set redirect policy %u\n", GetLastError()); 995 996 protocols = WINHTTP_FLAG_SECURE_PROTOCOL_TLS1_2; 997 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SECURE_PROTOCOLS, &protocols, sizeof(protocols)); 998 err = GetLastError(); 999 ok(ret || err == ERROR_INVALID_PARAMETER /* < win7 */, "failed to set protocols %u\n", err); 1000 1001 con = WinHttpConnect(ses, test_winehq, 443, 0); 1002 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1003 1004 /* try without setting WINHTTP_FLAG_SECURE */ 1005 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1006 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1007 1008 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0); 1009 err = GetLastError(); 1010 ok(!ret, "unexpected success\n"); 1011 ok(err == ERROR_WINHTTP_INCORRECT_HANDLE_STATE || broken(err == ERROR_INVALID_PARAMETER) /* winxp */, 1012 "setting client cert context returned %u\n", err); 1013 1014 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1015 err = GetLastError(); 1016 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 1017 { 1018 skip("Connection failed, skipping.\n"); 1019 goto cleanup; 1020 } 1021 ok(ret, "failed to send request %u\n", GetLastError()); 1022 1023 ret = WinHttpReceiveResponse(req, NULL); 1024 ok(ret, "failed to receive response %u\n", GetLastError()); 1025 1026 status = 0xdeadbeef; 1027 size = sizeof(status); 1028 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1029 ok(ret, "header query failed %u\n", GetLastError()); 1030 ok(status == HTTP_STATUS_BAD_REQUEST, "got %u\n", status); 1031 1032 WinHttpCloseHandle(req); 1033 1034 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, WINHTTP_FLAG_SECURE); 1035 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1036 1037 ret = WinHttpSetOption(req, WINHTTP_OPTION_CLIENT_CERT_CONTEXT, WINHTTP_NO_CLIENT_CERT_CONTEXT, 0); 1038 err = GetLastError(); 1039 ok(ret || broken(!ret && err == ERROR_INVALID_PARAMETER) /* winxp */, "failed to set client cert context %u\n", err); 1040 1041 WinHttpSetStatusCallback(req, cert_error, WINHTTP_CALLBACK_STATUS_SECURE_FAILURE, 0); 1042 1043 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1044 err = GetLastError(); 1045 if (!ret && (err == ERROR_WINHTTP_SECURE_FAILURE || err == ERROR_WINHTTP_CANNOT_CONNECT || 1046 err == ERROR_WINHTTP_TIMEOUT)) 1047 { 1048 skip("secure connection failed, skipping remaining secure tests\n"); 1049 goto cleanup; 1050 } 1051 ok(ret, "failed to send request %u\n", GetLastError()); 1052 1053 size = sizeof(cert); 1054 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SERVER_CERT_CONTEXT, &cert, &size ); 1055 ok(ret, "failed to retrieve certificate context %u\n", GetLastError()); 1056 if (ret) CertFreeCertificateContext(cert); 1057 1058 size = sizeof(bitness); 1059 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_KEY_BITNESS, &bitness, &size ); 1060 ok(ret, "failed to retrieve key bitness %u\n", GetLastError()); 1061 1062 size = sizeof(info); 1063 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SECURITY_CERTIFICATE_STRUCT, &info, &size ); 1064 ok(ret, "failed to retrieve certificate info %u\n", GetLastError()); 1065 1066 if (ret) 1067 { 1068 trace("lpszSubjectInfo %s\n", wine_dbgstr_w(info.lpszSubjectInfo)); 1069 trace("lpszIssuerInfo %s\n", wine_dbgstr_w(info.lpszIssuerInfo)); 1070 trace("lpszProtocolName %s\n", wine_dbgstr_w(info.lpszProtocolName)); 1071 trace("lpszSignatureAlgName %s\n", wine_dbgstr_w(info.lpszSignatureAlgName)); 1072 trace("lpszEncryptionAlgName %s\n", wine_dbgstr_w(info.lpszEncryptionAlgName)); 1073 trace("dwKeySize %u\n", info.dwKeySize); 1074 LocalFree( info.lpszSubjectInfo ); 1075 LocalFree( info.lpszIssuerInfo ); 1076 } 1077 1078 ret = WinHttpReceiveResponse(req, NULL); 1079 ok(ret, "failed to receive response %u\n", GetLastError()); 1080 1081 available_size = 0; 1082 ret = WinHttpQueryDataAvailable(req, &available_size); 1083 ok(ret, "failed to query available data %u\n", GetLastError()); 1084 ok(available_size > 2014, "available_size = %u\n", available_size); 1085 1086 status = 0xdeadbeef; 1087 size = sizeof(status); 1088 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1089 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1090 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 1091 1092 size = 0; 1093 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, NULL, &size, NULL); 1094 ok(!ret, "succeeded unexpectedly\n"); 1095 1096 read_size = 0; 1097 for (;;) 1098 { 1099 size = 0; 1100 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 1101 ok(ret == TRUE, "WinHttpReadData failed: %u.\n", GetLastError()); 1102 if (!size) break; 1103 read_size += size; 1104 1105 if (read_size <= 32) 1106 ok(!memcmp(buffer, data_start, sizeof(data_start)-1), "not expected: %.32s\n", buffer); 1107 } 1108 ok(read_size >= available_size, "read_size = %u, available_size = %u\n", read_size, available_size); 1109 1110 cleanup: 1111 WinHttpCloseHandle(req); 1112 WinHttpCloseHandle(con); 1113 WinHttpCloseHandle(ses); 1114 } 1115 1116 static void test_request_parameter_defaults(void) 1117 { 1118 static const WCHAR empty[] = {0}; 1119 HINTERNET ses, con, req; 1120 DWORD size, status, error; 1121 WCHAR *version; 1122 BOOL ret; 1123 1124 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1125 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1126 1127 con = WinHttpConnect(ses, test_winehq, 0, 0); 1128 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1129 1130 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1131 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1132 1133 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1134 error = GetLastError(); 1135 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT)) 1136 { 1137 skip("connection failed, skipping\n"); 1138 goto done; 1139 } 1140 ok(ret, "failed to send request %u\n", GetLastError()); 1141 1142 ret = WinHttpReceiveResponse(req, NULL); 1143 if (!ret && GetLastError() == ERROR_WINHTTP_INVALID_SERVER_RESPONSE) /* win2k */ 1144 { 1145 win_skip("invalid response\n"); 1146 goto done; 1147 } 1148 ok(ret, "failed to receive response %u\n", GetLastError()); 1149 1150 status = 0xdeadbeef; 1151 size = sizeof(status); 1152 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1153 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1154 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 1155 1156 WinHttpCloseHandle(req); 1157 1158 req = WinHttpOpenRequest(con, empty, empty, empty, NULL, NULL, 0); 1159 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1160 1161 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1162 error = GetLastError(); 1163 if (!ret && (error == ERROR_WINHTTP_CANNOT_CONNECT || error == ERROR_WINHTTP_TIMEOUT)) 1164 { 1165 skip("connection failed, skipping\n"); 1166 goto done; 1167 } 1168 ok(ret, "failed to send request %u\n", GetLastError()); 1169 1170 ret = WinHttpReceiveResponse(req, NULL); 1171 ok(ret, "failed to receive response %u\n", GetLastError()); 1172 1173 size = 0; 1174 SetLastError(0xdeadbeef); 1175 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, NULL, &size, NULL); 1176 error = GetLastError(); 1177 ok(!ret, "succeeded unexpectedly\n"); 1178 ok(error == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %u\n", error); 1179 1180 version = HeapAlloc(GetProcessHeap(), 0, size); 1181 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_VERSION, NULL, version, &size, NULL); 1182 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1183 ok(lstrlenW(version) == size / sizeof(WCHAR), "unexpected size %u\n", size); 1184 HeapFree(GetProcessHeap(), 0, version); 1185 1186 status = 0xdeadbeef; 1187 size = sizeof(status); 1188 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 1189 ok(ret, "failed unexpectedly %u\n", GetLastError()); 1190 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 1191 1192 done: 1193 WinHttpCloseHandle(req); 1194 WinHttpCloseHandle(con); 1195 WinHttpCloseHandle(ses); 1196 } 1197 1198 static const WCHAR Connections[] = { 1199 'S','o','f','t','w','a','r','e','\\', 1200 'M','i','c','r','o','s','o','f','t','\\', 1201 'W','i','n','d','o','w','s','\\', 1202 'C','u','r','r','e','n','t','V','e','r','s','i','o','n','\\', 1203 'I','n','t','e','r','n','e','t',' ','S','e','t','t','i','n','g','s','\\', 1204 'C','o','n','n','e','c','t','i','o','n','s',0 }; 1205 static const WCHAR WinHttpSettings[] = { 1206 'W','i','n','H','t','t','p','S','e','t','t','i','n','g','s',0 }; 1207 1208 static DWORD get_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD *type ) 1209 { 1210 LONG l; 1211 HKEY key; 1212 DWORD ret = 0; 1213 1214 l = RegOpenKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, KEY_READ, &key ); 1215 if (!l) 1216 { 1217 DWORD size = 0; 1218 1219 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, NULL, &size ); 1220 if (!l) 1221 { 1222 if (size <= len) 1223 l = RegQueryValueExW( key, WinHttpSettings, NULL, type, buf, 1224 &size ); 1225 if (!l) 1226 ret = size; 1227 } 1228 RegCloseKey( key ); 1229 } 1230 return ret; 1231 } 1232 1233 static void set_proxy( REGSAM access, BYTE *buf, DWORD len, DWORD type ) 1234 { 1235 HKEY hkey; 1236 if (!RegCreateKeyExW( HKEY_LOCAL_MACHINE, Connections, 0, NULL, 0, access, NULL, &hkey, NULL )) 1237 { 1238 if (len) RegSetValueExW( hkey, WinHttpSettings, 0, type, buf, len ); 1239 else RegDeleteValueW( hkey, WinHttpSettings ); 1240 RegCloseKey( hkey ); 1241 } 1242 } 1243 1244 static void set_default_proxy_reg_value( BYTE *buf, DWORD len, DWORD type ) 1245 { 1246 BOOL wow64; 1247 IsWow64Process( GetCurrentProcess(), &wow64 ); 1248 if (sizeof(void *) > sizeof(int) || wow64) 1249 { 1250 set_proxy( KEY_WRITE|KEY_WOW64_64KEY, buf, len, type ); 1251 set_proxy( KEY_WRITE|KEY_WOW64_32KEY, buf, len, type ); 1252 } 1253 else 1254 set_proxy( KEY_WRITE, buf, len, type ); 1255 } 1256 1257 static void test_set_default_proxy_config(void) 1258 { 1259 static WCHAR wideString[] = { 0x226f, 0x575b, 0 }; 1260 static WCHAR normalString[] = { 'f','o','o',0 }; 1261 DWORD type, len; 1262 BYTE *saved_proxy_settings = NULL; 1263 WINHTTP_PROXY_INFO info; 1264 BOOL ret; 1265 1266 /* FIXME: it would be simpler to read the current settings using 1267 * WinHttpGetDefaultProxyConfiguration and save them using 1268 * WinHttpSetDefaultProxyConfiguration, but they appear to have a bug. 1269 * 1270 * If a proxy is configured in the registry, e.g. via 'proxcfg -p "foo"', 1271 * the access type reported by WinHttpGetDefaultProxyConfiguration is 1, 1272 * WINHTTP_ACCESS_TYPE_NO_PROXY, whereas it should be 1273 * WINHTTP_ACCESS_TYPE_NAMED_PROXY. 1274 * If WinHttpSetDefaultProxyConfiguration is called with dwAccessType = 1, 1275 * the lpszProxy and lpszProxyBypass values are ignored. 1276 * Thus, if a proxy is set with proxycfg, then calling 1277 * WinHttpGetDefaultProxyConfiguration followed by 1278 * WinHttpSetDefaultProxyConfiguration results in the proxy settings 1279 * getting deleted from the registry. 1280 * 1281 * Instead I read the current registry value and restore it directly. 1282 */ 1283 len = get_default_proxy_reg_value( NULL, 0, &type ); 1284 if (len) 1285 { 1286 saved_proxy_settings = HeapAlloc( GetProcessHeap(), 0, len ); 1287 len = get_default_proxy_reg_value( saved_proxy_settings, len, &type ); 1288 } 1289 1290 if (0) 1291 { 1292 /* Crashes on Vista and higher */ 1293 SetLastError(0xdeadbeef); 1294 ret = WinHttpSetDefaultProxyConfiguration(NULL); 1295 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1296 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1297 } 1298 1299 /* test with invalid access type */ 1300 info.dwAccessType = 0xdeadbeef; 1301 info.lpszProxy = info.lpszProxyBypass = NULL; 1302 SetLastError(0xdeadbeef); 1303 ret = WinHttpSetDefaultProxyConfiguration(&info); 1304 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1305 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1306 1307 /* at a minimum, the proxy server must be set */ 1308 info.dwAccessType = WINHTTP_ACCESS_TYPE_NAMED_PROXY; 1309 info.lpszProxy = info.lpszProxyBypass = NULL; 1310 SetLastError(0xdeadbeef); 1311 ret = WinHttpSetDefaultProxyConfiguration(&info); 1312 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1313 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1314 info.lpszProxyBypass = normalString; 1315 SetLastError(0xdeadbeef); 1316 ret = WinHttpSetDefaultProxyConfiguration(&info); 1317 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1318 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1319 1320 /* the proxy server can't have wide characters */ 1321 info.lpszProxy = wideString; 1322 SetLastError(0xdeadbeef); 1323 ret = WinHttpSetDefaultProxyConfiguration(&info); 1324 if (!ret && GetLastError() == ERROR_ACCESS_DENIED) 1325 skip("couldn't set default proxy configuration: access denied\n"); 1326 else 1327 ok((!ret && GetLastError() == ERROR_INVALID_PARAMETER) || 1328 broken(ret), /* Earlier winhttp versions on W2K/XP */ 1329 "expected ERROR_INVALID_PARAMETER, got %d\n", GetLastError()); 1330 1331 info.lpszProxy = normalString; 1332 SetLastError(0xdeadbeef); 1333 ret = WinHttpSetDefaultProxyConfiguration(&info); 1334 if (!ret && GetLastError() == ERROR_ACCESS_DENIED) 1335 skip("couldn't set default proxy configuration: access denied\n"); 1336 else 1337 { 1338 ok(ret, "WinHttpSetDefaultProxyConfiguration failed: %u\n", GetLastError()); 1339 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 1340 "got %u\n", GetLastError()); 1341 } 1342 set_default_proxy_reg_value( saved_proxy_settings, len, type ); 1343 } 1344 1345 static void test_Timeouts (void) 1346 { 1347 BOOL ret; 1348 DWORD value, size; 1349 HINTERNET ses, req, con; 1350 1351 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1352 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1353 1354 SetLastError(0xdeadbeef); 1355 ret = WinHttpSetTimeouts(ses, -2, 0, 0, 0); 1356 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1357 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1358 1359 SetLastError(0xdeadbeef); 1360 ret = WinHttpSetTimeouts(ses, 0, -2, 0, 0); 1361 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1362 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1363 1364 SetLastError(0xdeadbeef); 1365 ret = WinHttpSetTimeouts(ses, 0, 0, -2, 0); 1366 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1367 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1368 1369 SetLastError(0xdeadbeef); 1370 ret = WinHttpSetTimeouts(ses, 0, 0, 0, -2); 1371 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1372 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1373 1374 SetLastError(0xdeadbeef); 1375 ret = WinHttpSetTimeouts(ses, -1, -1, -1, -1); 1376 ok(ret, "%u\n", GetLastError()); 1377 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 1378 "expected ERROR_SUCCESS, got %u\n", GetLastError()); 1379 1380 SetLastError(0xdeadbeef); 1381 ret = WinHttpSetTimeouts(ses, 0, 0, 0, 0); 1382 ok(ret, "%u\n", GetLastError()); 1383 1384 SetLastError(0xdeadbeef); 1385 ret = WinHttpSetTimeouts(ses, 0x0123, 0x4567, 0x89ab, 0xcdef); 1386 ok(ret, "%u\n", GetLastError()); 1387 1388 SetLastError(0xdeadbeef); 1389 value = 0xdeadbeef; 1390 size = sizeof(DWORD); 1391 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1392 ok(ret, "%u\n", GetLastError()); 1393 ok(value == 0x0123, "Expected 0x0123, got %u\n", value); 1394 1395 SetLastError(0xdeadbeef); 1396 value = 0xdeadbeef; 1397 size = sizeof(DWORD); 1398 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1399 ok(ret, "%u\n", GetLastError()); 1400 ok(value == 0x4567, "Expected 0x4567, got %u\n", value); 1401 1402 SetLastError(0xdeadbeef); 1403 value = 0xdeadbeef; 1404 size = sizeof(DWORD); 1405 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1406 ok(ret, "%u\n", GetLastError()); 1407 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value); 1408 1409 SetLastError(0xdeadbeef); 1410 value = 0xdeadbeef; 1411 size = sizeof(DWORD); 1412 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1413 ok(ret, "%u\n", GetLastError()); 1414 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value); 1415 1416 SetLastError(0xdeadbeef); 1417 value = 0; 1418 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1419 ok(ret, "%u\n", GetLastError()); 1420 1421 SetLastError(0xdeadbeef); 1422 value = 0xdeadbeef; 1423 size = sizeof(DWORD); 1424 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1425 ok(ret, "%u\n", GetLastError()); 1426 ok(value == 0, "Expected 0, got %u\n", value); 1427 1428 SetLastError(0xdeadbeef); 1429 value = 0; 1430 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1431 ok(ret, "%u\n", GetLastError()); 1432 1433 SetLastError(0xdeadbeef); 1434 value = 0xdeadbeef; 1435 size = sizeof(DWORD); 1436 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1437 ok(ret, "%u\n", GetLastError()); 1438 ok(value == 0, "Expected 0, got %u\n", value); 1439 1440 SetLastError(0xdeadbeef); 1441 value = 0; 1442 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1443 ok(ret, "%u\n", GetLastError()); 1444 1445 SetLastError(0xdeadbeef); 1446 value = 0xdeadbeef; 1447 size = sizeof(DWORD); 1448 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1449 ok(ret, "%u\n", GetLastError()); 1450 ok(value == 0, "Expected 0, got %u\n", value); 1451 1452 SetLastError(0xdeadbeef); 1453 value = 0; 1454 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1455 ok(ret, "%u\n", GetLastError()); 1456 1457 SetLastError(0xdeadbeef); 1458 value = 0xdeadbeef; 1459 size = sizeof(DWORD); 1460 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1461 ok(ret, "%u\n", GetLastError()); 1462 ok(value == 0, "Expected 0, got %u\n", value); 1463 1464 SetLastError(0xdeadbeef); 1465 value = 0xbeefdead; 1466 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1467 ok(ret, "%u\n", GetLastError()); 1468 1469 SetLastError(0xdeadbeef); 1470 value = 0xdeadbeef; 1471 size = sizeof(DWORD); 1472 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1473 ok(ret, "%u\n", GetLastError()); 1474 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1475 1476 SetLastError(0xdeadbeef); 1477 value = 0xbeefdead; 1478 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1479 ok(ret, "%u\n", GetLastError()); 1480 1481 SetLastError(0xdeadbeef); 1482 value = 0xdeadbeef; 1483 size = sizeof(DWORD); 1484 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1485 ok(ret, "%u\n", GetLastError()); 1486 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1487 1488 SetLastError(0xdeadbeef); 1489 value = 0xbeefdead; 1490 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1491 ok(ret, "%u\n", GetLastError()); 1492 1493 SetLastError(0xdeadbeef); 1494 value = 0xdeadbeef; 1495 size = sizeof(DWORD); 1496 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1497 ok(ret, "%u\n", GetLastError()); 1498 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1499 1500 SetLastError(0xdeadbeef); 1501 value = 0xbeefdead; 1502 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1503 ok(ret, "%u\n", GetLastError()); 1504 1505 SetLastError(0xdeadbeef); 1506 value = 0xdeadbeef; 1507 size = sizeof(DWORD); 1508 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1509 ok(ret, "%u\n", GetLastError()); 1510 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1511 1512 con = WinHttpConnect(ses, test_winehq, 0, 0); 1513 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1514 1515 /* Timeout values should match the last one set for session */ 1516 SetLastError(0xdeadbeef); 1517 value = 0xdeadbeef; 1518 size = sizeof(DWORD); 1519 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1520 ok(ret, "%u\n", GetLastError()); 1521 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1522 1523 SetLastError(0xdeadbeef); 1524 value = 0xdeadbeef; 1525 size = sizeof(DWORD); 1526 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1527 ok(ret, "%u\n", GetLastError()); 1528 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1529 1530 SetLastError(0xdeadbeef); 1531 value = 0xdeadbeef; 1532 size = sizeof(DWORD); 1533 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1534 ok(ret, "%u\n", GetLastError()); 1535 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1536 1537 SetLastError(0xdeadbeef); 1538 value = 0xdeadbeef; 1539 size = sizeof(DWORD); 1540 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1541 ok(ret, "%u\n", GetLastError()); 1542 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1543 1544 SetLastError(0xdeadbeef); 1545 ret = WinHttpSetTimeouts(con, -2, 0, 0, 0); 1546 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1547 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1548 1549 SetLastError(0xdeadbeef); 1550 ret = WinHttpSetTimeouts(con, 0, -2, 0, 0); 1551 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1552 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1553 1554 SetLastError(0xdeadbeef); 1555 ret = WinHttpSetTimeouts(con, 0, 0, -2, 0); 1556 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1557 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1558 1559 SetLastError(0xdeadbeef); 1560 ret = WinHttpSetTimeouts(con, 0, 0, 0, -2); 1561 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1562 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1563 1564 SetLastError(0xdeadbeef); 1565 ret = WinHttpSetTimeouts(con, -1, -1, -1, -1); 1566 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1567 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1568 1569 SetLastError(0xdeadbeef); 1570 ret = WinHttpSetTimeouts(con, 0, 0, 0, 0); 1571 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1572 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1573 1574 SetLastError(0xdeadbeef); 1575 value = 0; 1576 ret = WinHttpSetOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1577 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1578 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1579 1580 SetLastError(0xdeadbeef); 1581 value = 0; 1582 ret = WinHttpSetOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1583 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1584 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1585 1586 SetLastError(0xdeadbeef); 1587 value = 0; 1588 ret = WinHttpSetOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1589 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1590 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1591 1592 SetLastError(0xdeadbeef); 1593 value = 0; 1594 ret = WinHttpSetOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1595 ok(!ret && GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_TYPE, 1596 "expected ERROR_WINHTTP_INVALID_TYPE, got %u\n", GetLastError()); 1597 1598 /* Changing timeout values for session should affect the values for connection */ 1599 SetLastError(0xdeadbeef); 1600 value = 0xdead; 1601 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1602 ok(ret, "%u\n", GetLastError()); 1603 1604 SetLastError(0xdeadbeef); 1605 value = 0xdeadbeef; 1606 size = sizeof(DWORD); 1607 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1608 ok(ret, "%u\n", GetLastError()); 1609 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1610 1611 SetLastError(0xdeadbeef); 1612 value = 0xdead; 1613 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1614 ok(ret, "%u\n", GetLastError()); 1615 1616 SetLastError(0xdeadbeef); 1617 value = 0xdeadbeef; 1618 size = sizeof(DWORD); 1619 ret = WinHttpQueryOption(con, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1620 ok(ret, "%u\n", GetLastError()); 1621 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1622 1623 SetLastError(0xdeadbeef); 1624 value = 0xdead; 1625 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1626 ok(ret, "%u\n", GetLastError()); 1627 1628 SetLastError(0xdeadbeef); 1629 value = 0xdeadbeef; 1630 size = sizeof(DWORD); 1631 ret = WinHttpQueryOption(con, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1632 ok(ret, "%u\n", GetLastError()); 1633 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1634 1635 SetLastError(0xdeadbeef); 1636 value = 0xdead; 1637 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1638 ok(ret, "%u\n", GetLastError()); 1639 1640 SetLastError(0xdeadbeef); 1641 value = 0xdeadbeef; 1642 size = sizeof(DWORD); 1643 ret = WinHttpQueryOption(con, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1644 ok(ret, "%u\n", GetLastError()); 1645 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1646 1647 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1648 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1649 1650 /* Timeout values should match the last one set for session */ 1651 SetLastError(0xdeadbeef); 1652 value = 0xdeadbeef; 1653 size = sizeof(DWORD); 1654 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1655 ok(ret, "%u\n", GetLastError()); 1656 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1657 1658 SetLastError(0xdeadbeef); 1659 value = 0xdeadbeef; 1660 size = sizeof(DWORD); 1661 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1662 ok(ret, "%u\n", GetLastError()); 1663 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1664 1665 SetLastError(0xdeadbeef); 1666 value = 0xdeadbeef; 1667 size = sizeof(DWORD); 1668 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1669 ok(ret, "%u\n", GetLastError()); 1670 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1671 1672 SetLastError(0xdeadbeef); 1673 value = 0xdeadbeef; 1674 size = sizeof(DWORD); 1675 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1676 ok(ret, "%u\n", GetLastError()); 1677 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1678 1679 SetLastError(0xdeadbeef); 1680 ret = WinHttpSetTimeouts(req, -2, 0, 0, 0); 1681 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1682 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1683 1684 SetLastError(0xdeadbeef); 1685 ret = WinHttpSetTimeouts(req, 0, -2, 0, 0); 1686 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1687 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1688 1689 SetLastError(0xdeadbeef); 1690 ret = WinHttpSetTimeouts(req, 0, 0, -2, 0); 1691 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1692 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1693 1694 SetLastError(0xdeadbeef); 1695 ret = WinHttpSetTimeouts(req, 0, 0, 0, -2); 1696 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, 1697 "expected ERROR_INVALID_PARAMETER, got %u\n", GetLastError()); 1698 1699 SetLastError(0xdeadbeef); 1700 ret = WinHttpSetTimeouts(req, -1, -1, -1, -1); 1701 ok(ret, "%u\n", GetLastError()); 1702 1703 SetLastError(0xdeadbeef); 1704 ret = WinHttpSetTimeouts(req, 0, 0, 0, 0); 1705 ok(ret, "%u\n", GetLastError()); 1706 1707 SetLastError(0xdeadbeef); 1708 ret = WinHttpSetTimeouts(req, 0xcdef, 0x89ab, 0x4567, 0x0123); 1709 ok(ret, "%u\n", GetLastError()); 1710 1711 SetLastError(0xdeadbeef); 1712 value = 0xdeadbeef; 1713 size = sizeof(DWORD); 1714 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1715 ok(ret, "%u\n", GetLastError()); 1716 ok(value == 0xcdef, "Expected 0xcdef, got %u\n", value); 1717 1718 SetLastError(0xdeadbeef); 1719 value = 0xdeadbeef; 1720 size = sizeof(DWORD); 1721 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1722 ok(ret, "%u\n", GetLastError()); 1723 ok(value == 0x89ab, "Expected 0x89ab, got %u\n", value); 1724 1725 SetLastError(0xdeadbeef); 1726 value = 0xdeadbeef; 1727 size = sizeof(DWORD); 1728 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1729 ok(ret, "%u\n", GetLastError()); 1730 ok(value == 0x4567, "Expected 0x4567, got %u\n", value); 1731 1732 SetLastError(0xdeadbeef); 1733 value = 0xdeadbeef; 1734 size = sizeof(DWORD); 1735 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1736 ok(ret, "%u\n", GetLastError()); 1737 ok(value == 0x0123, "Expected 0x0123, got %u\n", value); 1738 1739 SetLastError(0xdeadbeef); 1740 value = 0; 1741 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1742 ok(ret, "%u\n", GetLastError()); 1743 1744 SetLastError(0xdeadbeef); 1745 value = 0xdeadbeef; 1746 size = sizeof(DWORD); 1747 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1748 ok(ret, "%u\n", GetLastError()); 1749 ok(value == 0, "Expected 0, got %u\n", value); 1750 1751 SetLastError(0xdeadbeef); 1752 value = 0; 1753 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1754 ok(ret, "%u\n", GetLastError()); 1755 1756 SetLastError(0xdeadbeef); 1757 value = 0xdeadbeef; 1758 size = sizeof(DWORD); 1759 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1760 ok(ret, "%u\n", GetLastError()); 1761 ok(value == 0, "Expected 0, got %u\n", value); 1762 1763 SetLastError(0xdeadbeef); 1764 value = 0; 1765 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1766 ok(ret, "%u\n", GetLastError()); 1767 1768 SetLastError(0xdeadbeef); 1769 value = 0xdeadbeef; 1770 size = sizeof(DWORD); 1771 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1772 ok(ret, "%u\n", GetLastError()); 1773 ok(value == 0, "Expected 0, got %u\n", value); 1774 1775 SetLastError(0xdeadbeef); 1776 value = 0; 1777 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1778 ok(ret, "%u\n", GetLastError()); 1779 1780 SetLastError(0xdeadbeef); 1781 value = 0xdeadbeef; 1782 size = sizeof(DWORD); 1783 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1784 ok(ret, "%u\n", GetLastError()); 1785 ok(value == 0, "Expected 0, got %u\n", value); 1786 1787 SetLastError(0xdeadbeef); 1788 value = 0xbeefdead; 1789 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1790 ok(ret, "%u\n", GetLastError()); 1791 1792 SetLastError(0xdeadbeef); 1793 value = 0xdeadbeef; 1794 size = sizeof(DWORD); 1795 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1796 ok(ret, "%u\n", GetLastError()); 1797 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1798 1799 SetLastError(0xdeadbeef); 1800 value = 0xbeefdead; 1801 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1802 ok(ret, "%u\n", GetLastError()); 1803 1804 SetLastError(0xdeadbeef); 1805 value = 0xdeadbeef; 1806 size = sizeof(DWORD); 1807 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1808 ok(ret, "%u\n", GetLastError()); 1809 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1810 1811 SetLastError(0xdeadbeef); 1812 value = 0xbeefdead; 1813 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1814 ok(ret, "%u\n", GetLastError()); 1815 1816 SetLastError(0xdeadbeef); 1817 value = 0xdeadbeef; 1818 size = sizeof(DWORD); 1819 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1820 ok(ret, "%u\n", GetLastError()); 1821 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1822 1823 SetLastError(0xdeadbeef); 1824 value = 0xbeefdead; 1825 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1826 ok(ret, "%u\n", GetLastError()); 1827 1828 SetLastError(0xdeadbeef); 1829 value = 0xdeadbeef; 1830 size = sizeof(DWORD); 1831 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1832 ok(ret, "%u\n", GetLastError()); 1833 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1834 1835 /* Changing timeout values for session should not affect the values for a request, 1836 * neither should the other way around. 1837 */ 1838 SetLastError(0xdeadbeef); 1839 value = 0xbeefdead; 1840 ret = WinHttpSetOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1841 ok(ret, "%u\n", GetLastError()); 1842 1843 SetLastError(0xdeadbeef); 1844 value = 0xdeadbeef; 1845 size = sizeof(DWORD); 1846 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1847 ok(ret, "%u\n", GetLastError()); 1848 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1849 1850 SetLastError(0xdeadbeef); 1851 value = 0xbeefdead; 1852 ret = WinHttpSetOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1853 ok(ret, "%u\n", GetLastError()); 1854 1855 SetLastError(0xdeadbeef); 1856 value = 0xdeadbeef; 1857 size = sizeof(DWORD); 1858 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1859 ok(ret, "%u\n", GetLastError()); 1860 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1861 1862 SetLastError(0xdeadbeef); 1863 value = 0xbeefdead; 1864 ret = WinHttpSetOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1865 ok(ret, "%u\n", GetLastError()); 1866 1867 SetLastError(0xdeadbeef); 1868 value = 0xdeadbeef; 1869 size = sizeof(DWORD); 1870 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1871 ok(ret, "%u\n", GetLastError()); 1872 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1873 1874 SetLastError(0xdeadbeef); 1875 value = 0xbeefdead; 1876 ret = WinHttpSetOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1877 ok(ret, "%u\n", GetLastError()); 1878 1879 SetLastError(0xdeadbeef); 1880 value = 0xdeadbeef; 1881 size = sizeof(DWORD); 1882 ret = WinHttpQueryOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1883 ok(ret, "%u\n", GetLastError()); 1884 ok(value == 0xdead, "Expected 0xdead, got %u\n", value); 1885 1886 SetLastError(0xdeadbeef); 1887 value = 0xbeef; 1888 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, sizeof(value)); 1889 ok(ret, "%u\n", GetLastError()); 1890 1891 SetLastError(0xdeadbeef); 1892 value = 0xdeadbeef; 1893 size = sizeof(DWORD); 1894 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RESOLVE_TIMEOUT, &value, &size); 1895 ok(ret, "%u\n", GetLastError()); 1896 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1897 1898 SetLastError(0xdeadbeef); 1899 value = 0xbeef; 1900 ret = WinHttpSetOption(ses, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, sizeof(value)); 1901 ok(ret, "%u\n", GetLastError()); 1902 1903 SetLastError(0xdeadbeef); 1904 value = 0xdeadbeef; 1905 size = sizeof(DWORD); 1906 ret = WinHttpQueryOption(req, WINHTTP_OPTION_CONNECT_TIMEOUT, &value, &size); 1907 ok(ret, "%u\n", GetLastError()); 1908 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1909 1910 SetLastError(0xdeadbeef); 1911 value = 0xbeef; 1912 ret = WinHttpSetOption(ses, WINHTTP_OPTION_SEND_TIMEOUT, &value, sizeof(value)); 1913 ok(ret, "%u\n", GetLastError()); 1914 1915 SetLastError(0xdeadbeef); 1916 value = 0xdeadbeef; 1917 size = sizeof(DWORD); 1918 ret = WinHttpQueryOption(req, WINHTTP_OPTION_SEND_TIMEOUT, &value, &size); 1919 ok(ret, "%u\n", GetLastError()); 1920 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1921 1922 SetLastError(0xdeadbeef); 1923 value = 0xbeef; 1924 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, sizeof(value)); 1925 ok(ret, "%u\n", GetLastError()); 1926 1927 SetLastError(0xdeadbeef); 1928 value = 0xdeadbeef; 1929 size = sizeof(DWORD); 1930 ret = WinHttpQueryOption(req, WINHTTP_OPTION_RECEIVE_TIMEOUT, &value, &size); 1931 ok(ret, "%u\n", GetLastError()); 1932 ok(value == 0xbeefdead, "Expected 0xbeefdead, got %u\n", value); 1933 1934 WinHttpCloseHandle(req); 1935 WinHttpCloseHandle(con); 1936 WinHttpCloseHandle(ses); 1937 } 1938 1939 static void test_resolve_timeout(void) 1940 { 1941 static const WCHAR nxdomain[] = 1942 {'n','x','d','o','m','a','i','n','.','w','i','n','e','h','q','.','o','r','g',0}; 1943 HINTERNET ses, con, req; 1944 DWORD timeout; 1945 BOOL ret; 1946 1947 if (! proxy_active()) 1948 { 1949 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1950 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1951 1952 timeout = 10000; 1953 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout)); 1954 ok(ret, "failed to set resolve timeout %u\n", GetLastError()); 1955 1956 con = WinHttpConnect(ses, nxdomain, 0, 0); 1957 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1958 1959 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1960 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1961 1962 SetLastError(0xdeadbeef); 1963 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1964 if (ret) 1965 { 1966 skip("nxdomain returned success. Broken ISP redirects?\n"); 1967 goto done; 1968 } 1969 ok(GetLastError() == ERROR_WINHTTP_NAME_NOT_RESOLVED, 1970 "expected ERROR_WINHTTP_NAME_NOT_RESOLVED got %u\n", GetLastError()); 1971 1972 WinHttpCloseHandle(req); 1973 WinHttpCloseHandle(con); 1974 WinHttpCloseHandle(ses); 1975 } 1976 else 1977 skip("Skipping host resolution tests, host resolution preformed by proxy\n"); 1978 1979 ses = WinHttpOpen(test_useragent, 0, NULL, NULL, 0); 1980 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 1981 1982 timeout = 10000; 1983 ret = WinHttpSetOption(ses, WINHTTP_OPTION_RESOLVE_TIMEOUT, &timeout, sizeof(timeout)); 1984 ok(ret, "failed to set resolve timeout %u\n", GetLastError()); 1985 1986 con = WinHttpConnect(ses, test_winehq, 0, 0); 1987 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 1988 1989 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 1990 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 1991 1992 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 1993 if (!ret && GetLastError() == ERROR_WINHTTP_CANNOT_CONNECT) 1994 { 1995 skip("connection failed, skipping\n"); 1996 goto done; 1997 } 1998 ok(ret, "failed to send request\n"); 1999 2000 done: 2001 WinHttpCloseHandle(req); 2002 WinHttpCloseHandle(con); 2003 WinHttpCloseHandle(ses); 2004 } 2005 2006 static const char page1[] = 2007 "<HTML>\r\n" 2008 "<HEAD><TITLE>winhttp test page</TITLE></HEAD>\r\n" 2009 "<BODY>The quick brown fox jumped over the lazy dog<P></BODY>\r\n" 2010 "</HTML>\r\n\r\n"; 2011 2012 static const char okmsg[] = 2013 "HTTP/1.1 200 OK\r\n" 2014 "Server: winetest\r\n" 2015 "\r\n"; 2016 2017 static const char notokmsg[] = 2018 "HTTP/1.1 400 Bad Request\r\n" 2019 "\r\n"; 2020 2021 static const char cookiemsg[] = 2022 "HTTP/1.1 200 OK\r\n" 2023 "Set-Cookie: name = value \r\n" 2024 "Set-Cookie: NAME = value \r\n" 2025 "\r\n"; 2026 2027 static const char cookiemsg2[] = 2028 "HTTP/1.1 200 OK\r\n" 2029 "Set-Cookie: name2=value; Domain = localhost; Path=/cookie5;Expires=Wed, 13 Jan 2021 22:23:01 GMT; HttpOnly; \r\n" 2030 "\r\n"; 2031 2032 static const char nocontentmsg[] = 2033 "HTTP/1.1 204 No Content\r\n" 2034 "Server: winetest\r\n" 2035 "\r\n"; 2036 2037 static const char notmodified[] = 2038 "HTTP/1.1 304 Not Modified\r\n" 2039 "\r\n"; 2040 2041 static const char noauthmsg[] = 2042 "HTTP/1.1 401 Unauthorized\r\n" 2043 "Server: winetest\r\n" 2044 "Connection: close\r\n" 2045 "WWW-Authenticate: Basic realm=\"placebo\"\r\n" 2046 "Content-Length: 12\r\n" 2047 "Content-Type: text/plain\r\n" 2048 "\r\n"; 2049 2050 static const char okauthmsg[] = 2051 "HTTP/1.1 200 OK\r\n" 2052 "Server: winetest\r\n" 2053 "Connection: close\r\n" 2054 "Content-Length: 11\r\n" 2055 "Content-Type: text/plain\r\n" 2056 "\r\n"; 2057 2058 static const char headmsg[] = 2059 "HTTP/1.1 200 OK\r\n" 2060 "Content-Length: 100\r\n" 2061 "\r\n"; 2062 2063 static const char multiauth[] = 2064 "HTTP/1.1 401 Unauthorized\r\n" 2065 "Server: winetest\r\n" 2066 "WWW-Authenticate: Bearer\r\n" 2067 "WWW-Authenticate: Basic realm=\"placebo\"\r\n" 2068 "WWW-Authenticate: NTLM\r\n" 2069 "Content-Length: 10\r\n" 2070 "Content-Type: text/plain\r\n" 2071 "\r\n"; 2072 2073 static const char largeauth[] = 2074 "HTTP/1.1 401 Unauthorized\r\n" 2075 "Server: winetest\r\n" 2076 "WWW-Authenticate: Basic realm=\"placebo\"\r\n" 2077 "WWW-Authenticate: NTLM\r\n" 2078 "Content-Length: 10240\r\n" 2079 "Content-Type: text/plain\r\n" 2080 "\r\n"; 2081 2082 static const char unauthorized[] = "Unauthorized"; 2083 static const char hello_world[] = "Hello World"; 2084 static const char auth_unseen[] = "Auth Unseen"; 2085 2086 struct server_info 2087 { 2088 HANDLE event; 2089 int port; 2090 }; 2091 2092 #define BIG_BUFFER_LEN 0x2250 2093 2094 static DWORD CALLBACK server_thread(LPVOID param) 2095 { 2096 struct server_info *si = param; 2097 int r, c = -1, i, on; 2098 SOCKET s; 2099 struct sockaddr_in sa; 2100 char buffer[0x100]; 2101 WSADATA wsaData; 2102 int last_request = 0; 2103 2104 WSAStartup(MAKEWORD(1,1), &wsaData); 2105 2106 s = socket(AF_INET, SOCK_STREAM, 0); 2107 if (s == INVALID_SOCKET) 2108 return 1; 2109 2110 on = 1; 2111 setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (char*)&on, sizeof on); 2112 2113 memset(&sa, 0, sizeof sa); 2114 sa.sin_family = AF_INET; 2115 sa.sin_port = htons(si->port); 2116 sa.sin_addr.S_un.S_addr = inet_addr("127.0.0.1"); 2117 2118 r = bind(s, (struct sockaddr *)&sa, sizeof(sa)); 2119 if (r < 0) 2120 return 1; 2121 2122 listen(s, 0); 2123 SetEvent(si->event); 2124 do 2125 { 2126 if (c == -1) c = accept(s, NULL, NULL); 2127 2128 memset(buffer, 0, sizeof buffer); 2129 for(i = 0; i < sizeof buffer - 1; i++) 2130 { 2131 r = recv(c, &buffer[i], 1, 0); 2132 if (r != 1) 2133 break; 2134 if (i < 4) continue; 2135 if (buffer[i - 2] == '\n' && buffer[i] == '\n' && 2136 buffer[i - 3] == '\r' && buffer[i - 1] == '\r') 2137 break; 2138 } 2139 if (strstr(buffer, "GET /basic")) 2140 { 2141 send(c, okmsg, sizeof okmsg - 1, 0); 2142 send(c, page1, sizeof page1 - 1, 0); 2143 } 2144 if (strstr(buffer, "/auth_with_creds")) 2145 { 2146 send(c, okauthmsg, sizeof okauthmsg - 1, 0); 2147 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q=")) 2148 send(c, hello_world, sizeof hello_world - 1, 0); 2149 else 2150 send(c, auth_unseen, sizeof auth_unseen - 1, 0); 2151 continue; 2152 } 2153 if (strstr(buffer, "/auth")) 2154 { 2155 if (strstr(buffer, "Authorization: Basic dXNlcjpwd2Q=")) 2156 { 2157 send(c, okauthmsg, sizeof okauthmsg - 1, 0); 2158 send(c, hello_world, sizeof hello_world - 1, 0); 2159 } 2160 else 2161 { 2162 send(c, noauthmsg, sizeof noauthmsg - 1, 0); 2163 send(c, unauthorized, sizeof unauthorized - 1, 0); 2164 } 2165 continue; 2166 } 2167 if (strstr(buffer, "/big")) 2168 { 2169 char msg[BIG_BUFFER_LEN]; 2170 memset(msg, 'm', sizeof(msg)); 2171 send(c, okmsg, sizeof(okmsg) - 1, 0); 2172 send(c, msg, sizeof(msg), 0); 2173 } 2174 if (strstr(buffer, "/no_headers")) 2175 { 2176 send(c, page1, sizeof page1 - 1, 0); 2177 } 2178 if (strstr(buffer, "GET /no_content")) 2179 { 2180 send(c, nocontentmsg, sizeof nocontentmsg - 1, 0); 2181 continue; 2182 } 2183 if (strstr(buffer, "GET /not_modified")) 2184 { 2185 if (strstr(buffer, "If-Modified-Since:")) send(c, notmodified, sizeof notmodified - 1, 0); 2186 else send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2187 continue; 2188 } 2189 if (strstr(buffer, "HEAD /head")) 2190 { 2191 send(c, headmsg, sizeof headmsg - 1, 0); 2192 continue; 2193 } 2194 if (strstr(buffer, "GET /multiauth")) 2195 { 2196 send(c, multiauth, sizeof multiauth - 1, 0); 2197 } 2198 if (strstr(buffer, "GET /largeauth")) 2199 { 2200 if (strstr(buffer, "Authorization: NTLM")) 2201 send(c, okmsg, sizeof(okmsg) - 1, 0); 2202 else 2203 { 2204 send(c, largeauth, sizeof largeauth - 1, 0); 2205 #ifdef __REACTOS__ 2206 memset(buffer, 'A', sizeof(buffer)); 2207 for (i = 0; i < (10240 / sizeof(buffer)); i++) send(c, buffer, sizeof(buffer), 0); 2208 #else 2209 for (i = 0; i < 10240; i++) send(c, "A", 1, 0); 2210 #endif 2211 continue; 2212 } 2213 } 2214 if (strstr(buffer, "GET /cookie5")) 2215 { 2216 if (strstr(buffer, "Cookie: name2=value\r\n")) 2217 send(c, okmsg, sizeof(okmsg) - 1, 0); 2218 else 2219 send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2220 } 2221 if (strstr(buffer, "GET /cookie4")) 2222 { 2223 send(c, cookiemsg2, sizeof(cookiemsg2) - 1, 0); 2224 } 2225 if (strstr(buffer, "GET /cookie3")) 2226 { 2227 if (strstr(buffer, "Cookie: name=value2; NAME=value; name=value\r\n") || 2228 broken(strstr(buffer, "Cookie: name=value2; name=value; NAME=value\r\n") != NULL)) 2229 send(c, okmsg, sizeof(okmsg) - 1, 0); 2230 else 2231 send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2232 } 2233 if (strstr(buffer, "GET /cookie2")) 2234 { 2235 if (strstr(buffer, "Cookie: NAME=value; name=value\r\n") || 2236 broken(strstr(buffer, "Cookie: name=value; NAME=value\r\n") != NULL)) 2237 send(c, okmsg, sizeof(okmsg) - 1, 0); 2238 else 2239 send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2240 } 2241 else if (strstr(buffer, "GET /cookie")) 2242 { 2243 if (!strstr(buffer, "Cookie: name=value\r\n")) send(c, cookiemsg, sizeof(cookiemsg) - 1, 0); 2244 else send(c, notokmsg, sizeof(notokmsg) - 1, 0); 2245 } 2246 if (strstr(buffer, "GET /quit")) 2247 { 2248 send(c, okmsg, sizeof okmsg - 1, 0); 2249 send(c, page1, sizeof page1 - 1, 0); 2250 last_request = 1; 2251 } 2252 shutdown(c, 2); 2253 closesocket(c); 2254 c = -1; 2255 2256 } while (!last_request); 2257 2258 closesocket(s); 2259 return 0; 2260 } 2261 2262 static void test_basic_request(int port, const WCHAR *verb, const WCHAR *path) 2263 { 2264 static const WCHAR test_header_end_clrf[] = {'\r','\n','\r','\n',0}; 2265 static const WCHAR test_header_end_raw[] = {0,0}; 2266 HINTERNET ses, con, req; 2267 char buffer[0x100]; 2268 WCHAR buffer2[0x100]; 2269 DWORD count, status, size, error, supported, first, target; 2270 BOOL ret; 2271 2272 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2273 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2274 2275 SetLastError(0xdeadbeef); 2276 ret = WinHttpSetOption(ses, 0, buffer, sizeof(buffer)); 2277 ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError()); 2278 2279 SetLastError(0xdeadbeef); 2280 ret = WinHttpQueryOption(ses, 0, buffer, &size); 2281 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError()); 2282 2283 con = WinHttpConnect(ses, localhostW, port, 0); 2284 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2285 2286 SetLastError(0xdeadbeef); 2287 ret = WinHttpSetOption(con, 0, buffer, sizeof(buffer)); 2288 todo_wine ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError()); 2289 2290 SetLastError(0xdeadbeef); 2291 ret = WinHttpQueryOption(con, 0, buffer, &size); 2292 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError()); 2293 2294 req = WinHttpOpenRequest(con, verb, path, NULL, NULL, NULL, 0); 2295 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2296 2297 SetLastError(0xdeadbeef); 2298 ret = WinHttpSetOption(req, 0, buffer, sizeof(buffer)); 2299 ok(!ret && GetLastError() == ERROR_WINHTTP_INVALID_OPTION, "got %u\n", GetLastError()); 2300 2301 SetLastError(0xdeadbeef); 2302 ret = WinHttpQueryOption(req, 0, buffer, &size); 2303 ok(!ret && GetLastError() == ERROR_INVALID_PARAMETER, "got %u\n", GetLastError()); 2304 2305 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2306 ok(ret, "failed to send request %u\n", GetLastError()); 2307 2308 ret = WinHttpReceiveResponse(req, NULL); 2309 ok(ret, "failed to receive response %u\n", GetLastError()); 2310 2311 status = 0xdeadbeef; 2312 size = sizeof(status); 2313 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2314 ok(ret, "failed to query status code %u\n", GetLastError()); 2315 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2316 2317 supported = first = target = 0xdeadbeef; 2318 SetLastError(0xdeadbeef); 2319 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2320 error = GetLastError(); 2321 ok(!ret, "unexpected success\n"); 2322 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error); 2323 ok(supported == 0xdeadbeef, "got %x\n", supported); 2324 ok(first == 0xdeadbeef, "got %x\n", first); 2325 ok(target == 0xdeadbeef, "got %x\n", target); 2326 2327 size = sizeof(buffer2); 2328 memset(buffer2, 0, sizeof(buffer2)); 2329 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS_CRLF, NULL, buffer2, &size, NULL); 2330 ok(ret, "failed to query for raw headers: %u\n", GetLastError()); 2331 ok(!memcmp(buffer2 + lstrlenW(buffer2) - 4, test_header_end_clrf, sizeof(test_header_end_clrf)), 2332 "WinHttpQueryHeaders returned invalid end of header string\n"); 2333 2334 size = sizeof(buffer2); 2335 memset(buffer2, 0, sizeof(buffer2)); 2336 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_RAW_HEADERS, NULL, buffer2, &size, NULL); 2337 ok(ret, "failed to query for raw headers: %u\n", GetLastError()); 2338 ok(!memcmp(buffer2 + (size / sizeof(WCHAR)) - 1, test_header_end_raw, sizeof(test_header_end_raw)), 2339 "WinHttpQueryHeaders returned invalid end of header string\n"); 2340 ok(buffer2[(size / sizeof(WCHAR)) - 2] != 0, "returned string has too many NULL characters\n"); 2341 2342 count = 0; 2343 memset(buffer, 0, sizeof(buffer)); 2344 ret = WinHttpReadData(req, buffer, sizeof buffer, &count); 2345 ok(ret, "failed to read data %u\n", GetLastError()); 2346 ok(count == sizeof page1 - 1, "count was wrong\n"); 2347 ok(!memcmp(buffer, page1, sizeof page1), "http data wrong\n"); 2348 2349 WinHttpCloseHandle(req); 2350 WinHttpCloseHandle(con); 2351 WinHttpCloseHandle(ses); 2352 } 2353 2354 static void test_basic_authentication(int port) 2355 { 2356 static const WCHAR authW[] = {'/','a','u','t','h',0}; 2357 static const WCHAR auth_with_credsW[] = {'/','a','u','t','h','_','w','i','t','h','_','c','r','e','d','s',0}; 2358 static WCHAR userW[] = {'u','s','e','r',0}; 2359 static WCHAR passW[] = {'p','w','d',0}; 2360 static WCHAR pass2W[] = {'p','w','d','2',0}; 2361 HINTERNET ses, con, req; 2362 DWORD status, size, error, supported, first, target; 2363 char buffer[32]; 2364 BOOL ret; 2365 2366 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2367 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2368 2369 con = WinHttpConnect(ses, localhostW, port, 0); 2370 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2371 2372 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0); 2373 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2374 2375 SetLastError(0xdeadbeef); 2376 ret = WinHttpQueryAuthSchemes(NULL, NULL, NULL, NULL); 2377 error = GetLastError(); 2378 ok(!ret, "expected failure\n"); 2379 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error); 2380 2381 SetLastError(0xdeadbeef); 2382 ret = WinHttpQueryAuthSchemes(req, NULL, NULL, NULL); 2383 error = GetLastError(); 2384 ok(!ret, "expected failure\n"); 2385 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error); 2386 2387 supported = 0xdeadbeef; 2388 SetLastError(0xdeadbeef); 2389 ret = WinHttpQueryAuthSchemes(req, &supported, NULL, NULL); 2390 error = GetLastError(); 2391 ok(!ret, "expected failure\n"); 2392 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error); 2393 ok(supported == 0xdeadbeef, "got %x\n", supported); 2394 2395 supported = first = 0xdeadbeef; 2396 SetLastError(0xdeadbeef); 2397 ret = WinHttpQueryAuthSchemes(req, &supported, &first, NULL); 2398 error = GetLastError(); 2399 ok(!ret, "expected failure\n"); 2400 ok(error == ERROR_INVALID_PARAMETER || error == ERROR_INVALID_OPERATION, "got %u\n", error); 2401 ok(supported == 0xdeadbeef, "got %x\n", supported); 2402 ok(first == 0xdeadbeef, "got %x\n", first); 2403 2404 supported = first = target = 0xdeadbeef; 2405 SetLastError(0xdeadbeef); 2406 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2407 error = GetLastError(); 2408 ok(!ret, "expected failure\n"); 2409 todo_wine ok(error == ERROR_INVALID_OPERATION, "expected ERROR_INVALID_OPERATION, got %u\n", error); 2410 ok(supported == 0xdeadbeef, "got %x\n", supported); 2411 ok(first == 0xdeadbeef, "got %x\n", first); 2412 ok(target == 0xdeadbeef, "got %x\n", target); 2413 2414 supported = first = target = 0xdeadbeef; 2415 SetLastError(0xdeadbeef); 2416 ret = WinHttpQueryAuthSchemes(NULL, &supported, &first, &target); 2417 error = GetLastError(); 2418 ok(!ret, "expected failure\n"); 2419 ok(error == ERROR_INVALID_HANDLE, "expected ERROR_INVALID_HANDLE, got %u\n", error); 2420 ok(supported == 0xdeadbeef, "got %x\n", supported); 2421 ok(first == 0xdeadbeef, "got %x\n", first); 2422 ok(target == 0xdeadbeef, "got %x\n", target); 2423 2424 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2425 ok(ret, "failed to send request %u\n", GetLastError()); 2426 2427 ret = WinHttpReceiveResponse(req, NULL); 2428 ok(ret, "failed to receive response %u\n", GetLastError()); 2429 2430 status = 0xdeadbeef; 2431 size = sizeof(status); 2432 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2433 ok(ret, "failed to query status code %u\n", GetLastError()); 2434 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status); 2435 2436 size = 0; 2437 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 2438 error = GetLastError(); 2439 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError()); 2440 if (ret) 2441 { 2442 ok(size == 12, "expected 12, got %u\n", size); 2443 ok(!memcmp(buffer, unauthorized, 12), "got %s\n", buffer); 2444 } 2445 2446 supported = first = target = 0xdeadbeef; 2447 SetLastError(0xdeadbeef); 2448 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2449 error = GetLastError(); 2450 ok(ret, "failed to query authentication schemes %u\n", error); 2451 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error); 2452 ok(supported == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", supported); 2453 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first); 2454 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target); 2455 2456 SetLastError(0xdeadbeef); 2457 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, NULL, NULL, NULL); 2458 error = GetLastError(); 2459 ok(ret, "failed to set credentials %u\n", error); 2460 ok(error == ERROR_SUCCESS || broken(error == 0xdeadbeef) /* < win7 */, "expected ERROR_SUCCESS, got %u\n", error); 2461 2462 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_PASSPORT, NULL, NULL, NULL); 2463 ok(ret, "failed to set credentials %u\n", GetLastError()); 2464 2465 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NEGOTIATE, NULL, NULL, NULL); 2466 ok(ret, "failed to set credentials %u\n", GetLastError()); 2467 2468 SetLastError(0xdeadbeef); 2469 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_DIGEST, NULL, NULL, NULL); 2470 error = GetLastError(); 2471 ok(!ret, "expected failure\n"); 2472 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2473 2474 SetLastError(0xdeadbeef); 2475 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, NULL, NULL); 2476 error = GetLastError(); 2477 ok(!ret, "expected failure\n"); 2478 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2479 2480 SetLastError(0xdeadbeef); 2481 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL); 2482 error = GetLastError(); 2483 ok(!ret, "expected failure\n"); 2484 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2485 2486 SetLastError(0xdeadbeef); 2487 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL); 2488 error = GetLastError(); 2489 ok(!ret, "expected failure\n"); 2490 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 2491 2492 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 2493 ok(ret, "failed to set credentials %u\n", GetLastError()); 2494 2495 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2496 ok(ret, "failed to send request %u\n", GetLastError()); 2497 2498 ret = WinHttpReceiveResponse(req, NULL); 2499 ok(ret, "failed to receive response %u\n", GetLastError()); 2500 2501 status = 0xdeadbeef; 2502 size = sizeof(status); 2503 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2504 ok(ret, "failed to query status code %u\n", GetLastError()); 2505 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2506 2507 size = 0; 2508 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 2509 error = GetLastError(); 2510 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError()); 2511 if (ret) 2512 { 2513 ok(size == 11, "expected 11, got %u\n", size); 2514 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer); 2515 } 2516 2517 WinHttpCloseHandle(req); 2518 WinHttpCloseHandle(con); 2519 WinHttpCloseHandle(ses); 2520 2521 /* now set the credentials first to show that they get sent with the first request */ 2522 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2523 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2524 2525 con = WinHttpConnect(ses, localhostW, port, 0); 2526 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2527 2528 req = WinHttpOpenRequest(con, NULL, auth_with_credsW, NULL, NULL, NULL, 0); 2529 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2530 2531 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 2532 ok(ret, "failed to set credentials %u\n", GetLastError()); 2533 2534 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2535 ok(ret, "failed to send request %u\n", GetLastError()); 2536 2537 ret = WinHttpReceiveResponse(req, NULL); 2538 ok(ret, "failed to receive response %u\n", GetLastError()); 2539 2540 status = 0xdeadbeef; 2541 size = sizeof(status); 2542 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2543 ok(ret, "failed to query status code %u\n", GetLastError()); 2544 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2545 2546 size = 0; 2547 ret = WinHttpReadData(req, buffer, sizeof(buffer), &size); 2548 error = GetLastError(); 2549 ok(ret || broken(error == ERROR_WINHTTP_SHUTDOWN || error == ERROR_WINHTTP_TIMEOUT) /* XP */, "failed to read data %u\n", GetLastError()); 2550 if (ret) 2551 { 2552 ok(size == 11, "expected 11, got %u\n", size); 2553 ok(!memcmp(buffer, hello_world, 11), "got %s\n", buffer); 2554 } 2555 2556 WinHttpCloseHandle(req); 2557 WinHttpCloseHandle(con); 2558 WinHttpCloseHandle(ses); 2559 2560 /* credentials set with WinHttpSetCredentials take precedence over those set through options */ 2561 2562 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2563 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2564 2565 con = WinHttpConnect(ses, localhostW, port, 0); 2566 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2567 2568 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0); 2569 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2570 2571 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 2572 ok(ret, "failed to set credentials %u\n", GetLastError()); 2573 2574 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW)); 2575 ok(ret, "failed to set username %u\n", GetLastError()); 2576 2577 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, pass2W, lstrlenW(pass2W)); 2578 ok(ret, "failed to set password %u\n", GetLastError()); 2579 2580 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2581 ok(ret, "failed to send request %u\n", GetLastError()); 2582 2583 ret = WinHttpReceiveResponse(req, NULL); 2584 ok(ret, "failed to receive response %u\n", GetLastError()); 2585 2586 status = 0xdeadbeef; 2587 size = sizeof(status); 2588 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2589 ok(ret, "failed to query status code %u\n", GetLastError()); 2590 ok(status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status); 2591 2592 WinHttpCloseHandle(req); 2593 WinHttpCloseHandle(con); 2594 WinHttpCloseHandle(ses); 2595 2596 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2597 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2598 2599 con = WinHttpConnect(ses, localhostW, port, 0); 2600 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2601 2602 req = WinHttpOpenRequest(con, NULL, authW, NULL, NULL, NULL, 0); 2603 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2604 2605 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW)); 2606 ok(ret, "failed to set username %u\n", GetLastError()); 2607 2608 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW)); 2609 ok(ret, "failed to set password %u\n", GetLastError()); 2610 2611 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, pass2W, NULL); 2612 ok(ret, "failed to set credentials %u\n", GetLastError()); 2613 2614 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2615 ok(ret, "failed to send request %u\n", GetLastError()); 2616 2617 ret = WinHttpReceiveResponse(req, NULL); 2618 ok(ret, "failed to receive response %u\n", GetLastError()); 2619 2620 status = 0xdeadbeef; 2621 size = sizeof(status); 2622 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL); 2623 ok(ret, "failed to query status code %u\n", GetLastError()); 2624 ok(status == HTTP_STATUS_DENIED, "request failed unexpectedly %u\n", status); 2625 2626 WinHttpCloseHandle(req); 2627 WinHttpCloseHandle(con); 2628 WinHttpCloseHandle(ses); 2629 } 2630 2631 static void test_multi_authentication(int port) 2632 { 2633 static const WCHAR multiauthW[] = {'/','m','u','l','t','i','a','u','t','h',0}; 2634 static const WCHAR getW[] = {'G','E','T',0}; 2635 HINTERNET ses, con, req; 2636 DWORD supported, first, target; 2637 BOOL ret; 2638 2639 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2640 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2641 2642 con = WinHttpConnect(ses, localhostW, port, 0); 2643 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2644 2645 req = WinHttpOpenRequest(con, getW, multiauthW, NULL, NULL, NULL, 0); 2646 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2647 2648 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, 2649 WINHTTP_NO_REQUEST_DATA,0, 0, 0 ); 2650 ok(ret, "expected success\n"); 2651 2652 ret = WinHttpReceiveResponse(req, NULL); 2653 ok(ret, "expected success\n"); 2654 2655 supported = first = target = 0xdeadbeef; 2656 ret = WinHttpQueryAuthSchemes(req, &supported, &first, &target); 2657 ok(ret, "expected success\n"); 2658 ok(supported == (WINHTTP_AUTH_SCHEME_BASIC | WINHTTP_AUTH_SCHEME_NTLM), "got %x\n", supported); 2659 ok(target == WINHTTP_AUTH_TARGET_SERVER, "got %x\n", target); 2660 ok(first == WINHTTP_AUTH_SCHEME_BASIC, "got %x\n", first); 2661 2662 WinHttpCloseHandle(req); 2663 WinHttpCloseHandle(con); 2664 WinHttpCloseHandle(ses); 2665 } 2666 2667 static void test_large_data_authentication(int port) 2668 { 2669 static const WCHAR largeauthW[] = {'/','l','a','r','g','e','a','u','t','h',0}; 2670 static const WCHAR getW[] = {'G','E','T',0}; 2671 static WCHAR userW[] = {'u','s','e','r',0}; 2672 static WCHAR passW[] = {'p','w','d',0}; 2673 HINTERNET ses, con, req; 2674 DWORD status, size; 2675 BOOL ret; 2676 2677 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2678 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2679 2680 con = WinHttpConnect(ses, localhostW, port, 0); 2681 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2682 2683 req = WinHttpOpenRequest(con, getW, largeauthW, NULL, NULL, NULL, 0); 2684 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2685 2686 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); 2687 ok(ret, "expected success\n"); 2688 2689 ret = WinHttpReceiveResponse(req, NULL); 2690 ok(ret, "expected success\n"); 2691 2692 size = sizeof(status); 2693 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, 2694 &status, &size, NULL); 2695 ok(ret, "expected success\n"); 2696 ok(status == HTTP_STATUS_DENIED, "got %d\n", status); 2697 2698 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_NTLM, userW, passW, NULL); 2699 ok(ret, "expected success\n"); 2700 2701 ret = WinHttpSendRequest(req, WINHTTP_NO_ADDITIONAL_HEADERS, 0, WINHTTP_NO_REQUEST_DATA, 0, 0, 0); 2702 ok(ret, "expected success %d\n", GetLastError()); 2703 2704 ret = WinHttpReceiveResponse(req, NULL); 2705 ok(ret, "expected success\n"); 2706 2707 size = sizeof(status); 2708 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, NULL, 2709 &status, &size, NULL); 2710 ok(ret, "expected success\n"); 2711 ok(status == HTTP_STATUS_OK, "got %d\n", status); 2712 2713 WinHttpCloseHandle(req); 2714 WinHttpCloseHandle(con); 2715 WinHttpCloseHandle(ses); 2716 } 2717 2718 static void test_no_headers(int port) 2719 { 2720 static const WCHAR no_headersW[] = {'/','n','o','_','h','e','a','d','e','r','s',0}; 2721 HINTERNET ses, con, req; 2722 DWORD error; 2723 BOOL ret; 2724 2725 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2726 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2727 2728 con = WinHttpConnect(ses, localhostW, port, 0); 2729 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2730 2731 req = WinHttpOpenRequest(con, NULL, no_headersW, NULL, NULL, NULL, 0); 2732 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2733 2734 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2735 if (!ret) 2736 { 2737 error = GetLastError(); 2738 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error); 2739 } 2740 else 2741 { 2742 SetLastError(0xdeadbeef); 2743 ret = WinHttpReceiveResponse(req, NULL); 2744 error = GetLastError(); 2745 ok(!ret, "expected failure\n"); 2746 ok(error == ERROR_WINHTTP_INVALID_SERVER_RESPONSE, "got %u\n", error); 2747 } 2748 2749 WinHttpCloseHandle(req); 2750 WinHttpCloseHandle(con); 2751 WinHttpCloseHandle(ses); 2752 } 2753 2754 static void test_no_content(int port) 2755 { 2756 static const WCHAR no_contentW[] = {'/','n','o','_','c','o','n','t','e','n','t',0}; 2757 HINTERNET ses, con, req; 2758 char buf[128]; 2759 DWORD size, len = sizeof(buf), bytes_read, status; 2760 BOOL ret; 2761 2762 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2763 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2764 2765 con = WinHttpConnect(ses, localhostW, port, 0); 2766 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2767 2768 req = WinHttpOpenRequest(con, NULL, no_contentW, NULL, NULL, NULL, 0); 2769 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2770 2771 size = 12345; 2772 SetLastError(0xdeadbeef); 2773 ret = WinHttpQueryDataAvailable(req, &size); 2774 todo_wine { 2775 ok(!ret, "expected error\n"); 2776 ok(GetLastError() == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, 2777 "expected ERROR_WINHTTP_INCORRECT_HANDLE_STATE, got 0x%08x\n", GetLastError()); 2778 ok(size == 12345 || broken(size == 0) /* Win <= 2003 */, 2779 "expected 12345, got %u\n", size); 2780 } 2781 2782 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2783 ok(ret, "expected success\n"); 2784 2785 ret = WinHttpReceiveResponse(req, NULL); 2786 ok(ret, "expected success\n"); 2787 2788 status = 0xdeadbeef; 2789 size = sizeof(status); 2790 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, 2791 NULL, &status, &size, NULL); 2792 ok(ret, "expected success\n"); 2793 ok(status == HTTP_STATUS_NO_CONTENT, "expected status 204, got %d\n", status); 2794 2795 SetLastError(0xdeadbeef); 2796 size = sizeof(status); 2797 status = 12345; 2798 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, 2799 NULL, &status, &size, 0); 2800 ok(!ret, "expected no content-length header\n"); 2801 ok(GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError()); 2802 ok(status == 12345, "expected 0, got %d\n", status); 2803 2804 SetLastError(0xdeadbeef); 2805 size = 12345; 2806 ret = WinHttpQueryDataAvailable(req, &size); 2807 ok(ret, "expected success\n"); 2808 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 2809 "wrong error %u\n", GetLastError()); 2810 ok(!size, "expected 0, got %u\n", size); 2811 2812 SetLastError(0xdeadbeef); 2813 ret = WinHttpReadData(req, buf, len, &bytes_read); 2814 ok(ret, "expected success\n"); 2815 ok(GetLastError() == ERROR_SUCCESS || broken(GetLastError() == 0xdeadbeef) /* < win7 */, 2816 "wrong error %u\n", GetLastError()); 2817 ok(!bytes_read, "expected 0, got %u\n", bytes_read); 2818 2819 size = 12345; 2820 ret = WinHttpQueryDataAvailable(req, &size); 2821 ok(ret, "expected success\n"); 2822 ok(size == 0, "expected 0, got %d\n", size); 2823 2824 WinHttpCloseHandle(req); 2825 2826 size = 12345; 2827 SetLastError(0xdeadbeef); 2828 ret = WinHttpQueryDataAvailable(req, &size); 2829 ok(!ret, "expected error\n"); 2830 ok(GetLastError() == ERROR_INVALID_HANDLE, 2831 "expected ERROR_INVALID_HANDLE, got 0x%08x\n", GetLastError()); 2832 ok(size == 12345, "expected 12345, got %u\n", size); 2833 2834 WinHttpCloseHandle(con); 2835 WinHttpCloseHandle(ses); 2836 } 2837 2838 static void test_head_request(int port) 2839 { 2840 static const WCHAR verbW[] = {'H','E','A','D',0}; 2841 static const WCHAR headW[] = {'/','h','e','a','d',0}; 2842 HINTERNET ses, con, req; 2843 char buf[128]; 2844 DWORD size, len, count, status; 2845 BOOL ret; 2846 2847 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2848 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 2849 2850 con = WinHttpConnect(ses, localhostW, port, 0); 2851 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 2852 2853 req = WinHttpOpenRequest(con, verbW, headW, NULL, NULL, NULL, 0); 2854 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 2855 2856 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 2857 ok(ret, "failed to send request %u\n", GetLastError()); 2858 2859 ret = WinHttpReceiveResponse(req, NULL); 2860 ok(ret, "failed to receive response %u\n", GetLastError()); 2861 2862 status = 0xdeadbeef; 2863 size = sizeof(status); 2864 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_STATUS_CODE | WINHTTP_QUERY_FLAG_NUMBER, 2865 NULL, &status, &size, NULL); 2866 ok(ret, "failed to get status code %u\n", GetLastError()); 2867 ok(status == HTTP_STATUS_OK, "got %u\n", status); 2868 2869 len = 0xdeadbeef; 2870 size = sizeof(len); 2871 ret = WinHttpQueryHeaders(req, WINHTTP_QUERY_CONTENT_LENGTH | WINHTTP_QUERY_FLAG_NUMBER, 2872 NULL, &len, &size, 0); 2873 ok(ret, "failed to get content-length header %u\n", GetLastError()); 2874 ok(len == HTTP_STATUS_CONTINUE, "got %u\n", len); 2875 2876 count = 0xdeadbeef; 2877 ret = WinHttpQueryDataAvailable(req, &count); 2878 ok(ret, "failed to query data available %u\n", GetLastError()); 2879 ok(!count, "got %u\n", count); 2880 2881 len = sizeof(buf); 2882 count = 0xdeadbeef; 2883 ret = WinHttpReadData(req, buf, len, &count); 2884 ok(ret, "failed to read data %u\n", GetLastError()); 2885 ok(!count, "got %u\n", count); 2886 2887 count = 0xdeadbeef; 2888 ret = WinHttpQueryDataAvailable(req, &count); 2889 ok(ret, "failed to query data available %u\n", GetLastError()); 2890 ok(!count, "got %u\n", count); 2891 2892 WinHttpCloseHandle(req); 2893 WinHttpCloseHandle(con); 2894 WinHttpCloseHandle(ses); 2895 } 2896 2897 static void test_not_modified(int port) 2898 { 2899 static const WCHAR pathW[] = {'/','n','o','t','_','m','o','d','i','f','i','e','d',0}; 2900 static const WCHAR ifmodifiedW[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',':',' '}; 2901 static const WCHAR ifmodified2W[] = {'I','f','-','M','o','d','i','f','i','e','d','-','S','i','n','c','e',0}; 2902 BOOL ret; 2903 HINTERNET session, request, connection; 2904 DWORD index, len, status, size, start = GetTickCount(); 2905 SYSTEMTIME st; 2906 WCHAR today[(sizeof(ifmodifiedW) + WINHTTP_TIME_FORMAT_BUFSIZE)/sizeof(WCHAR) + 3], buffer[32]; 2907 2908 memcpy(today, ifmodifiedW, sizeof(ifmodifiedW)); 2909 GetSystemTime(&st); 2910 WinHttpTimeFromSystemTime(&st, &today[sizeof(ifmodifiedW)/sizeof(WCHAR)]); 2911 2912 session = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, 2913 WINHTTP_NO_PROXY_NAME, WINHTTP_NO_PROXY_BYPASS, 0); 2914 ok(session != NULL, "WinHttpOpen failed: %u\n", GetLastError()); 2915 2916 connection = WinHttpConnect(session, localhostW, port, 0); 2917 ok(connection != NULL, "WinHttpConnect failed: %u\n", GetLastError()); 2918 2919 request = WinHttpOpenRequest(connection, NULL, pathW, NULL, WINHTTP_NO_REFERER, 2920 WINHTTP_DEFAULT_ACCEPT_TYPES, WINHTTP_FLAG_BYPASS_PROXY_CACHE); 2921 ok(request != NULL, "WinHttpOpenrequest failed: %u\n", GetLastError()); 2922 2923 ret = WinHttpSendRequest(request, today, 0, NULL, 0, 0, 0); 2924 ok(ret, "WinHttpSendRequest failed: %u\n", GetLastError()); 2925 2926 ret = WinHttpReceiveResponse(request, NULL); 2927 ok(ret, "WinHttpReceiveResponse failed: %u\n", GetLastError()); 2928 2929 index = 0; 2930 len = sizeof(buffer); 2931 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_CUSTOM | WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 2932 ifmodified2W, buffer, &len, &index); 2933 ok(ret, "failed to get header %u\n", GetLastError()); 2934 2935 status = 0xdeadbeef; 2936 size = sizeof(status); 2937 ret = WinHttpQueryHeaders(request, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, 2938 NULL, &status, &size, NULL); 2939 ok(ret, "WinHttpQueryHeaders failed: %u\n", GetLastError()); 2940 ok(status == HTTP_STATUS_NOT_MODIFIED, "got %u\n", status); 2941 2942 size = 0xdeadbeef; 2943 ret = WinHttpQueryDataAvailable(request, &size); 2944 ok(ret, "WinHttpQueryDataAvailable failed: %u\n", GetLastError()); 2945 ok(!size, "got %u\n", size); 2946 2947 WinHttpCloseHandle(request); 2948 WinHttpCloseHandle(connection); 2949 WinHttpCloseHandle(session); 2950 start = GetTickCount() - start; 2951 ok(start <= 2000, "Expected less than 2 seconds for the test, got %u ms\n", start); 2952 } 2953 2954 static void test_bad_header( int port ) 2955 { 2956 static const WCHAR bad_headerW[] = 2957 {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ', 2958 't','e','x','t','/','h','t','m','l','\n','\r',0}; 2959 static const WCHAR text_htmlW[] = {'t','e','x','t','/','h','t','m','l',0}; 2960 static const WCHAR content_typeW[] = {'C','o','n','t','e','n','t','-','T','y','p','e',0}; 2961 WCHAR buffer[32]; 2962 HINTERNET ses, con, req; 2963 DWORD index, len; 2964 BOOL ret; 2965 2966 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 2967 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 2968 2969 con = WinHttpConnect( ses, localhostW, port, 0 ); 2970 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 2971 2972 req = WinHttpOpenRequest( con, NULL, NULL, NULL, NULL, NULL, 0 ); 2973 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 2974 2975 ret = WinHttpAddRequestHeaders( req, bad_headerW, ~0u, WINHTTP_ADDREQ_FLAG_ADD ); 2976 ok( ret, "failed to add header %u\n", GetLastError() ); 2977 2978 index = 0; 2979 buffer[0] = 0; 2980 len = sizeof(buffer); 2981 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CUSTOM|WINHTTP_QUERY_FLAG_REQUEST_HEADERS, 2982 content_typeW, buffer, &len, &index ); 2983 ok( ret, "failed to query headers %u\n", GetLastError() ); 2984 ok( !lstrcmpW( buffer, text_htmlW ), "got %s\n", wine_dbgstr_w(buffer) ); 2985 2986 WinHttpCloseHandle( req ); 2987 WinHttpCloseHandle( con ); 2988 WinHttpCloseHandle( ses ); 2989 } 2990 2991 static void test_multiple_reads(int port) 2992 { 2993 static const WCHAR bigW[] = {'b','i','g',0}; 2994 HINTERNET ses, con, req; 2995 DWORD total_len = 0; 2996 BOOL ret; 2997 2998 ses = WinHttpOpen(test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0); 2999 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 3000 3001 con = WinHttpConnect(ses, localhostW, port, 0); 3002 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 3003 3004 req = WinHttpOpenRequest(con, NULL, bigW, NULL, NULL, NULL, 0); 3005 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 3006 3007 ret = WinHttpSendRequest(req, NULL, 0, NULL, 0, 0, 0); 3008 ok(ret, "failed to send request %u\n", GetLastError()); 3009 3010 ret = WinHttpReceiveResponse(req, NULL); 3011 ok(ret == TRUE, "expected success\n"); 3012 3013 for (;;) 3014 { 3015 DWORD len = 0xdeadbeef; 3016 ret = WinHttpQueryDataAvailable( req, &len ); 3017 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() ); 3018 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" ); 3019 if (len) 3020 { 3021 DWORD bytes_read; 3022 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 ); 3023 3024 ret = WinHttpReadData( req, buf, len, &bytes_read ); 3025 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len ); 3026 3027 HeapFree( GetProcessHeap(), 0, buf ); 3028 if (!bytes_read) break; 3029 total_len += bytes_read; 3030 } 3031 if (!len) break; 3032 } 3033 ok(total_len == BIG_BUFFER_LEN, "got wrong length: 0x%x\n", total_len); 3034 3035 WinHttpCloseHandle(req); 3036 WinHttpCloseHandle(con); 3037 WinHttpCloseHandle(ses); 3038 } 3039 3040 static void test_cookies( int port ) 3041 { 3042 static const WCHAR cookieW[] = {'/','c','o','o','k','i','e',0}; 3043 static const WCHAR cookie2W[] = {'/','c','o','o','k','i','e','2',0}; 3044 static const WCHAR cookie3W[] = {'/','c','o','o','k','i','e','3',0}; 3045 static const WCHAR cookie4W[] = {'/','c','o','o','k','i','e','4',0}; 3046 static const WCHAR cookie5W[] = {'/','c','o','o','k','i','e','5',0}; 3047 static const WCHAR cookieheaderW[] = 3048 {'C','o','o','k','i','e',':',' ','n','a','m','e','=','v','a','l','u','e','2','\r','\n',0}; 3049 HINTERNET ses, con, req; 3050 DWORD status, size; 3051 BOOL ret; 3052 3053 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3054 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3055 3056 con = WinHttpConnect( ses, localhostW, port, 0 ); 3057 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3058 3059 req = WinHttpOpenRequest( con, NULL, cookieW, NULL, NULL, NULL, 0 ); 3060 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3061 3062 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3063 ok( ret, "failed to send request %u\n", GetLastError() ); 3064 3065 ret = WinHttpReceiveResponse( req, NULL ); 3066 ok( ret, "failed to receive response %u\n", GetLastError() ); 3067 3068 status = 0xdeadbeef; 3069 size = sizeof(status); 3070 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3071 ok( ret, "failed to query status code %u\n", GetLastError() ); 3072 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3073 3074 WinHttpCloseHandle( req ); 3075 3076 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); 3077 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3078 3079 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3080 ok( ret, "failed to send request %u\n", GetLastError() ); 3081 3082 ret = WinHttpReceiveResponse( req, NULL ); 3083 ok( ret, "failed to receive response %u\n", GetLastError() ); 3084 3085 status = 0xdeadbeef; 3086 size = sizeof(status); 3087 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3088 ok( ret, "failed to query status code %u\n", GetLastError() ); 3089 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3090 3091 WinHttpCloseHandle( req ); 3092 WinHttpCloseHandle( con ); 3093 3094 con = WinHttpConnect( ses, localhostW, port, 0 ); 3095 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3096 3097 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); 3098 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3099 3100 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3101 ok( ret, "failed to send request %u\n", GetLastError() ); 3102 3103 ret = WinHttpReceiveResponse( req, NULL ); 3104 ok( ret, "failed to receive response %u\n", GetLastError() ); 3105 3106 status = 0xdeadbeef; 3107 size = sizeof(status); 3108 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3109 ok( ret, "failed to query status code %u\n", GetLastError() ); 3110 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3111 3112 WinHttpCloseHandle( req ); 3113 3114 req = WinHttpOpenRequest( con, NULL, cookie3W, NULL, NULL, NULL, 0 ); 3115 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3116 3117 ret = WinHttpSendRequest( req, cookieheaderW, ~0u, NULL, 0, 0, 0 ); 3118 ok( ret, "failed to send request %u\n", GetLastError() ); 3119 3120 ret = WinHttpReceiveResponse( req, NULL ); 3121 ok( ret, "failed to receive response %u\n", GetLastError() ); 3122 3123 status = 0xdeadbeef; 3124 size = sizeof(status); 3125 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3126 ok( ret, "failed to query status code %u\n", GetLastError() ); 3127 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST), "request failed unexpectedly %u\n", status ); 3128 3129 WinHttpCloseHandle( req ); 3130 WinHttpCloseHandle( con ); 3131 WinHttpCloseHandle( ses ); 3132 3133 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3134 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3135 3136 con = WinHttpConnect( ses, localhostW, port, 0 ); 3137 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3138 3139 req = WinHttpOpenRequest( con, NULL, cookie2W, NULL, NULL, NULL, 0 ); 3140 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3141 3142 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3143 ok( ret, "failed to send request %u\n", GetLastError() ); 3144 3145 ret = WinHttpReceiveResponse( req, NULL ); 3146 ok( ret, "failed to receive response %u\n", GetLastError() ); 3147 3148 status = 0xdeadbeef; 3149 size = sizeof(status); 3150 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3151 ok( ret, "failed to query status code %u\n", GetLastError() ); 3152 ok( status == HTTP_STATUS_BAD_REQUEST, "request failed unexpectedly %u\n", status ); 3153 3154 WinHttpCloseHandle( req ); 3155 WinHttpCloseHandle( con ); 3156 WinHttpCloseHandle( ses ); 3157 3158 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3159 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3160 3161 con = WinHttpConnect( ses, localhostW, port, 0 ); 3162 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3163 3164 req = WinHttpOpenRequest( con, NULL, cookie4W, NULL, NULL, NULL, 0 ); 3165 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3166 3167 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3168 ok( ret, "failed to send request %u\n", GetLastError() ); 3169 3170 ret = WinHttpReceiveResponse( req, NULL ); 3171 ok( ret, "failed to receive response %u\n", GetLastError() ); 3172 3173 status = 0xdeadbeef; 3174 size = sizeof(status); 3175 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3176 ok( ret, "failed to query status code %u\n", GetLastError() ); 3177 ok( status == HTTP_STATUS_OK, "request failed unexpectedly %u\n", status ); 3178 WinHttpCloseHandle( req ); 3179 3180 req = WinHttpOpenRequest( con, NULL, cookie5W, NULL, NULL, NULL, 0 ); 3181 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3182 3183 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3184 ok( ret, "failed to send request %u\n", GetLastError() ); 3185 3186 ret = WinHttpReceiveResponse( req, NULL ); 3187 ok( ret, "failed to receive response %u\n", GetLastError() ); 3188 3189 status = 0xdeadbeef; 3190 size = sizeof(status); 3191 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_STATUS_CODE|WINHTTP_QUERY_FLAG_NUMBER, NULL, &status, &size, NULL ); 3192 ok( ret, "failed to query status code %u\n", GetLastError() ); 3193 ok( status == HTTP_STATUS_OK || broken(status == HTTP_STATUS_BAD_REQUEST) /* < win7 */, 3194 "request failed unexpectedly %u\n", status ); 3195 3196 WinHttpCloseHandle( req ); 3197 WinHttpCloseHandle( con ); 3198 WinHttpCloseHandle( ses ); 3199 } 3200 3201 static void test_connection_info( int port ) 3202 { 3203 static const WCHAR basicW[] = {'/','b','a','s','i','c',0}; 3204 HINTERNET ses, con, req; 3205 WINHTTP_CONNECTION_INFO info; 3206 DWORD size, error; 3207 BOOL ret; 3208 3209 ses = WinHttpOpen( test_useragent, WINHTTP_ACCESS_TYPE_NO_PROXY, NULL, NULL, 0 ); 3210 ok( ses != NULL, "failed to open session %u\n", GetLastError() ); 3211 3212 con = WinHttpConnect( ses, localhostW, port, 0 ); 3213 ok( con != NULL, "failed to open a connection %u\n", GetLastError() ); 3214 3215 req = WinHttpOpenRequest( con, NULL, basicW, NULL, NULL, NULL, 0 ); 3216 ok( req != NULL, "failed to open a request %u\n", GetLastError() ); 3217 3218 size = sizeof(info); 3219 SetLastError( 0xdeadbeef ); 3220 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3221 error = GetLastError(); 3222 if (!ret && error == ERROR_INVALID_PARAMETER) 3223 { 3224 win_skip( "WINHTTP_OPTION_CONNECTION_INFO not supported\n" ); 3225 return; 3226 } 3227 ok( !ret, "unexpected success\n" ); 3228 ok( error == ERROR_WINHTTP_INCORRECT_HANDLE_STATE, "got %u\n", error ); 3229 3230 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 3231 ok( ret, "failed to send request %u\n", GetLastError() ); 3232 3233 size = 0; 3234 SetLastError( 0xdeadbeef ); 3235 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3236 error = GetLastError(); 3237 ok( !ret, "unexpected success\n" ); 3238 ok( error == ERROR_INSUFFICIENT_BUFFER, "got %u\n", error ); 3239 3240 size = sizeof(info); 3241 memset( &info, 0, sizeof(info) ); 3242 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3243 ok( ret, "failed to retrieve connection info %u\n", GetLastError() ); 3244 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize ); 3245 3246 ret = WinHttpReceiveResponse( req, NULL ); 3247 ok( ret, "failed to receive response %u\n", GetLastError() ); 3248 3249 size = sizeof(info); 3250 memset( &info, 0, sizeof(info) ); 3251 ret = WinHttpQueryOption( req, WINHTTP_OPTION_CONNECTION_INFO, &info, &size ); 3252 ok( ret, "failed to retrieve connection info %u\n", GetLastError() ); 3253 ok( info.cbSize == sizeof(info) || info.cbSize == sizeof(info) - sizeof(info.cbSize) /* Win7 */, "wrong size %u\n", info.cbSize ); 3254 3255 WinHttpCloseHandle( req ); 3256 WinHttpCloseHandle( con ); 3257 WinHttpCloseHandle( ses ); 3258 } 3259 3260 static void test_credentials(void) 3261 { 3262 static WCHAR userW[] = {'u','s','e','r',0}; 3263 static WCHAR passW[] = {'p','a','s','s',0}; 3264 static WCHAR proxy_userW[] = {'p','r','o','x','y','u','s','e','r',0}; 3265 static WCHAR proxy_passW[] = {'p','r','o','x','y','p','a','s','s',0}; 3266 HINTERNET ses, con, req; 3267 DWORD size, error; 3268 WCHAR buffer[32]; 3269 BOOL ret; 3270 3271 ses = WinHttpOpen(test_useragent, 0, proxy_userW, proxy_passW, 0); 3272 ok(ses != NULL, "failed to open session %u\n", GetLastError()); 3273 3274 con = WinHttpConnect(ses, localhostW, 0, 0); 3275 ok(con != NULL, "failed to open a connection %u\n", GetLastError()); 3276 3277 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 3278 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 3279 3280 size = sizeof(buffer)/sizeof(WCHAR); 3281 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size); 3282 ok(ret, "failed to query proxy username %u\n", GetLastError()); 3283 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3284 ok(!size, "expected 0, got %u\n", size); 3285 3286 size = sizeof(buffer)/sizeof(WCHAR); 3287 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size); 3288 ok(ret, "failed to query proxy password %u\n", GetLastError()); 3289 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3290 ok(!size, "expected 0, got %u\n", size); 3291 3292 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_USERNAME, proxy_userW, lstrlenW(proxy_userW)); 3293 ok(ret, "failed to set username %u\n", GetLastError()); 3294 3295 size = sizeof(buffer)/sizeof(WCHAR); 3296 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_USERNAME, &buffer, &size); 3297 ok(ret, "failed to query proxy username %u\n", GetLastError()); 3298 ok(!winetest_strcmpW(buffer, proxy_userW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3299 ok(size == lstrlenW(proxy_userW) * sizeof(WCHAR), "unexpected result %u\n", size); 3300 3301 size = sizeof(buffer)/sizeof(WCHAR); 3302 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); 3303 ok(ret, "failed to query username %u\n", GetLastError()); 3304 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3305 ok(!size, "expected 0, got %u\n", size); 3306 3307 size = sizeof(buffer)/sizeof(WCHAR); 3308 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); 3309 ok(ret, "failed to query password %u\n", GetLastError()); 3310 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3311 ok(!size, "expected 0, got %u\n", size); 3312 3313 ret = WinHttpSetOption(req, WINHTTP_OPTION_PROXY_PASSWORD, proxy_passW, lstrlenW(proxy_passW)); 3314 ok(ret, "failed to set proxy password %u\n", GetLastError()); 3315 3316 size = sizeof(buffer)/sizeof(WCHAR); 3317 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PROXY_PASSWORD, &buffer, &size); 3318 ok(ret, "failed to query proxy password %u\n", GetLastError()); 3319 ok(!winetest_strcmpW(buffer, proxy_passW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3320 ok(size == lstrlenW(proxy_passW) * sizeof(WCHAR), "unexpected result %u\n", size); 3321 3322 ret = WinHttpSetOption(req, WINHTTP_OPTION_USERNAME, userW, lstrlenW(userW)); 3323 ok(ret, "failed to set username %u\n", GetLastError()); 3324 3325 size = sizeof(buffer)/sizeof(WCHAR); 3326 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); 3327 ok(ret, "failed to query username %u\n", GetLastError()); 3328 ok(!winetest_strcmpW(buffer, userW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3329 ok(size == lstrlenW(userW) * sizeof(WCHAR), "unexpected result %u\n", size); 3330 3331 ret = WinHttpSetOption(req, WINHTTP_OPTION_PASSWORD, passW, lstrlenW(passW)); 3332 ok(ret, "failed to set password %u\n", GetLastError()); 3333 3334 size = sizeof(buffer)/sizeof(WCHAR); 3335 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); 3336 ok(ret, "failed to query password %u\n", GetLastError()); 3337 ok(!winetest_strcmpW(buffer, passW), "unexpected result %s\n", wine_dbgstr_w(buffer)); 3338 ok(size == lstrlenW(passW) * sizeof(WCHAR), "unexpected result %u\n", size); 3339 3340 WinHttpCloseHandle(req); 3341 3342 req = WinHttpOpenRequest(con, NULL, NULL, NULL, NULL, NULL, 0); 3343 ok(req != NULL, "failed to open a request %u\n", GetLastError()); 3344 3345 SetLastError(0xdeadbeef); 3346 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, NULL, NULL); 3347 error = GetLastError(); 3348 ok(!ret, "expected failure\n"); 3349 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 3350 3351 SetLastError(0xdeadbeef); 3352 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, NULL, passW, NULL); 3353 error = GetLastError(); 3354 ok(!ret, "expected failure\n"); 3355 ok(error == ERROR_INVALID_PARAMETER, "expected ERROR_INVALID_PARAMETER, got %u\n", error); 3356 3357 ret = WinHttpSetCredentials(req, WINHTTP_AUTH_TARGET_SERVER, WINHTTP_AUTH_SCHEME_BASIC, userW, passW, NULL); 3358 ok(ret, "failed to set credentials %u\n", GetLastError()); 3359 3360 size = sizeof(buffer)/sizeof(WCHAR); 3361 ret = WinHttpQueryOption(req, WINHTTP_OPTION_USERNAME, &buffer, &size); 3362 ok(ret, "failed to query username %u\n", GetLastError()); 3363 todo_wine { 3364 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3365 ok(!size, "expected 0, got %u\n", size); 3366 } 3367 3368 size = sizeof(buffer)/sizeof(WCHAR); 3369 ret = WinHttpQueryOption(req, WINHTTP_OPTION_PASSWORD, &buffer, &size); 3370 ok(ret, "failed to query password %u\n", GetLastError()); 3371 todo_wine { 3372 ok(!buffer[0], "unexpected result %s\n", wine_dbgstr_w(buffer)); 3373 ok(!size, "expected 0, got %u\n", size); 3374 } 3375 3376 WinHttpCloseHandle(req); 3377 WinHttpCloseHandle(con); 3378 WinHttpCloseHandle(ses); 3379 } 3380 3381 static void test_IWinHttpRequest(int port) 3382 { 3383 static const WCHAR data_start[] = {'<','!','D','O','C','T','Y','P','E',' ','h','t','m','l',' ','P','U','B','L','I','C'}; 3384 static const WCHAR usernameW[] = {'u','s','e','r','n','a','m','e',0}; 3385 static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0}; 3386 static const WCHAR url1W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0}; 3387 static const WCHAR url2W[] = {'t','e','s','t','.','w','i','n','e','h','q','.','o','r','g',0}; 3388 static const WCHAR url3W[] = {'h','t','t','p',':','/','/','t','e','s','t','.','w','i','n','e','h','q','.', 3389 'o','r','g','/','t','e','s','t','s','/','p','o','s','t','.','p','h','p',0}; 3390 static const WCHAR method1W[] = {'G','E','T',0}; 3391 static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0}; 3392 static const WCHAR method3W[] = {'P','O','S','T',0}; 3393 static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0}; 3394 static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0}; 3395 static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0}; 3396 static const WCHAR dateW[] = {'D','a','t','e',0}; 3397 static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0}; 3398 static const WCHAR utf8W[] = {'u','t','f','-','8',0}; 3399 static const WCHAR unauthW[] = {'U','n','a','u','t','h','o','r','i','z','e','d',0}; 3400 HRESULT hr; 3401 IWinHttpRequest *req; 3402 BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL; 3403 BSTR date, today, connection, value = NULL; 3404 VARIANT async, empty, timeout, body, body2, proxy_server, bypass_list, data, cp; 3405 VARIANT_BOOL succeeded; 3406 LONG status; 3407 WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE]; 3408 SYSTEMTIME st; 3409 IStream *stream, *stream2; 3410 LARGE_INTEGER pos; 3411 char buf[128]; 3412 WCHAR bufW[128]; 3413 DWORD count; 3414 3415 GetSystemTime( &st ); 3416 WinHttpTimeFromSystemTime( &st, todayW ); 3417 3418 CoInitialize( NULL ); 3419 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3420 ok( hr == S_OK, "got %08x\n", hr ); 3421 3422 V_VT( &empty ) = VT_ERROR; 3423 V_ERROR( &empty ) = 0xdeadbeef; 3424 3425 V_VT( &async ) = VT_BOOL; 3426 V_BOOL( &async ) = VARIANT_FALSE; 3427 3428 method = SysAllocString( method3W ); 3429 url = SysAllocString( url3W ); 3430 hr = IWinHttpRequest_Open( req, method, url, async ); 3431 ok( hr == S_OK, "got %08x\n", hr ); 3432 SysFreeString( method ); 3433 SysFreeString( url ); 3434 3435 V_VT( &data ) = VT_BSTR; 3436 V_BSTR( &data ) = SysAllocString( test_dataW ); 3437 hr = IWinHttpRequest_Send( req, data ); 3438 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)), 3439 "got %08x\n", hr ); 3440 SysFreeString( V_BSTR( &data ) ); 3441 3442 hr = IWinHttpRequest_Open( req, NULL, NULL, empty ); 3443 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3444 3445 method = SysAllocString( method1W ); 3446 hr = IWinHttpRequest_Open( req, method, NULL, empty ); 3447 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3448 3449 hr = IWinHttpRequest_Open( req, method, NULL, async ); 3450 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3451 3452 url = SysAllocString( url1W ); 3453 hr = IWinHttpRequest_Open( req, NULL, url, empty ); 3454 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3455 3456 hr = IWinHttpRequest_Abort( req ); 3457 ok( hr == S_OK, "got %08x\n", hr ); 3458 3459 hr = IWinHttpRequest_Open( req, method, url, empty ); 3460 ok( hr == S_OK, "got %08x\n", hr ); 3461 3462 hr = IWinHttpRequest_Abort( req ); 3463 ok( hr == S_OK, "got %08x\n", hr ); 3464 3465 IWinHttpRequest_Release( req ); 3466 3467 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3468 ok( hr == S_OK, "got %08x\n", hr ); 3469 3470 SysFreeString( url ); 3471 url = SysAllocString( url2W ); 3472 hr = IWinHttpRequest_Open( req, method, url, async ); 3473 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr ); 3474 3475 SysFreeString( method ); 3476 method = SysAllocString( method2W ); 3477 hr = IWinHttpRequest_Open( req, method, url, async ); 3478 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_UNRECOGNIZED_SCHEME ), "got %08x\n", hr ); 3479 3480 SysFreeString( method ); 3481 method = SysAllocString( method1W ); 3482 SysFreeString( url ); 3483 url = SysAllocString( url1W ); 3484 V_VT( &async ) = VT_ERROR; 3485 V_ERROR( &async ) = DISP_E_PARAMNOTFOUND; 3486 hr = IWinHttpRequest_Open( req, method, url, async ); 3487 ok( hr == S_OK, "got %08x\n", hr ); 3488 3489 V_VT( &cp ) = VT_ERROR; 3490 V_ERROR( &cp ) = 0xdeadbeef; 3491 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp ); 3492 ok( hr == S_OK, "got %08x\n", hr ); 3493 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) ); 3494 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) ); 3495 3496 V_VT( &cp ) = VT_UI4; 3497 V_UI4( &cp ) = CP_ACP; 3498 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp ); 3499 ok( hr == S_OK, "got %08x\n", hr ); 3500 3501 V_VT( &cp ) = VT_ERROR; 3502 V_ERROR( &cp ) = 0xdeadbeef; 3503 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp ); 3504 ok( hr == S_OK, "got %08x\n", hr ); 3505 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) ); 3506 ok( V_I4( &cp ) == CP_ACP, "got %u\n", V_I4( &cp ) ); 3507 3508 value = SysAllocString( utf8W ); 3509 V_VT( &cp ) = VT_BSTR; 3510 V_BSTR( &cp ) = value; 3511 hr = IWinHttpRequest_put_Option( req, WinHttpRequestOption_URLCodePage, cp ); 3512 ok( hr == S_OK, "got %08x\n", hr ); 3513 SysFreeString( value ); 3514 3515 V_VT( &cp ) = VT_ERROR; 3516 V_ERROR( &cp ) = 0xdeadbeef; 3517 hr = IWinHttpRequest_get_Option( req, WinHttpRequestOption_URLCodePage, &cp ); 3518 ok( hr == S_OK, "got %08x\n", hr ); 3519 ok( V_VT( &cp ) == VT_I4, "got %08x\n", V_VT( &cp ) ); 3520 ok( V_I4( &cp ) == CP_UTF8, "got %u\n", V_I4( &cp ) ); 3521 3522 hr = IWinHttpRequest_Abort( req ); 3523 ok( hr == S_OK, "got %08x\n", hr ); 3524 3525 hr = IWinHttpRequest_Send( req, empty ); 3526 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3527 3528 hr = IWinHttpRequest_Abort( req ); 3529 ok( hr == S_OK, "got %08x\n", hr ); 3530 3531 IWinHttpRequest_Release( req ); 3532 3533 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3534 ok( hr == S_OK, "got %08x\n", hr ); 3535 3536 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3537 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3538 3539 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3540 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3541 3542 hr = IWinHttpRequest_get_Status( req, NULL ); 3543 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3544 3545 hr = IWinHttpRequest_get_Status( req, &status ); 3546 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3547 3548 hr = IWinHttpRequest_get_StatusText( req, NULL ); 3549 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3550 3551 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3552 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3553 3554 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3555 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3556 3557 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 ); 3558 ok( hr == S_OK, "got %08x\n", hr ); 3559 3560 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef ); 3561 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3562 3563 VariantInit( &proxy_server ); 3564 V_VT( &proxy_server ) = VT_ERROR; 3565 VariantInit( &bypass_list ); 3566 V_VT( &bypass_list ) = VT_ERROR; 3567 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3568 ok( hr == S_OK, "got %08x\n", hr ); 3569 3570 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3571 ok( hr == S_OK, "got %08x\n", hr ); 3572 3573 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3574 ok( hr == S_OK, "got %08x\n", hr ); 3575 3576 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL ); 3577 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3578 3579 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3580 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3581 3582 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL ); 3583 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3584 3585 connection = SysAllocString( connectionW ); 3586 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL ); 3587 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3588 3589 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3590 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3591 3592 hr = IWinHttpRequest_SetRequestHeader( req, NULL, NULL ); 3593 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3594 3595 date = SysAllocString( dateW ); 3596 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL ); 3597 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3598 3599 today = SysAllocString( todayW ); 3600 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3601 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_OPEN ), "got %08x\n", hr ); 3602 3603 hr = IWinHttpRequest_SetAutoLogonPolicy( req, 0xdeadbeef ); 3604 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3605 3606 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3607 ok( hr == S_OK, "got %08x\n", hr ); 3608 3609 SysFreeString( method ); 3610 method = SysAllocString( method1W ); 3611 SysFreeString( url ); 3612 url = SysAllocString( url1W ); 3613 hr = IWinHttpRequest_Open( req, method, url, async ); 3614 ok( hr == S_OK, "got %08x\n", hr ); 3615 3616 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3617 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3618 3619 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3620 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3621 3622 hr = IWinHttpRequest_get_Status( req, &status ); 3623 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3624 3625 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3626 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3627 3628 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3629 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3630 3631 hr = IWinHttpRequest_SetTimeouts( req, 10000, 10000, 10000, 10000 ); 3632 ok( hr == S_OK, "got %08x\n", hr ); 3633 3634 hr = IWinHttpRequest_SetCredentials( req, NULL, NULL, 0xdeadbeef ); 3635 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3636 3637 username = SysAllocString( usernameW ); 3638 hr = IWinHttpRequest_SetCredentials( req, username, NULL, 0xdeadbeef ); 3639 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3640 3641 password = SysAllocString( passwordW ); 3642 hr = IWinHttpRequest_SetCredentials( req, NULL, password, 0xdeadbeef ); 3643 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3644 3645 hr = IWinHttpRequest_SetCredentials( req, username, password, 0xdeadbeef ); 3646 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3647 3648 hr = IWinHttpRequest_SetCredentials( req, NULL, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3649 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3650 3651 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3652 ok( hr == S_OK, "got %08x\n", hr ); 3653 3654 V_VT( &proxy_server ) = VT_BSTR; 3655 V_BSTR( &proxy_server ) = SysAllocString( proxy_serverW ); 3656 V_VT( &bypass_list ) = VT_BSTR; 3657 V_BSTR( &bypass_list ) = SysAllocString( bypas_listW ); 3658 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3659 ok( hr == S_OK, "got %08x\n", hr ); 3660 3661 hr = IWinHttpRequest_SetProxy( req, 0xdeadbeef, proxy_server, bypass_list ); 3662 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3663 3664 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3665 ok( hr == S_OK, "got %08x\n", hr ); 3666 3667 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3668 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3669 3670 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3671 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3672 3673 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3674 ok( hr == S_OK, "got %08x\n", hr ); 3675 3676 hr = IWinHttpRequest_SetRequestHeader( req, date, NULL ); 3677 ok( hr == S_OK, "got %08x\n", hr ); 3678 3679 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3680 ok( hr == S_OK, "got %08x\n", hr ); 3681 3682 hr = IWinHttpRequest_Send( req, empty ); 3683 ok( hr == S_OK, "got %08x\n", hr ); 3684 3685 hr = IWinHttpRequest_Send( req, empty ); 3686 ok( hr == S_OK, "got %08x\n", hr ); 3687 3688 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3689 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3690 3691 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3692 ok( hr == S_OK, "got %08x\n", hr ); 3693 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) ); 3694 SysFreeString( response ); 3695 3696 hr = IWinHttpRequest_get_Status( req, NULL ); 3697 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3698 3699 status = 0; 3700 hr = IWinHttpRequest_get_Status( req, &status ); 3701 ok( hr == S_OK, "got %08x\n", hr ); 3702 trace("Status=%d\n", status); 3703 3704 hr = IWinHttpRequest_get_StatusText( req, NULL ); 3705 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3706 3707 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3708 ok( hr == S_OK, "got %08x\n", hr ); 3709 trace("StatusText=%s\n", wine_dbgstr_w(status_text)); 3710 SysFreeString( status_text ); 3711 3712 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3713 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3714 3715 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3716 ok( hr == S_OK, "got %08x\n", hr ); 3717 3718 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3719 ok( hr == S_OK, "got %08x\n", hr ); 3720 3721 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3722 ok( hr == S_OK, "got %08x\n", hr ); 3723 3724 hr = IWinHttpRequest_GetAllResponseHeaders( req, NULL ); 3725 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3726 3727 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3728 ok( hr == S_OK, "got %08x\n", hr ); 3729 SysFreeString( headers ); 3730 3731 hr = IWinHttpRequest_GetResponseHeader( req, NULL, NULL ); 3732 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3733 3734 hr = IWinHttpRequest_GetResponseHeader( req, connection, NULL ); 3735 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3736 3737 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3738 ok( hr == S_OK, "got %08x\n", hr ); 3739 SysFreeString( value ); 3740 3741 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3742 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr ); 3743 3744 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3745 ok( hr == S_OK, "got %08x\n", hr ); 3746 3747 VariantInit( &timeout ); 3748 V_VT( &timeout ) = VT_I4; 3749 V_I4( &timeout ) = 10; 3750 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded ); 3751 ok( hr == S_OK, "got %08x\n", hr ); 3752 3753 hr = IWinHttpRequest_get_Status( req, &status ); 3754 ok( hr == S_OK, "got %08x\n", hr ); 3755 3756 hr = IWinHttpRequest_get_StatusText( req, &status_text ); 3757 ok( hr == S_OK, "got %08x\n", hr ); 3758 SysFreeString( status_text ); 3759 3760 hr = IWinHttpRequest_SetCredentials( req, username, password, HTTPREQUEST_SETCREDENTIALS_FOR_SERVER ); 3761 ok( hr == S_OK, "got %08x\n", hr ); 3762 3763 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3764 ok( hr == S_OK, "got %08x\n", hr ); 3765 3766 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3767 ok( hr == S_OK, "got %08x\n", hr ); 3768 3769 hr = IWinHttpRequest_Send( req, empty ); 3770 ok( hr == S_OK, "got %08x\n", hr ); 3771 3772 hr = IWinHttpRequest_get_ResponseText( req, NULL ); 3773 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3774 3775 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3776 ok( hr == S_OK, "got %08x\n", hr ); 3777 SysFreeString( response ); 3778 3779 hr = IWinHttpRequest_get_ResponseBody( req, NULL ); 3780 ok( hr == E_INVALIDARG, "got %08x\n", hr ); 3781 3782 VariantInit( &body ); 3783 V_VT( &body ) = VT_ERROR; 3784 hr = IWinHttpRequest_get_ResponseBody( req, &body ); 3785 ok( hr == S_OK, "got %08x\n", hr ); 3786 ok( V_VT( &body ) == (VT_ARRAY|VT_UI1), "got %08x\n", V_VT( &body ) ); 3787 3788 hr = VariantClear( &body ); 3789 ok( hr == S_OK, "got %08x\n", hr ); 3790 3791 VariantInit( &body ); 3792 V_VT( &body ) = VT_ERROR; 3793 hr = IWinHttpRequest_get_ResponseStream( req, &body ); 3794 ok( hr == S_OK, "got %08x\n", hr ); 3795 ok( V_VT( &body ) == VT_UNKNOWN, "got %08x\n", V_VT( &body ) ); 3796 3797 hr = IUnknown_QueryInterface( V_UNKNOWN( &body ), &IID_IStream, (void **)&stream ); 3798 ok( hr == S_OK, "got %08x\n", hr ); 3799 ok( V_UNKNOWN( &body ) == (IUnknown *)stream, "got different interface pointer\n" ); 3800 3801 buf[0] = 0; 3802 count = 0xdeadbeef; 3803 hr = IStream_Read( stream, buf, 128, &count ); 3804 ok( hr == S_OK, "got %08x\n", hr ); 3805 ok( count != 0xdeadbeef, "count not set\n" ); 3806 ok( buf[0], "no data\n" ); 3807 3808 VariantInit( &body2 ); 3809 V_VT( &body2 ) = VT_ERROR; 3810 hr = IWinHttpRequest_get_ResponseStream( req, &body2 ); 3811 ok( hr == S_OK, "got %08x\n", hr ); 3812 ok( V_VT( &body2 ) == VT_UNKNOWN, "got %08x\n", V_VT( &body2 ) ); 3813 ok( V_UNKNOWN( &body ) != V_UNKNOWN( &body2 ), "got same interface pointer\n" ); 3814 3815 hr = IUnknown_QueryInterface( V_UNKNOWN( &body2 ), &IID_IStream, (void **)&stream2 ); 3816 ok( hr == S_OK, "got %08x\n", hr ); 3817 ok( V_UNKNOWN( &body2 ) == (IUnknown *)stream2, "got different interface pointer\n" ); 3818 IStream_Release( stream2 ); 3819 3820 hr = VariantClear( &body ); 3821 ok( hr == S_OK, "got %08x\n", hr ); 3822 3823 hr = VariantClear( &body2 ); 3824 ok( hr == S_OK, "got %08x\n", hr ); 3825 3826 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_PROXY, proxy_server, bypass_list ); 3827 ok( hr == S_OK, "got %08x\n", hr ); 3828 3829 hr = IWinHttpRequest_SetProxy( req, HTTPREQUEST_PROXYSETTING_DIRECT, proxy_server, bypass_list ); 3830 ok( hr == S_OK, "got %08x\n", hr ); 3831 3832 hr = IWinHttpRequest_GetAllResponseHeaders( req, &headers ); 3833 ok( hr == S_OK, "got %08x\n", hr ); 3834 SysFreeString( headers ); 3835 3836 hr = IWinHttpRequest_GetResponseHeader( req, connection, &value ); 3837 ok( hr == S_OK, "got %08x\n", hr ); 3838 SysFreeString( value ); 3839 3840 hr = IWinHttpRequest_SetRequestHeader( req, date, today ); 3841 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_AFTER_SEND ), "got %08x\n", hr ); 3842 3843 hr = IWinHttpRequest_SetAutoLogonPolicy( req, AutoLogonPolicy_OnlyIfBypassProxy ); 3844 ok( hr == S_OK, "got %08x\n", hr ); 3845 3846 hr = IWinHttpRequest_Send( req, empty ); 3847 ok( hr == S_OK, "got %08x\n", hr ); 3848 3849 hr = IWinHttpRequest_Abort( req ); 3850 ok( hr == S_OK, "got %08x\n", hr ); 3851 3852 hr = IWinHttpRequest_Abort( req ); 3853 ok( hr == S_OK, "got %08x\n", hr ); 3854 3855 IWinHttpRequest_Release( req ); 3856 3857 pos.QuadPart = 0; 3858 hr = IStream_Seek( stream, pos, STREAM_SEEK_SET, NULL ); 3859 ok( hr == S_OK, "got %08x\n", hr ); 3860 3861 buf[0] = 0; 3862 count = 0xdeadbeef; 3863 hr = IStream_Read( stream, buf, 128, &count ); 3864 ok( hr == S_OK, "got %08x\n", hr ); 3865 ok( count != 0xdeadbeef, "count not set\n" ); 3866 ok( buf[0], "no data\n" ); 3867 IStream_Release( stream ); 3868 3869 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3870 ok( hr == S_OK, "got %08x\n", hr ); 3871 3872 V_VT( &async ) = VT_I4; 3873 V_I4( &async ) = 1; 3874 hr = IWinHttpRequest_Open( req, method, url, async ); 3875 ok( hr == S_OK, "got %08x\n", hr ); 3876 3877 hr = IWinHttpRequest_Send( req, empty ); 3878 ok( hr == S_OK, "got %08x\n", hr ); 3879 3880 hr = IWinHttpRequest_WaitForResponse( req, timeout, &succeeded ); 3881 ok( hr == S_OK, "got %08x\n", hr ); 3882 3883 IWinHttpRequest_Release( req ); 3884 3885 SysFreeString( method ); 3886 SysFreeString( url ); 3887 SysFreeString( username ); 3888 SysFreeString( password ); 3889 SysFreeString( connection ); 3890 SysFreeString( date ); 3891 SysFreeString( today ); 3892 VariantClear( &proxy_server ); 3893 VariantClear( &bypass_list ); 3894 3895 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3896 ok( hr == S_OK, "got %08x\n", hr ); 3897 3898 url = SysAllocString( test_winehq_https ); 3899 method = SysAllocString( method3W ); 3900 V_VT( &async ) = VT_BOOL; 3901 V_BOOL( &async ) = VARIANT_FALSE; 3902 hr = IWinHttpRequest_Open( req, method, url, async ); 3903 ok( hr == S_OK, "got %08x\n", hr ); 3904 SysFreeString( method ); 3905 SysFreeString( url ); 3906 3907 hr = IWinHttpRequest_Send( req, empty ); 3908 ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_INVALID_SERVER_RESPONSE )), "got %08x\n", hr ); 3909 if (hr == S_OK) 3910 { 3911 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3912 ok( hr == S_OK, "got %08x\n", hr ); 3913 ok( !memcmp(response, data_start, sizeof(data_start)), "got %s\n", wine_dbgstr_wn(response, 32) ); 3914 SysFreeString( response ); 3915 } 3916 3917 IWinHttpRequest_Release( req ); 3918 3919 hr = CoCreateInstance( &CLSID_WinHttpRequest, NULL, CLSCTX_INPROC_SERVER, &IID_IWinHttpRequest, (void **)&req ); 3920 ok( hr == S_OK, "got %08x\n", hr ); 3921 3922 sprintf( buf, "http://localhost:%d/auth", port ); 3923 MultiByteToWideChar( CP_ACP, 0, buf, -1, bufW, sizeof(bufW)/sizeof(bufW[0]) ); 3924 url = SysAllocString( bufW ); 3925 method = SysAllocString( method3W ); 3926 V_VT( &async ) = VT_BOOL; 3927 V_BOOL( &async ) = VARIANT_FALSE; 3928 hr = IWinHttpRequest_Open( req, method, url, async ); 3929 ok( hr == S_OK, "got %08x\n", hr ); 3930 SysFreeString( method ); 3931 SysFreeString( url ); 3932 3933 hr = IWinHttpRequest_get_Status( req, &status ); 3934 ok( hr == HRESULT_FROM_WIN32( ERROR_WINHTTP_CANNOT_CALL_BEFORE_SEND ), "got %08x\n", hr ); 3935 3936 V_VT( &data ) = VT_BSTR; 3937 V_BSTR( &data ) = SysAllocString( test_dataW ); 3938 hr = IWinHttpRequest_Send( req, data ); 3939 ok( hr == S_OK, "got %08x\n", hr ); 3940 SysFreeString( V_BSTR( &data ) ); 3941 3942 hr = IWinHttpRequest_get_ResponseText( req, &response ); 3943 ok( hr == S_OK, "got %08x\n", hr ); 3944 ok( !memcmp( response, unauthW, sizeof(unauthW) ), "got %s\n", wine_dbgstr_w(response) ); 3945 SysFreeString( response ); 3946 3947 status = 0xdeadbeef; 3948 hr = IWinHttpRequest_get_Status( req, &status ); 3949 ok( hr == S_OK, "got %08x\n", hr ); 3950 ok( status == HTTP_STATUS_DENIED, "got %d\n", status ); 3951 3952 IWinHttpRequest_Release( req ); 3953 3954 CoUninitialize(); 3955 } 3956 3957 static void request_get_property(IWinHttpRequest *request, int property, VARIANT *ret) 3958 { 3959 DISPPARAMS params; 3960 VARIANT arg; 3961 HRESULT hr; 3962 3963 memset(¶ms, 0, sizeof(params)); 3964 params.cNamedArgs = 0; 3965 params.rgdispidNamedArgs = NULL; 3966 params.cArgs = 1; 3967 params.rgvarg = &arg; 3968 VariantInit(&arg); 3969 V_VT(&arg) = VT_I4; 3970 V_I4(&arg) = property; 3971 VariantInit(ret); 3972 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 3973 DISPATCH_PROPERTYGET, ¶ms, ret, NULL, NULL); 3974 ok(hr == S_OK, "error %#x\n", hr); 3975 } 3976 3977 static void test_IWinHttpRequest_Invoke(void) 3978 { 3979 static const WCHAR utf8W[] = {'U','T','F','-','8',0}; 3980 static const WCHAR regid[] = {'W','i','n','H','t','t','p','.','W','i','n','H','t','t','p','R','e','q','u','e','s','t','.','5','.','1',0}; 3981 WCHAR openW[] = {'O','p','e','n',0}; 3982 WCHAR optionW[] = {'O','p','t','i','o','n',0}; 3983 OLECHAR *open = openW, *option = optionW; 3984 BSTR utf8; 3985 CLSID clsid; 3986 IWinHttpRequest *request; 3987 IDispatch *dispatch; 3988 DISPID id; 3989 DISPPARAMS params; 3990 VARIANT arg[3], ret; 3991 UINT err; 3992 BOOL bret; 3993 HRESULT hr; 3994 3995 CoInitialize(NULL); 3996 3997 hr = CLSIDFromProgID(regid, &clsid); 3998 ok(hr == S_OK, "CLSIDFromProgID error %#x\n", hr); 3999 bret = IsEqualIID(&clsid, &CLSID_WinHttpRequest); 4000 ok(bret || broken(!bret) /* win2003 */, "not expected %s\n", wine_dbgstr_guid(&clsid)); 4001 4002 hr = CoCreateInstance(&CLSID_WinHttpRequest, 0, CLSCTX_INPROC_SERVER, &IID_IUnknown, (void **)&request); 4003 ok(hr == S_OK, "error %#x\n", hr); 4004 4005 hr = IWinHttpRequest_QueryInterface(request, &IID_IDispatch, (void **)&dispatch); 4006 ok(hr == S_OK, "error %#x\n", hr); 4007 IDispatch_Release(dispatch); 4008 4009 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &open, 1, 0x0409, &id); 4010 ok(hr == S_OK, "error %#x\n", hr); 4011 ok(id == DISPID_HTTPREQUEST_OPEN, "expected DISPID_HTTPREQUEST_OPEN, got %u\n", id); 4012 4013 hr = IWinHttpRequest_GetIDsOfNames(request, &IID_NULL, &option, 1, 0x0409, &id); 4014 ok(hr == S_OK, "error %#x\n", hr); 4015 ok(id == DISPID_HTTPREQUEST_OPTION, "expected DISPID_HTTPREQUEST_OPTION, got %u\n", id); 4016 4017 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4018 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4019 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4020 4021 memset(¶ms, 0, sizeof(params)); 4022 params.cArgs = 2; 4023 params.cNamedArgs = 0; 4024 params.rgvarg = arg; 4025 V_VT(&arg[0]) = VT_I4; 4026 V_I4(&arg[0]) = 1252; 4027 V_VT(&arg[1]) = VT_R8; 4028 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4029 VariantInit(&ret); 4030 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 4031 DISPATCH_METHOD, ¶ms, NULL, NULL, &err); 4032 ok(hr == S_OK, "error %#x\n", hr); 4033 4034 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4035 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4036 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4037 4038 memset(¶ms, 0, sizeof(params)); 4039 params.cArgs = 2; 4040 params.cNamedArgs = 0; 4041 params.rgvarg = arg; 4042 V_VT(&arg[0]) = VT_I4; 4043 V_I4(&arg[0]) = 1252; 4044 V_VT(&arg[1]) = VT_R8; 4045 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4046 VariantInit(&ret); 4047 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 4048 DISPATCH_METHOD | DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, &err); 4049 ok(hr == S_OK, "error %#x\n", hr); 4050 4051 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4052 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4053 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4054 4055 memset(¶ms, 0, sizeof(params)); 4056 params.cArgs = 2; 4057 params.cNamedArgs = 0; 4058 params.rgvarg = arg; 4059 V_VT(&arg[0]) = VT_I4; 4060 V_I4(&arg[0]) = 1252; 4061 V_VT(&arg[1]) = VT_R8; 4062 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4063 VariantInit(&ret); 4064 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 4065 DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, &err); 4066 ok(hr == S_OK, "error %#x\n", hr); 4067 4068 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4069 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4070 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret)); 4071 4072 memset(¶ms, 0, sizeof(params)); 4073 params.cArgs = 2; 4074 params.cNamedArgs = 0; 4075 params.rgvarg = arg; 4076 V_VT(&arg[0]) = VT_BSTR; 4077 utf8 = SysAllocString(utf8W); 4078 V_BSTR(&arg[0]) = utf8; 4079 V_VT(&arg[1]) = VT_R8; 4080 V_R8(&arg[1]) = 2.0; /* WinHttpRequestOption_URLCodePage */ 4081 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, NULL, NULL, &err); 4082 ok(hr == S_OK, "error %#x\n", hr); 4083 4084 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4085 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4086 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret)); 4087 4088 VariantInit(&ret); 4089 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &ret, NULL, &err); 4090 ok(hr == S_OK, "error %#x\n", hr); 4091 4092 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4093 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4094 ok(V_I4(&ret) == 1252, "expected 1252, got %d\n", V_I4(&ret)); 4095 4096 VariantInit(&ret); 4097 hr = IWinHttpRequest_Invoke(request, id, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4098 ok(hr == S_OK, "error %#x\n", hr); 4099 4100 request_get_property(request, WinHttpRequestOption_URLCodePage, &ret); 4101 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4102 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4103 4104 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL); 4105 ok(hr == S_OK, "error %#x\n", hr); 4106 4107 hr = IWinHttpRequest_Invoke(request, 255, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, NULL, NULL, NULL); 4108 ok(hr == DISP_E_MEMBERNOTFOUND, "error %#x\n", hr); 4109 4110 VariantInit(&ret); 4111 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4112 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr); 4113 4114 VariantInit(&ret); 4115 if (0) /* crashes */ 4116 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, NULL, &ret, NULL, &err); 4117 4118 params.cArgs = 1; 4119 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4120 ok(hr == DISP_E_TYPEMISMATCH, "error %#x\n", hr); 4121 4122 VariantInit(&arg[2]); 4123 params.cArgs = 3; 4124 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYPUT, ¶ms, &ret, NULL, &err); 4125 todo_wine 4126 ok(hr == S_OK, "error %#x\n", hr); 4127 4128 VariantInit(&arg[0]); 4129 VariantInit(&arg[1]); 4130 VariantInit(&arg[2]); 4131 4132 params.cArgs = 1; 4133 V_VT(&arg[0]) = VT_I4; 4134 V_I4(&arg[0]) = WinHttpRequestOption_URLCodePage; 4135 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4136 ok(hr == S_OK, "error %#x\n", hr); 4137 4138 V_VT(&ret) = 0xdead; 4139 V_I4(&ret) = 0xbeef; 4140 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, ¶ms, &ret, NULL, NULL); 4141 ok(hr == S_OK, "error %#x\n", hr); 4142 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4143 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4144 4145 V_VT(&ret) = 0xdead; 4146 V_I4(&ret) = 0xbeef; 4147 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD, ¶ms, &ret, NULL, NULL); 4148 ok(hr == S_OK, "error %#x\n", hr); 4149 ok(V_VT(&ret) == VT_I4, "expected VT_I4, got %d\n", V_VT(&ret)); 4150 ok(V_I4(&ret) == CP_UTF8, "expected CP_UTF8, got %d\n", V_I4(&ret)); 4151 4152 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_METHOD|DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4153 ok(hr == S_OK, "error %#x\n", hr); 4154 4155 V_VT(&ret) = 0xdead; 4156 V_I4(&ret) = 0xbeef; 4157 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, ¶ms, &ret, NULL, NULL); 4158 ok(hr == S_OK, "error %#x\n", hr); 4159 ok(V_VT(&ret) == VT_EMPTY, "expected VT_EMPTY, got %d\n", V_VT(&ret)); 4160 ok(V_I4(&ret) == 0xbeef || V_I4(&ret) == 0 /* Win8 */, "expected 0xdead, got %d\n", V_I4(&ret)); 4161 4162 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, 0, ¶ms, NULL, NULL, NULL); 4163 ok(hr == S_OK, "error %#x\n", hr); 4164 4165 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_IUnknown, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4166 ok(hr == DISP_E_UNKNOWNINTERFACE, "error %#x\n", hr); 4167 4168 params.cArgs = 2; 4169 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4170 todo_wine 4171 ok(hr == S_OK, "error %#x\n", hr); 4172 4173 params.cArgs = 0; 4174 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_OPTION, &IID_NULL, 0, DISPATCH_PROPERTYGET, ¶ms, NULL, NULL, NULL); 4175 ok(hr == DISP_E_PARAMNOTFOUND, "error %#x\n", hr); 4176 4177 SysFreeString(utf8); 4178 4179 params.cArgs = 1; 4180 V_VT(&arg[0]) = VT_I4; 4181 V_I4(&arg[0]) = AutoLogonPolicy_Never; 4182 VariantInit(&ret); 4183 hr = IWinHttpRequest_Invoke(request, DISPID_HTTPREQUEST_SETAUTOLOGONPOLICY, &IID_NULL, 0, 4184 DISPATCH_METHOD, ¶ms, &ret, NULL, NULL); 4185 ok(hr == S_OK, "error %#x\n", hr); 4186 4187 IWinHttpRequest_Release(request); 4188 4189 CoUninitialize(); 4190 } 4191 4192 static void test_WinHttpDetectAutoProxyConfigUrl(void) 4193 { 4194 BOOL ret; 4195 WCHAR *url; 4196 DWORD error; 4197 4198 if (0) /* crashes on some win2k systems */ 4199 { 4200 SetLastError(0xdeadbeef); 4201 ret = WinHttpDetectAutoProxyConfigUrl( 0, NULL ); 4202 error = GetLastError(); 4203 ok( !ret, "expected failure\n" ); 4204 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4205 } 4206 url = NULL; 4207 SetLastError(0xdeadbeef); 4208 ret = WinHttpDetectAutoProxyConfigUrl( 0, &url ); 4209 error = GetLastError(); 4210 ok( !ret, "expected failure\n" ); 4211 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4212 4213 if (0) /* crashes on some win2k systems */ 4214 { 4215 SetLastError(0xdeadbeef); 4216 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, NULL ); 4217 error = GetLastError(); 4218 ok( !ret, "expected failure\n" ); 4219 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4220 } 4221 url = (WCHAR *)0xdeadbeef; 4222 SetLastError(0xdeadbeef); 4223 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DNS_A, &url ); 4224 error = GetLastError(); 4225 if (!ret) 4226 { 4227 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error ); 4228 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url ); 4229 } 4230 else 4231 { 4232 trace("%s\n", wine_dbgstr_w(url)); 4233 GlobalFree( url ); 4234 } 4235 4236 url = (WCHAR *)0xdeadbeef; 4237 SetLastError(0xdeadbeef); 4238 ret = WinHttpDetectAutoProxyConfigUrl( WINHTTP_AUTO_DETECT_TYPE_DHCP, &url ); 4239 error = GetLastError(); 4240 if (!ret) 4241 { 4242 ok( error == ERROR_WINHTTP_AUTODETECTION_FAILED, "got %u\n", error ); 4243 ok( !url || broken(url == (WCHAR *)0xdeadbeef), "got %p\n", url ); 4244 } 4245 else 4246 { 4247 ok( error == ERROR_SUCCESS, "got %u\n", error ); 4248 trace("%s\n", wine_dbgstr_w(url)); 4249 GlobalFree( url ); 4250 } 4251 } 4252 4253 static void test_WinHttpGetIEProxyConfigForCurrentUser(void) 4254 { 4255 BOOL ret; 4256 DWORD error; 4257 WINHTTP_CURRENT_USER_IE_PROXY_CONFIG cfg; 4258 4259 memset( &cfg, 0, sizeof(cfg) ); 4260 4261 SetLastError(0xdeadbeef); 4262 ret = WinHttpGetIEProxyConfigForCurrentUser( NULL ); 4263 error = GetLastError(); 4264 ok( !ret, "expected failure\n" ); 4265 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4266 4267 SetLastError(0xdeadbeef); 4268 ret = WinHttpGetIEProxyConfigForCurrentUser( &cfg ); 4269 error = GetLastError(); 4270 ok( ret, "expected success\n" ); 4271 ok( error == ERROR_SUCCESS || broken(error == ERROR_NO_TOKEN) /* < win7 */, "got %u\n", error ); 4272 4273 trace("IEProxy.AutoDetect=%d\n", cfg.fAutoDetect); 4274 trace("IEProxy.AutoConfigUrl=%s\n", wine_dbgstr_w(cfg.lpszAutoConfigUrl)); 4275 trace("IEProxy.Proxy=%s\n", wine_dbgstr_w(cfg.lpszProxy)); 4276 trace("IEProxy.ProxyBypass=%s\n", wine_dbgstr_w(cfg.lpszProxyBypass)); 4277 GlobalFree( cfg.lpszAutoConfigUrl ); 4278 GlobalFree( cfg.lpszProxy ); 4279 GlobalFree( cfg.lpszProxyBypass ); 4280 } 4281 4282 static void test_WinHttpGetProxyForUrl(void) 4283 { 4284 static const WCHAR urlW[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0}; 4285 static const WCHAR wpadW[] = {'h','t','t','p',':','/','/','w','p','a','d','/','w','p','a','d','.','d','a','t',0}; 4286 static const WCHAR emptyW[] = {0}; 4287 BOOL ret; 4288 DWORD error; 4289 HINTERNET session; 4290 WINHTTP_AUTOPROXY_OPTIONS options; 4291 WINHTTP_PROXY_INFO info; 4292 4293 memset( &options, 0, sizeof(options) ); 4294 4295 SetLastError(0xdeadbeef); 4296 ret = WinHttpGetProxyForUrl( NULL, NULL, NULL, NULL ); 4297 error = GetLastError(); 4298 ok( !ret, "expected failure\n" ); 4299 ok( error == ERROR_INVALID_HANDLE, "got %u\n", error ); 4300 4301 session = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 ); 4302 ok( session != NULL, "failed to open session %u\n", GetLastError() ); 4303 4304 SetLastError(0xdeadbeef); 4305 ret = WinHttpGetProxyForUrl( session, NULL, NULL, NULL ); 4306 error = GetLastError(); 4307 ok( !ret, "expected failure\n" ); 4308 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4309 4310 SetLastError(0xdeadbeef); 4311 ret = WinHttpGetProxyForUrl( session, emptyW, NULL, NULL ); 4312 error = GetLastError(); 4313 ok( !ret, "expected failure\n" ); 4314 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4315 4316 SetLastError(0xdeadbeef); 4317 ret = WinHttpGetProxyForUrl( session, urlW, NULL, NULL ); 4318 error = GetLastError(); 4319 ok( !ret, "expected failure\n" ); 4320 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4321 4322 SetLastError(0xdeadbeef); 4323 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4324 error = GetLastError(); 4325 ok( !ret, "expected failure\n" ); 4326 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4327 4328 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; 4329 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; 4330 4331 SetLastError(0xdeadbeef); 4332 ret = WinHttpGetProxyForUrl( session, urlW, &options, NULL ); 4333 error = GetLastError(); 4334 ok( !ret, "expected failure\n" ); 4335 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4336 4337 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; 4338 options.dwAutoDetectFlags = 0; 4339 4340 SetLastError(0xdeadbeef); 4341 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4342 error = GetLastError(); 4343 ok( !ret, "expected failure\n" ); 4344 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4345 4346 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT | WINHTTP_AUTOPROXY_CONFIG_URL; 4347 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; 4348 4349 SetLastError(0xdeadbeef); 4350 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4351 error = GetLastError(); 4352 ok( !ret, "expected failure\n" ); 4353 ok( error == ERROR_INVALID_PARAMETER, "got %u\n", error ); 4354 4355 options.dwFlags = WINHTTP_AUTOPROXY_AUTO_DETECT; 4356 options.dwAutoDetectFlags = WINHTTP_AUTO_DETECT_TYPE_DNS_A; 4357 4358 memset( &info, 0, sizeof(info) ); 4359 SetLastError(0xdeadbeef); 4360 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4361 error = GetLastError(); 4362 if (ret) 4363 { 4364 ok( error == ERROR_SUCCESS, "got %u\n", error ); 4365 trace("Proxy.AccessType=%u\n", info.dwAccessType); 4366 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy)); 4367 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass)); 4368 GlobalFree( info.lpszProxy ); 4369 GlobalFree( info.lpszProxyBypass ); 4370 } 4371 4372 options.dwFlags = WINHTTP_AUTOPROXY_CONFIG_URL; 4373 options.dwAutoDetectFlags = 0; 4374 options.lpszAutoConfigUrl = wpadW; 4375 4376 memset( &info, 0, sizeof(info) ); 4377 ret = WinHttpGetProxyForUrl( session, urlW, &options, &info ); 4378 if (ret) 4379 { 4380 trace("Proxy.AccessType=%u\n", info.dwAccessType); 4381 trace("Proxy.Proxy=%s\n", wine_dbgstr_w(info.lpszProxy)); 4382 trace("Proxy.ProxyBypass=%s\n", wine_dbgstr_w(info.lpszProxyBypass)); 4383 GlobalFree( info.lpszProxy ); 4384 GlobalFree( info.lpszProxyBypass ); 4385 } 4386 WinHttpCloseHandle( session ); 4387 } 4388 4389 static void test_chunked_read(void) 4390 { 4391 static const WCHAR verb[] = {'/','t','e','s','t','c','h','u','n','k','e','d',0}; 4392 static const WCHAR chunked[] = {'c','h','u','n','k','e','d',0}; 4393 WCHAR header[32]; 4394 DWORD len, err; 4395 HINTERNET ses, con = NULL, req = NULL; 4396 BOOL ret; 4397 4398 trace( "starting chunked read test\n" ); 4399 4400 ses = WinHttpOpen( test_useragent, 0, NULL, NULL, 0 ); 4401 ok( ses != NULL, "WinHttpOpen failed with error %u\n", GetLastError() ); 4402 if (!ses) goto done; 4403 4404 con = WinHttpConnect( ses, test_winehq, 0, 0 ); 4405 ok( con != NULL, "WinHttpConnect failed with error %u\n", GetLastError() ); 4406 if (!con) goto done; 4407 4408 req = WinHttpOpenRequest( con, NULL, verb, NULL, NULL, NULL, 0 ); 4409 ok( req != NULL, "WinHttpOpenRequest failed with error %u\n", GetLastError() ); 4410 if (!req) goto done; 4411 4412 ret = WinHttpSendRequest( req, NULL, 0, NULL, 0, 0, 0 ); 4413 err = GetLastError(); 4414 if (!ret && (err == ERROR_WINHTTP_CANNOT_CONNECT || err == ERROR_WINHTTP_TIMEOUT)) 4415 { 4416 skip("connection failed, skipping\n"); 4417 goto done; 4418 } 4419 ok( ret, "WinHttpSendRequest failed with error %u\n", GetLastError() ); 4420 4421 ret = WinHttpReceiveResponse( req, NULL ); 4422 ok( ret, "WinHttpReceiveResponse failed with error %u\n", GetLastError() ); 4423 4424 header[0] = 0; 4425 len = sizeof(header); 4426 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_TRANSFER_ENCODING, NULL, header, &len, 0 ); 4427 ok( ret, "failed to get TRANSFER_ENCODING header (error %u)\n", GetLastError() ); 4428 ok( !lstrcmpW( header, chunked ), "wrong transfer encoding %s\n", wine_dbgstr_w(header) ); 4429 trace( "transfer encoding: %s\n", wine_dbgstr_w(header) ); 4430 4431 header[0] = 0; 4432 len = sizeof(header); 4433 SetLastError( 0xdeadbeef ); 4434 ret = WinHttpQueryHeaders( req, WINHTTP_QUERY_CONTENT_LENGTH, NULL, &header, &len, 0 ); 4435 ok( !ret, "unexpected CONTENT_LENGTH header %s\n", wine_dbgstr_w(header) ); 4436 ok( GetLastError() == ERROR_WINHTTP_HEADER_NOT_FOUND, "wrong error %u\n", GetLastError() ); 4437 4438 trace( "entering query loop\n" ); 4439 for (;;) 4440 { 4441 len = 0xdeadbeef; 4442 ret = WinHttpQueryDataAvailable( req, &len ); 4443 ok( ret, "WinHttpQueryDataAvailable failed with error %u\n", GetLastError() ); 4444 if (ret) ok( len != 0xdeadbeef, "WinHttpQueryDataAvailable return wrong length\n" ); 4445 trace( "got %u available\n", len ); 4446 if (len) 4447 { 4448 DWORD bytes_read; 4449 char *buf = HeapAlloc( GetProcessHeap(), 0, len + 1 ); 4450 4451 ret = WinHttpReadData( req, buf, len, &bytes_read ); 4452 4453 buf[bytes_read] = 0; 4454 trace( "WinHttpReadData -> %d %u\n", ret, bytes_read ); 4455 ok( len == bytes_read, "only got %u of %u available\n", bytes_read, len ); 4456 ok( buf[bytes_read - 1] == '\n', "received partial line '%s'\n", buf ); 4457 4458 HeapFree( GetProcessHeap(), 0, buf ); 4459 if (!bytes_read) break; 4460 } 4461 if (!len) break; 4462 } 4463 trace( "done\n" ); 4464 4465 done: 4466 if (req) WinHttpCloseHandle( req ); 4467 if (con) WinHttpCloseHandle( con ); 4468 if (ses) WinHttpCloseHandle( ses ); 4469 } 4470 4471 START_TEST (winhttp) 4472 { 4473 static const WCHAR basicW[] = {'/','b','a','s','i','c',0}; 4474 static const WCHAR quitW[] = {'/','q','u','i','t',0}; 4475 struct server_info si; 4476 HANDLE thread; 4477 DWORD ret; 4478 4479 test_OpenRequest(); 4480 test_SendRequest(); 4481 test_WinHttpTimeFromSystemTime(); 4482 test_WinHttpTimeToSystemTime(); 4483 test_WinHttpAddHeaders(); 4484 test_secure_connection(); 4485 test_request_parameter_defaults(); 4486 test_QueryOption(); 4487 test_set_default_proxy_config(); 4488 test_empty_headers_param(); 4489 test_Timeouts(); 4490 test_resolve_timeout(); 4491 test_credentials(); 4492 test_IWinHttpRequest_Invoke(); 4493 test_WinHttpDetectAutoProxyConfigUrl(); 4494 test_WinHttpGetIEProxyConfigForCurrentUser(); 4495 test_WinHttpGetProxyForUrl(); 4496 test_chunked_read(); 4497 4498 si.event = CreateEventW(NULL, 0, 0, NULL); 4499 si.port = 7532; 4500 4501 thread = CreateThread(NULL, 0, server_thread, (LPVOID)&si, 0, NULL); 4502 ok(thread != NULL, "failed to create thread %u\n", GetLastError()); 4503 4504 ret = WaitForSingleObject(si.event, 10000); 4505 ok(ret == WAIT_OBJECT_0, "failed to start winhttp test server %u\n", GetLastError()); 4506 if (ret != WAIT_OBJECT_0) 4507 { 4508 CloseHandle(thread); 4509 return; 4510 } 4511 4512 test_IWinHttpRequest(si.port); 4513 test_connection_info(si.port); 4514 test_basic_request(si.port, NULL, basicW); 4515 test_no_headers(si.port); 4516 test_no_content(si.port); 4517 test_head_request(si.port); 4518 test_not_modified(si.port); 4519 test_basic_authentication(si.port); 4520 test_multi_authentication(si.port); 4521 test_large_data_authentication(si.port); 4522 test_bad_header(si.port); 4523 test_multiple_reads(si.port); 4524 test_cookies(si.port); 4525 4526 /* send the basic request again to shutdown the server thread */ 4527 test_basic_request(si.port, NULL, quitW); 4528 4529 WaitForSingleObject(thread, 3000); 4530 CloseHandle(thread); 4531 } 4532