Skip to content
Snippets Groups Projects
Commit 9f493b95 authored by Seva's avatar Seva
Browse files

http: make continious reads non blocking

parent b98cc78b
No related branches found
No related tags found
No related merge requests found
......@@ -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
......@@ -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 && \
......@@ -24,10 +26,15 @@ RUN echo "*** Installing RESTinio & dependencies ***" \
&& 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
......
......@@ -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_;
......
......@@ -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");
asio::async_read_until(conn->socket_, conn->response_stream_, "\r\n\r\n",
std::bind(&Client::handle_response, this, ec, parser, parser_s, conn));
});
}
while(asio::read(socket, resp_s, asio::transfer_at_least(1), ec)){
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 << &resp_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());
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());
if (logger_)
logger_->e("[connection:%i] error parsing: %s",
conn->id(), http_errno_name(err));
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(conn->socket_, conn->response_stream_, asio::transfer_at_least(1),
std::bind(&Client::handle_response, this, ec, parser, parser_s, conn));
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment