/* This file is part of TON Blockchain Library. TON Blockchain Library is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 2 of the License, or (at your option) any later version. TON Blockchain Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with TON Blockchain Library. If not, see . Copyright 2019-2020 Telegram Systems LLP */ #pragma once #include "http.h" #include "http-connection.h" #include "http-client.h" #include namespace ton { namespace http { class HttpOutboundConnection : public HttpConnection { public: struct Query { std::unique_ptr request; std::shared_ptr payload; td::Timestamp timeout; td::Promise, std::shared_ptr>> promise; }; HttpOutboundConnection(td::SocketFd fd, std::shared_ptr http_callback) : HttpConnection(std::move(fd), nullptr, false), http_callback_(std::move(http_callback)) { } td::Status receive_eof() override { found_eof_ = true; if (reading_payload_) { if (reading_payload_->payload_type() != HttpPayload::PayloadType::pt_eof && reading_payload_->payload_type() != HttpPayload::PayloadType::pt_tunnel) { return td::Status::Error("unexpected EOF"); } else { LOG(INFO) << "stopping (EOF payload)"; reading_payload_->complete_parse(); stop(); return td::Status::OK(); } } else { LOG(INFO) << "stopping (no req)"; stop(); return td::Status::OK(); } } void alarm() override { LOG(INFO) << "closing outbound HTTP connection because of request timeout"; if (promise_) { answer_error(HttpStatusCode::status_gateway_timeout, "", std::move(promise_)); } stop(); } void start_up() override { class Cb : public HttpConnection::Callback { public: Cb(std::shared_ptr callback) : callback_(std::move(callback)) { } void on_ready(td::actor::ActorId conn) { callback_->on_ready(); } void on_close(td::actor::ActorId conn) { callback_->on_stop_ready(); } private: std::shared_ptr callback_; }; callback_ = std::make_unique(std::move(http_callback_)); HttpConnection::start_up(); } td::Status receive(td::ChainBufferReader &input) override; void send_query(std::unique_ptr request, std::shared_ptr payload, td::Timestamp timeout, td::Promise, std::shared_ptr>> promise); void send_next_query(); void payload_read() override { reading_payload_ = nullptr; if (!close_after_read_) { alarm_timestamp() = td::Timestamp::never(); send_next_query(); } else { stop(); } } void payload_written() override { writing_payload_ = nullptr; } private: std::shared_ptr http_callback_; td::Promise, std::shared_ptr>> promise_; bool force_no_payload_; bool keep_alive_; std::unique_ptr cur_response_; std::string cur_line_; std::list next_; }; } // namespace http } // namespace ton