diff options
author | ipknHama <ipknhama@gmail.com> | 2014-04-01 21:25:16 +0900 |
---|---|---|
committer | ipknHama <ipknhama@gmail.com> | 2014-04-01 21:25:16 +0900 |
commit | 7056550bbb3a46b5f1ea077999cc3cd374af4b9e (patch) | |
tree | f9126fa815f8c9c1aa1f9a946f881558823560f0 /http_connection.h | |
parent | 4b8c67e2300205200f4f846400d73a03cb3da854 (diff) | |
download | crow-7056550bbb3a46b5f1ea077999cc3cd374af4b9e.tar.gz crow-7056550bbb3a46b5f1ea077999cc3cd374af4b9e.zip |
working http server
Diffstat (limited to 'http_connection.h')
-rw-r--r-- | http_connection.h | 89 |
1 files changed, 85 insertions, 4 deletions
diff --git a/http_connection.h b/http_connection.h index 92b06e1..c25c61d 100644 --- a/http_connection.h +++ b/http_connection.h @@ -1,7 +1,12 @@ #pragma once #include <boost/asio.hpp> #include <http_parser.h> +#include <atomic> +#include <boost/asio.hpp> +#include <boost/algorithm/string/predicate.hpp> + #include "parser.h" +#include "http_response.h" namespace flask { @@ -11,7 +16,7 @@ namespace flask class Connection { public: - Connection(tcp::socket&& socket, Handler* handler) : socket_(std::move(socket)), handler_(handler) + Connection(tcp::socket&& socket, Handler* handler) : socket_(std::move(socket)), handler_(handler), parser_(this) { } @@ -20,19 +25,91 @@ namespace flask do_read(); } + void handle() + { + // request = make_request_from_parser + res = handler_->handle(); + + static std::string seperator = ": "; + static std::string crlf = "\r\n"; + + std::vector<boost::asio::const_buffer> buffers; + + buffers.push_back(boost::asio::buffer(statusCodes[res.status])); + + bool has_content_length = false; + for(auto& kv : res.headers) + { + buffers.push_back(boost::asio::buffer(kv.first)); + buffers.push_back(boost::asio::buffer(seperator)); + buffers.push_back(boost::asio::buffer(kv.second)); + buffers.push_back(boost::asio::buffer(crlf)); + + if (boost::iequals(kv.first, "content-length")) + has_content_length = true; + } + + if (!has_content_length) + close_connection_ = true; + + buffers.push_back(boost::asio::buffer(crlf)); + buffers.push_back(boost::asio::buffer(res.body)); + + do_write(buffers); + } + private: void do_read() { + life_++; socket_.async_read_some(boost::asio::buffer(buffer_), [this](boost::system::error_code ec, std::size_t bytes_transferred) { if (!ec) { - parser_.feed(buffer_.data(), bytes_transferred); + bool ret = parser_.feed(buffer_.data(), bytes_transferred); + do_read(); + } + else + { + bool ret = parser_.done(); + socket_.close(); + + life_--; + if ((int)life_ == 0) + { + delete this; + } + } + }); + } + + void do_write(const std::vector<boost::asio::const_buffer>& buffers) + { + life_++; + boost::asio::async_write(socket_, buffers, + [this](const boost::system::error_code& ec, std::size_t bytes_transferred) + { + bool should_close = false; + if (!ec) + { + if (close_connection_) + { + should_close = true; + } } else { - parser_.done(); + should_close = true; + } + if (should_close) + { + socket_.close(); + life_--; + if ((int)life_ == 0) + { + delete this; + } } }); } @@ -43,6 +120,10 @@ namespace flask std::array<char, 8192> buffer_; - HTTPParser parser_; + HTTPParser<Connection> parser_; + response res; + + std::atomic<int> life_; + bool close_connection_ = false; }; } |