From a4171b0ae18760da377eb95dbb754cd41eaf9945 Mon Sep 17 00:00:00 2001 From: flamingcow Date: Tue, 7 May 2019 22:56:00 -0700 Subject: [PATCH] Re-use Request, instead of re-create. Add asan target. --- Makefile | 4 ++++ connection.cc | 17 +++++++++-------- connection.h | 9 ++++----- example_simple.cc | 2 +- firebuf | 2 +- firecgi.cc | 2 +- firecgi.h | 4 ++-- request.cc | 13 ++++++++++--- request.h | 8 +++++--- 9 files changed, 37 insertions(+), 24 deletions(-) diff --git a/Makefile b/Makefile index 1e4cab2..e4e5592 100644 --- a/Makefile +++ b/Makefile @@ -37,3 +37,7 @@ test_connection: connection_afl @echo "Running $$(ls testcases | wc -l) tests" for FILE in testcases/*; do ./connection_afl < $$FILE; done @printf '\033[0;32mALL TESTS PASSED\033[0m\n' + +asan: + $(MAKE) clean + FIRE_CXXFLAGS="-O1 -g -fsanitize=address -fno-omit-frame-pointer -std=gnu++2a -Wall -Werror" $(MAKE) all diff --git a/connection.cc b/connection.cc index 034ee03..a78eaba 100644 --- a/connection.cc +++ b/connection.cc @@ -9,11 +9,12 @@ namespace firecgi { -Connection::Connection(int sock, const sockaddr_in6& client_addr, const std::function)>& callback, const std::unordered_set& headers) +Connection::Connection(int sock, const sockaddr_in6& client_addr, const std::function& callback, const std::unordered_set& headers) : sock_(sock), callback_(callback), headers_(headers), - buf_(sock, max_record_len) { + buf_(sock, max_record_len), + request_(this) { char client_addr_str[INET6_ADDRSTRLEN]; PCHECK(inet_ntop(AF_INET6, &client_addr.sin6_addr, client_addr_str, sizeof(client_addr_str))); @@ -70,13 +71,13 @@ int Connection::Read() { return sock_; } - request_.reset(new Request(header->RequestId(), this)); + request_.NewRequest(header->RequestId()); } break; case 4: { - if (request_ == nullptr || header->RequestId() != request_->RequestId()) { + if (header->RequestId() != request_.RequestId()) { LOG(ERROR) << "out of order FCGI_PARAMS record, or client is multiplexing requests (which we don't support)"; return sock_; } @@ -104,7 +105,7 @@ int Connection::Read() { std::string_view value(value_buf, param_header->value_length); if (headers_.find(key) != headers_.end()) { - request_->AddParam(key, value); + request_.AddParam(key, value); } } } @@ -112,7 +113,7 @@ int Connection::Read() { case 5: { - if (request_ == nullptr || header->RequestId() != request_->RequestId()) { + if (header->RequestId() != request_.RequestId()) { LOG(ERROR) << "out of order FCGI_STDIN record, or client is multiplexing requests (which we don't support)"; return sock_; } @@ -120,10 +121,10 @@ int Connection::Read() { if (header->ContentLength() == 0) { // Magic signal for completed request (mirrors the HTTP/1.1 protocol) requests_++; - callback_(std::move(request_)); + callback_(&request_); } else { std::string_view in(buf_.Read(header->ContentLength()), header->ContentLength()); - request_->AddIn(in); + request_.AddIn(in); } } break; diff --git a/connection.h b/connection.h index f9cc8df..1496b93 100644 --- a/connection.h +++ b/connection.h @@ -13,7 +13,7 @@ namespace firecgi { class Connection { public: - Connection(int sock, const sockaddr_in6& client_addr, const std::function)>& callback, const std::unordered_set& headers); + Connection(int sock, const sockaddr_in6& client_addr, const std::function& callback, const std::unordered_set& headers); ~Connection(); [[nodiscard]] int Read(); @@ -21,14 +21,13 @@ class Connection { private: const int sock_; - const std::function)>& callback_; + const std::function& callback_; const std::unordered_set& headers_; + firebuf::StreamBuffer buf_; + Request request_; uint64_t requests_ = 0; - firebuf::StreamBuffer buf_; - - std::unique_ptr request_; }; } // namespace firecgi diff --git a/example_simple.cc b/example_simple.cc index b008397..6c83bc0 100644 --- a/example_simple.cc +++ b/example_simple.cc @@ -10,7 +10,7 @@ int main(int argc, char *argv[]) { google::InitGoogleLogging(argv[0]); gflags::ParseCommandLineFlags(&argc, &argv, true); - firecgi::Server server(FLAGS_port, [](std::unique_ptr request) { + firecgi::Server server(FLAGS_port, [](firecgi::Request* request) { request->WriteHeader("Content-Type", "text/plain"); request->WriteBody("Hello world"); request->End(); diff --git a/firebuf b/firebuf index acc7505..fa20ad9 160000 --- a/firebuf +++ b/firebuf @@ -1 +1 @@ -Subproject commit acc75058c62fb71631c24bd6034e4d21ec472144 +Subproject commit fa20ad9d29083eb67bc9fc44789b005d09e712c9 diff --git a/firecgi.cc b/firecgi.cc index eb8586e..227ff7e 100644 --- a/firecgi.cc +++ b/firecgi.cc @@ -11,7 +11,7 @@ namespace firecgi { -Server::Server(int port, const std::function)>& callback, int threads, const std::unordered_set& headers) +Server::Server(int port, const std::function& callback, int threads, const std::unordered_set& headers) : port_(port), callback_(callback), threads_(threads), diff --git a/firecgi.h b/firecgi.h index 8fdb4b9..c4452ef 100644 --- a/firecgi.h +++ b/firecgi.h @@ -10,7 +10,7 @@ namespace firecgi { class Server { public: - Server(int port, const std::function)>& callback, int threads=1, const std::unordered_set& headers={}); + Server(int port, const std::function& callback, int threads=1, const std::unordered_set& headers={}); void Serve(); private: @@ -19,7 +19,7 @@ class Server { void ServeInt(); const int port_; - const std::function)> callback_; + const std::function callback_; const int threads_; const std::unordered_set headers_; }; diff --git a/request.cc b/request.cc index b196664..58f3b0a 100644 --- a/request.cc +++ b/request.cc @@ -16,11 +16,18 @@ template void AppendVec(const T& obj, std::vector* vec) { } // namespace -Request::Request(uint16_t request_id, Connection* conn) - : request_id_(request_id), - conn_(conn), +Request::Request(Connection* conn) + : conn_(conn), out_buf_(max_record_len) {} +void Request::NewRequest(uint16_t request_id) { + request_id_ = request_id; + params_.clear(); + in_.clear(); + out_buf_.Reset(); + body_written_ = false; +} + uint16_t Request::RequestId() { return request_id_; } diff --git a/request.h b/request.h index 45ee8ed..a47e834 100644 --- a/request.h +++ b/request.h @@ -12,7 +12,9 @@ class Connection; class Request { public: - Request(uint16_t request_id, Connection *conn); + Request(Connection *conn); + + void NewRequest(uint16_t request_id); uint16_t RequestId(); @@ -30,14 +32,14 @@ class Request { Header OutputHeader(); iovec OutputVec(); - const uint16_t request_id_; Connection *conn_; + uint16_t request_id_ = 0; std::unordered_map params_; std::string in_; firebuf::Buffer out_buf_; - bool body_written_ = false; + bool body_written_; }; } // namespace firecgi