[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/deimi/expresscpp/master/src/session.cpp [Back]  [Original]

#include "expresscpp/impl/session.hpp"

#include "boost/asio.hpp"
#include "boost/asio/strand.hpp"
#include "boost/beast/http/field.hpp"
#include "expresscpp/console.hpp"
#include "expresscpp/expresscpp.hpp"
#include "expresscpp/impl/listener.hpp"

namespace expresscpp {

Session::Session(boost::asio::ip::tcp::socket socket, ExpressCpp *express_cpp)
    : socket_(std::move(socket)), express_cpp_(express_cpp) {
  assert(express_cpp_ != nullptr);
}

Session::~Session() {
  Console::Debug("destroying session");
}

void Session::run() {
  do_read();
}

void Session::do_read() {
  parser_ = std::make_unique();
  parser_->body_limit(std::numeric_limits::max());
  auto self = shared_from_this();
  boost::beast::http::async_read(
      socket_, buffer_, *parser_,
      [self](boost::beast::error_code ec, std::size_t bytes_transferred) { self->on_read(ec, bytes_transferred); });
}

void Session::on_read(boost::beast::error_code ec, std::size_t bytes_transferred) {
  boost::ignore_unused(bytes_transferred);

  // This means they closed the connection
  if (ec == boost::beast::http::error::end_of_stream) {
    return do_close();
  }

  if (ec) {
    Console::Trace(fmt::format("{}:{}", "read", ec.message()));
    return;
  }

  auto http_request = parser_->get();

  const auto path = std::string(http_request.target());
  const auto method = beastVerbToHttpMethod(http_request.method());
  const auto keep_alive = http_request.keep_alive();

  auto req = std::make_shared(path, method);
  auto res = std::make_shared(this);
  res->KeepAlive(keep_alive);

  for (auto const &field : http_request) {
    const std::string name = boost::beast::http::to_string(field.name()).data();
    const std::string value(field.value().data(), field.value().size());
    req->setHeader(name, value);
  }

  req->setBody(http_request.body());

  express_cpp_->HandleRequest(req, res, nullptr);

  // try to match with slash if not yet found
  if (!res->response_sent_) {
    auto path_with_slash = std::string(http_request.target()) + "/";
    req->setPath(path_with_slash);
    express_cpp_->HandleRequest(req, res, nullptr);
  }

  if (!res->response_sent_) {
    Console::Error(fmt::format(R"(no response sent for path "{}")", req->getPath()));
  }
}

void Session::on_write(bool close, boost::beast::error_code ec, std::size_t bytes_transferred) {
  boost::ignore_unused(bytes_transferred);

  if (ec) {
    Console::Trace(fmt::format("{}:{}", "write", ec.message()));
    return;
  }

  if (close) {
    // This means we should close the connection, usually because
    // the response indicated the "Connection: close" semantic.
    return do_close();
  }
  // We're done with the response so delete it
  res_ = nullptr;

  // Read another request
  do_read();
}

void Session::do_close() {
  // Send a TCP shutdown
  boost::beast::error_code ec;
  socket_.shutdown(boost::asio::ip::tcp::socket::shutdown_send, ec);
  // At this point the connection is closed gracefully
}
}  // namespace expresscpp

Web Proxy Viewer  |  New URL  |  Original Page