| 404 | |
| 405 | |
| 406 | std::unique_ptr<ReadBuffer> ReadWriteBufferFromHTTP::initialize() |
| 407 | { |
| 408 | Poco::Net::HTTPResponse response; |
| 409 | |
| 410 | std::optional<HTTPRange> range; |
| 411 | if (withPartialContent()) |
| 412 | range = HTTPRange{getOffset(), read_range.end}; |
| 413 | |
| 414 | auto result = callWithRedirects(response, method, range); |
| 415 | |
| 416 | if (range.has_value() && response.getStatus() != Poco::Net::HTTPResponse::HTTPStatus::HTTP_PARTIAL_CONTENT) |
| 417 | { |
| 418 | /// Having `200 OK` instead of `206 Partial Content` is acceptable in case we retried with range.begin == 0. |
| 419 | if (getOffset() != 0) |
| 420 | { |
| 421 | /// Retry 200 OK |
| 422 | if (response.getStatus() == Poco::Net::HTTPResponse::HTTPStatus::HTTP_OK) |
| 423 | { |
| 424 | String explanation = fmt::format( |
| 425 | "Cannot read with range: [{}, {}] (response status: {}, reason: {}), will retry", |
| 426 | getOffset(), read_range.end ? toString(*read_range.end) : "-", |
| 427 | toString(response.getStatus()), response.getReason()); |
| 428 | |
| 429 | /// it is retriable error |
| 430 | throw HTTPException( |
| 431 | ErrorCodes::HTTP_RANGE_NOT_SATISFIABLE, |
| 432 | current_uri.toString(), |
| 433 | Poco::Net::HTTPResponse::HTTP_REQUESTED_RANGE_NOT_SATISFIABLE, |
| 434 | response.getReason(), |
| 435 | explanation); |
| 436 | } |
| 437 | throw Exception( |
| 438 | ErrorCodes::HTTP_RANGE_NOT_SATISFIABLE, |
| 439 | "Cannot read with range: [{}, {}] (response status: {}, reason: {})", |
| 440 | getOffset(), |
| 441 | read_range.end ? toString(*read_range.end) : "-", |
| 442 | toString(response.getStatus()), |
| 443 | response.getReason()); |
| 444 | } |
| 445 | if (read_range.end) |
| 446 | { |
| 447 | /// We could have range.begin == 0 and range.end != 0 in case of DiskWeb and failing to read with partial content |
| 448 | /// will affect only performance, so a warning is enough. |
| 449 | LOG_WARNING(log, "Unable to read with range header: [{}, {}]", read_range.begin.value_or(0), *read_range.end); |
| 450 | } |
| 451 | } |
| 452 | |
| 453 | response.getCookies(cookies); |
| 454 | response.getHeaders(response_headers); |
| 455 | content_encoding = response.get("Content-Encoding", ""); |
| 456 | |
| 457 | // Remember file size. It'll be used to report eof in next nextImpl() call. |
| 458 | if (!read_range.end && response.hasContentLength()) |
| 459 | file_info = parseFileInfo(response, range.has_value() ? getOffset() : 0); |
| 460 | |
| 461 | return std::move(result).transformToReadBuffer(use_external_buffer ? 0 : buffer_size); |
| 462 | } |
| 463 |
nothing calls this directly
no test coverage detected