| 577 | } |
| 578 | |
| 579 | void ClientNetworkContentSocketHandler::OnReceiveData(std::unique_ptr<char[]> data, size_t length) |
| 580 | { |
| 581 | assert(data.get() == nullptr || length != 0); |
| 582 | |
| 583 | /* Ignore any latent data coming from a connection we closed. */ |
| 584 | if (this->http_response_index == -2) { |
| 585 | return; |
| 586 | } |
| 587 | |
| 588 | if (this->http_response_index == -1) { |
| 589 | if (data != nullptr) { |
| 590 | /* Append the rest of the response. */ |
| 591 | this->http_response.insert(this->http_response.end(), data.get(), data.get() + length); |
| 592 | return; |
| 593 | } else { |
| 594 | /* Make sure the response is properly terminated. */ |
| 595 | this->http_response.push_back('\0'); |
| 596 | |
| 597 | /* And prepare for receiving the rest of the data. */ |
| 598 | this->http_response_index = 0; |
| 599 | } |
| 600 | } |
| 601 | |
| 602 | if (data != nullptr) { |
| 603 | /* We have data, so write it to the file. */ |
| 604 | if (fwrite(data.get(), 1, length, *this->cur_file) != length) { |
| 605 | /* Writing failed somehow, let try via the old method. */ |
| 606 | this->OnFailure(); |
| 607 | } else { |
| 608 | /* Just received the data. */ |
| 609 | this->OnDownloadProgress(*this->cur_info, (int)length); |
| 610 | } |
| 611 | |
| 612 | /* Nothing more to do now. */ |
| 613 | return; |
| 614 | } |
| 615 | |
| 616 | if (this->cur_file.has_value()) { |
| 617 | /* We've finished downloading a file. */ |
| 618 | this->AfterDownload(); |
| 619 | } |
| 620 | |
| 621 | if ((uint)this->http_response_index >= this->http_response.size()) { |
| 622 | /* It's not a real failure, but if there's |
| 623 | * nothing more to download it helps with |
| 624 | * cleaning up the stuff we allocated. */ |
| 625 | this->OnFailure(); |
| 626 | return; |
| 627 | } |
| 628 | |
| 629 | /* When we haven't opened a file this must be our first packet with metadata. */ |
| 630 | this->cur_info = std::make_unique<ContentInfo>(); |
| 631 | |
| 632 | try { |
| 633 | for (;;) { |
| 634 | std::string_view buffer{this->http_response.data(), this->http_response.size()}; |
| 635 | buffer.remove_prefix(this->http_response_index); |
| 636 | auto len = buffer.find('\n'); |
nothing calls this directly
no test coverage detected