diff --git a/docker/DockerfileDeps b/docker/DockerfileDeps index f6724bba226f23d102d6cdd6a9007a1194dd1643..04906696d2efbb6d53a336a46f57c6badc8ebf8b 100644 --- a/docker/DockerfileDeps +++ b/docker/DockerfileDeps @@ -43,3 +43,14 @@ RUN wget https://github.com/msgpack/msgpack-c/releases/download/cpp-2.1.5/msgpac && cmake -DMSGPACK_CXX11=ON -DMSGPACK_BUILD_EXAMPLES=OFF -DCMAKE_INSTALL_PREFIX=/usr .. \ && make -j8 && make install \ && cd ../.. && rm -rf msgpack-2.1.5 msgpack-2.1.5.tar.gz + +RUN git clone https://github.com/binarytrails/opendht.git \ + && cd opendht && git checkout proxy_restinio \ + && mkdir build && cd build \ + && cmake .. -DCMAKE_INSTALL_PREFIX=/usr -DOPENDHT_PYTHON=On -DOPENDHT_LTO=On \ + -DOPENDHT_TESTS=ON -DOPENDHT_PROXY_SERVER=ON -DOPENDHT_PROXY_CLIENT=ON \ + -DOPENDHT_PROXY_SERVER_IDENTITY=ON -DOPENDHT_DOCUMENTATION=Off \ + -DOPENDHT_PUSH_NOTIFICATIONS=ON -DCMAKE_BUILD_TYPE=Debug \ + && make -j8 && make install \ + && ./opendht_unit_tests \ + && cd ../../ && rm -rf opendht diff --git a/docker/DockerfileDepsLlvm b/docker/DockerfileDepsLlvm index 9c5b59063686c08391e29c955949ce4dd6391012..0064b774f22d7a8e0796f35e11edf3d34c3f20cc 100644 --- a/docker/DockerfileDepsLlvm +++ b/docker/DockerfileDepsLlvm @@ -8,6 +8,8 @@ ENV CC cc ENV CXX c++ #patch for https://github.com/Stiffstream/restinio-conan-example/issues/2 +RUN apt-get update && apt-get install -y \ + python3-pip libasio-dev RUN pip3 install --upgrade cmake #install conan & add restinio remotes RUN pip3 install conan && \ @@ -20,14 +22,19 @@ COPY conan/restinio/conanfile.py restinio-conan/conanfile.py #build restinio from source RUN echo "*** Installing RESTinio & dependencies ***" \ && cd restinio-conan \ - && conan source . \ + && conan source . \ && conan install -o restinio:boost_libs=none --build=missing . \ && conan package . -pf /usr/local \ && cd ../ && rm -rf restinio* +#installing dependencies +RUN echo "*** Installing asio & fmt dependencies ***" \ + && cp -r ~/.conan/data/asio/*/bincrafters/stable/package/*/include/* /usr/local/include/ \ + && cp -r ~/.conan/data/fmt/*/bincrafters/stable/package/*/lib/* /usr/local/lib/ \ + && cp -r ~/.conan/data/fmt/*/bincrafters/stable/package/*/include/* /usr/local/include/ #build http_parser fork -RUN echo "*** Building http_parser for custom HTTP methods ***" \ +RUN echo "*** Building http_parser dependency for custom HTTP methods ***" \ && git clone https://github.com/eao197/http-parser.git \ - && cd http-parser && make && make install PREFIX=/usr \ + && cd http-parser && make -j8 && make install PREFIX=/usr \ && cd ../ && rm -rf restinio-conan/ #build msgpack from source diff --git a/include/opendht/http.h b/include/opendht/http.h index da1f217c55329af360523a963f9d1cf2b17d99bd..8c827a7f3d82d3acd4f9f0b31d74d466543a8c8b 100644 --- a/include/opendht/http.h +++ b/include/opendht/http.h @@ -42,8 +42,11 @@ public: void close(); private: + friend class Client; + uint16_t id_; asio::ip::tcp::socket socket_; + asio::streambuf response_stream_; }; /** @@ -112,6 +115,11 @@ private: std::shared_ptr<http_parser_settings> parser_s = nullptr, std::shared_ptr<Connection> conn = nullptr); + void handle_response(const asio::error_code &ec, + std::shared_ptr<http_parser> parser = nullptr, + std::shared_ptr<http_parser_settings> parser_s = nullptr, + std::shared_ptr<Connection> conn = nullptr); + uint16_t port_; asio::ip::address addr_; asio::ip::tcp::resolver resolver_; diff --git a/src/http.cpp b/src/http.cpp index e01712df31cdd2ea05fa76320784d720a7672062..405e4bd01bbd8702349274835075cd18626b1e79 100644 --- a/src/http.cpp +++ b/src/http.cpp @@ -256,30 +256,36 @@ Client::async_request(std::string request, } // read response logger_->d("[connection:%i] response read", conn->id()); - asio::streambuf resp_s; - auto& socket = conn->get_socket(); - asio::read_until(socket, resp_s, "\r\n\r\n"); - - while(asio::read(socket, resp_s, asio::transfer_at_least(1), ec)){ - std::ostringstream str_s; - str_s << &resp_s; - // parse the request - http_parser_execute(parser.get(), parser_s.get(), - str_s.str().c_str(), str_s.str().size()); - // detect parsing errors - if (HPE_OK != parser->http_errno && HPE_PAUSED != parser->http_errno){ - auto err = HTTP_PARSER_ERRNO(parser.get()); - if (logger_) - logger_->e("[connection:%i] error parsing: %s", - conn->id(), http_errno_name(err)); - } - } - if (ec != asio::error::eof) - throw std::runtime_error{fmt::format( - "[connection:{}] error parsing: {}", conn->id(), ec)}; - if (logger_) - logger_->d("[connection:%i] request finished", conn->id()); + asio::async_read_until(conn->socket_, conn->response_stream_, "\r\n\r\n", + std::bind(&Client::handle_response, this, ec, parser, parser_s, conn)); }); } +void +Client::handle_response(const asio::error_code &ec, + std::shared_ptr<http_parser> parser, + std::shared_ptr<http_parser_settings> parser_s, + std::shared_ptr<Connection> conn){ + if (ec && ec != asio::error::eof){ + if (logger_) + logger_->e("[connection:%i] error handling response: %s", + conn->id(), ec.message().c_str()); + } + std::ostringstream str_s; + str_s << &conn->response_stream_; + + // parse the request + http_parser_execute(parser.get(), parser_s.get(), str_s.str().c_str(), str_s.str().size()); + + // detect parsing errors + if (HPE_OK != parser->http_errno && HPE_PAUSED != parser->http_errno){ + if (logger_){ + auto err = HTTP_PARSER_ERRNO(parser.get()); + logger_->e("[connection:%i] error parsing: %s", conn->id(), http_errno_name(err)); + } + } + asio::async_read(conn->socket_, conn->response_stream_, asio::transfer_at_least(1), + std::bind(&Client::handle_response, this, ec, parser, parser_s, conn)); +} + }