diff options
author | ipknHama <ipknhama@gmail.com> | 2014-04-01 01:51:50 +0900 |
---|---|---|
committer | ipknHama <ipknhama@gmail.com> | 2014-04-01 01:51:50 +0900 |
commit | 4b8c67e2300205200f4f846400d73a03cb3da854 (patch) | |
tree | 46b63650efd6952cf88a62cc0511162af54d896f | |
parent | 1e11a177ee6b680b55f01d6090ccd1b2e2b8c51c (diff) | |
download | crow-4b8c67e2300205200f4f846400d73a03cb3da854.tar.gz crow-4b8c67e2300205200f4f846400d73a03cb3da854.zip |
accept connections, print http request parsed information
-rw-r--r-- | .gitmodules | 3 | ||||
-rw-r--r-- | Makefile | 8 | ||||
-rw-r--r-- | example.cpp | 10 | ||||
-rw-r--r-- | flask.h | 31 | ||||
m--------- | http-parser | 0 | ||||
-rw-r--r-- | http_connection.h | 48 | ||||
-rw-r--r-- | http_server.h | 48 | ||||
-rw-r--r-- | parser.h | 79 | ||||
-rw-r--r-- | test.py | 3 |
9 files changed, 227 insertions, 3 deletions
diff --git a/.gitmodules b/.gitmodules new file mode 100644 index 0000000..95da8a7 --- /dev/null +++ b/.gitmodules @@ -0,0 +1,3 @@ +[submodule "http-parser"] + path = http-parser + url = https://github.com/joyent/http-parser @@ -1,3 +1,7 @@ all: example -example: example.cpp - g++ -o example example.cpp +example: example.cpp flask.h http_server.h http_connection.h parser.h + g++ -g -std=c++11 -o example example.cpp http-parser/http_parser.c -pthread -lboost_system -lboost_thread -I http-parser/ +test: example + ./example & + test.py + pkill example diff --git a/example.cpp b/example.cpp index 3b07d61..904e1ff 100644 --- a/example.cpp +++ b/example.cpp @@ -1,8 +1,16 @@ #include "flask.h" +#include <iostream> + flask::Flask app; int main() { - app.run(); + app.route("/", + []{ + return "Hello World!"; + }); + + app.port(8080) + .run(); } @@ -1,3 +1,15 @@ +#pragma once +#include <string> +#include <functional> +#include <memory> +#include <future> +#include <stdint.h> + +#include "http_server.h" + +// TEST +#include <iostream> + namespace flask { class Flask @@ -7,8 +19,27 @@ namespace flask { } + void handle() + { + } + + void route(const std::string& url, std::function<std::string()> f) + { + } + + Flask& port(std::uint16_t port) + { + port_ = port; + return *this; + } + void run() { + Server<Flask> server(this, port_); + server.run(); } + private: + uint16_t port_ = 80; }; }; + diff --git a/http-parser b/http-parser new file mode 160000 +Subproject d19e12911a1b523885bdf0d82f1f3e91df90711 diff --git a/http_connection.h b/http_connection.h new file mode 100644 index 0000000..92b06e1 --- /dev/null +++ b/http_connection.h @@ -0,0 +1,48 @@ +#pragma once +#include <boost/asio.hpp> +#include <http_parser.h> +#include "parser.h" + +namespace flask +{ + using namespace boost; + using tcp = asio::ip::tcp; + template <typename Handler> + class Connection + { + public: + Connection(tcp::socket&& socket, Handler* handler) : socket_(std::move(socket)), handler_(handler) + { + } + + void start() + { + do_read(); + } + + private: + void do_read() + { + 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); + } + else + { + parser_.done(); + } + }); + } + + private: + tcp::socket socket_; + Handler* handler_; + + std::array<char, 8192> buffer_; + + HTTPParser parser_; + }; +} diff --git a/http_server.h b/http_server.h new file mode 100644 index 0000000..002eec6 --- /dev/null +++ b/http_server.h @@ -0,0 +1,48 @@ +#pragma once + +#include <boost/asio.hpp> +#include <stdint.h> + +#include "http_connection.h" + +// TEST +#include <iostream> + +namespace flask +{ + using namespace boost; + using tcp = asio::ip::tcp; + template <typename Handler> + class Server + { + public: + Server(Handler* handler, uint16_t port) + : acceptor_(io_service_, tcp::endpoint(asio::ip::address(), port)), socket_(io_service_), handler_(handler) + { + do_accept(); + } + + void run() + { + auto _ = std::async(std::launch::async, [this]{io_service_.run();}); + } + + private: + void do_accept() + { + acceptor_.async_accept(socket_, + [this](boost::system::error_code ec) + { + if (!ec) + (new Connection<Handler>(std::move(socket_), handler_))->start(); + do_accept(); + }); + } + + private: + asio::io_service io_service_; + tcp::acceptor acceptor_; + tcp::socket socket_; + Handler* handler_; + }; +} diff --git a/parser.h b/parser.h new file mode 100644 index 0000000..2f2626d --- /dev/null +++ b/parser.h @@ -0,0 +1,79 @@ +#include <iostream> +#include <string> +namespace flask +{ + struct HTTPParser : public http_parser + { + static int on_message_begin(http_parser* self_) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + return 0; + } + static int on_url(http_parser* self_, const char* at, size_t length) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + std::cout << std::string(at, at+length) << std::endl; + return 0; + } + static int on_status(http_parser* self_, const char* at, size_t length) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + std::cout << std::string(at, at+length) << std::endl; + return 0; + } + static int on_header_field(http_parser* self_, const char* at, size_t length) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + std::cout << std::string(at, at+length) << std::endl; + return 0; + } + static int on_header_value(http_parser* self_, const char* at, size_t length) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + std::cout << std::string(at, at+length) << std::endl; + return 0; + } + static int on_headers_complete(http_parser* self_) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + return 0; + } + static int on_body(http_parser* self_, const char* at, size_t length) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + std::cout << std::string(at, at+length) << std::endl; + return 0; + } + static int on_message_complete(http_parser* self_) + { + HTTPParser* self = static_cast<HTTPParser*>(self_); + return 0; + } + HTTPParser() : + settings_ { + on_message_begin, + on_url, + on_status, + on_header_field, + on_header_value, + on_headers_complete, + on_body, + on_message_complete, + } + { + http_parser_init(this, HTTP_REQUEST); + } + + void feed(const char* buffer, int length) + { + int nparsed = http_parser_execute(this, &settings_, buffer, length); + } + + void done() + { + int nparsed = http_parser_execute(this, &settings_, nullptr, 0); + } + + http_parser_settings settings_; + }; +} @@ -0,0 +1,3 @@ +import urllib +d = urllib.urlopen('http://localhost:8080').read() +print d |