| 495 | |
| 496 | namespace { |
| 497 | Error _wget_sync(const String &p_url, Ref<FileAccess> response, int retries, const Vector<String> &extra_headers, float *p_progress, bool *p_cancelled, int64_t *r_size) { |
| 498 | #define WGET_CANCELLED_CHECK() \ |
| 499 | if (p_cancelled && *p_cancelled) { \ |
| 500 | return ERR_SKIP; \ |
| 501 | } |
| 502 | WGET_CANCELLED_CHECK(); |
| 503 | Ref<HTTPClient> client = HTTPClient::create(); |
| 504 | client->set_blocking_mode(true); |
| 505 | Error err; |
| 506 | String request_url = p_url; |
| 507 | auto connect_to_host_and_request = [&](const String &url) { |
| 508 | WGET_CANCELLED_CHECK(); |
| 509 | bool is_https = url.begins_with("https://"); |
| 510 | String host = url.get_slice("://", 1).get_slice("/", 0); |
| 511 | String thingy = (is_https ? "https://" : "http://") + host; |
| 512 | Error connect_err = client->connect_to_host(thingy, is_https ? 443 : 80); |
| 513 | ERR_FAIL_COND_V_MSG(connect_err, connect_err, "Failed to connect to host " + url); |
| 514 | while (client->get_status() == HTTPClient::STATUS_RESOLVING || client->get_status() == HTTPClient::STATUS_CONNECTING) { |
| 515 | WGET_CANCELLED_CHECK(); |
| 516 | err = client->poll(); |
| 517 | if (err) { |
| 518 | return err; |
| 519 | } |
| 520 | } |
| 521 | if (client->get_status() != HTTPClient::STATUS_CONNECTED) { |
| 522 | return ERR_CANT_CONNECT; |
| 523 | } |
| 524 | WGET_CANCELLED_CHECK(); |
| 525 | Error request_err = client->request(HTTPClient::METHOD_GET, url, extra_headers, nullptr, 0); |
| 526 | ERR_FAIL_COND_V_MSG(request_err, request_err, "Failed to connect to host " + url); |
| 527 | return OK; |
| 528 | }; |
| 529 | bool done = false; |
| 530 | bool got_response = false; |
| 531 | List<String> response_headers; |
| 532 | int redirections = 0; |
| 533 | int response_code = 0; |
| 534 | int response_body_length = 0; |
| 535 | auto _handle_response = [&]() -> Error { |
| 536 | WGET_CANCELLED_CHECK(); |
| 537 | if (!client->has_response()) { |
| 538 | return ERR_BUG; |
| 539 | } |
| 540 | |
| 541 | got_response = true; |
| 542 | response_code = client->get_response_code(); |
| 543 | List<String> rheaders; |
| 544 | client->get_response_headers(&rheaders); |
| 545 | response_headers.clear(); |
| 546 | |
| 547 | for (const String &E : rheaders) { |
| 548 | response_headers.push_back(E); |
| 549 | } |
| 550 | if (response_code == 404) { |
| 551 | return ERR_FILE_NOT_FOUND; |
| 552 | } |
| 553 | if (response_code == 403) { |
| 554 | return ERR_UNAUTHORIZED; |