Re-use Request, instead of re-create. Add asan target.
This commit is contained in:
4
Makefile
4
Makefile
@@ -37,3 +37,7 @@ test_connection: connection_afl
|
|||||||
@echo "Running $$(ls testcases | wc -l) tests"
|
@echo "Running $$(ls testcases | wc -l) tests"
|
||||||
for FILE in testcases/*; do ./connection_afl < $$FILE; done
|
for FILE in testcases/*; do ./connection_afl < $$FILE; done
|
||||||
@printf '\033[0;32mALL TESTS PASSED\033[0m\n'
|
@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
|
||||||
|
|||||||
@@ -9,11 +9,12 @@
|
|||||||
|
|
||||||
namespace firecgi {
|
namespace firecgi {
|
||||||
|
|
||||||
Connection::Connection(int sock, const sockaddr_in6& client_addr, const std::function<void(std::unique_ptr<Request>)>& callback, const std::unordered_set<std::string_view>& headers)
|
Connection::Connection(int sock, const sockaddr_in6& client_addr, const std::function<void(Request*)>& callback, const std::unordered_set<std::string_view>& headers)
|
||||||
: sock_(sock),
|
: sock_(sock),
|
||||||
callback_(callback),
|
callback_(callback),
|
||||||
headers_(headers),
|
headers_(headers),
|
||||||
buf_(sock, max_record_len) {
|
buf_(sock, max_record_len),
|
||||||
|
request_(this) {
|
||||||
char client_addr_str[INET6_ADDRSTRLEN];
|
char client_addr_str[INET6_ADDRSTRLEN];
|
||||||
PCHECK(inet_ntop(AF_INET6, &client_addr.sin6_addr, client_addr_str, sizeof(client_addr_str)));
|
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_;
|
return sock_;
|
||||||
}
|
}
|
||||||
|
|
||||||
request_.reset(new Request(header->RequestId(), this));
|
request_.NewRequest(header->RequestId());
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 4:
|
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)";
|
LOG(ERROR) << "out of order FCGI_PARAMS record, or client is multiplexing requests (which we don't support)";
|
||||||
return sock_;
|
return sock_;
|
||||||
}
|
}
|
||||||
@@ -104,7 +105,7 @@ int Connection::Read() {
|
|||||||
std::string_view value(value_buf, param_header->value_length);
|
std::string_view value(value_buf, param_header->value_length);
|
||||||
|
|
||||||
if (headers_.find(key) != headers_.end()) {
|
if (headers_.find(key) != headers_.end()) {
|
||||||
request_->AddParam(key, value);
|
request_.AddParam(key, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -112,7 +113,7 @@ int Connection::Read() {
|
|||||||
|
|
||||||
case 5:
|
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)";
|
LOG(ERROR) << "out of order FCGI_STDIN record, or client is multiplexing requests (which we don't support)";
|
||||||
return sock_;
|
return sock_;
|
||||||
}
|
}
|
||||||
@@ -120,10 +121,10 @@ int Connection::Read() {
|
|||||||
if (header->ContentLength() == 0) {
|
if (header->ContentLength() == 0) {
|
||||||
// Magic signal for completed request (mirrors the HTTP/1.1 protocol)
|
// Magic signal for completed request (mirrors the HTTP/1.1 protocol)
|
||||||
requests_++;
|
requests_++;
|
||||||
callback_(std::move(request_));
|
callback_(&request_);
|
||||||
} else {
|
} else {
|
||||||
std::string_view in(buf_.Read(header->ContentLength()), header->ContentLength());
|
std::string_view in(buf_.Read(header->ContentLength()), header->ContentLength());
|
||||||
request_->AddIn(in);
|
request_.AddIn(in);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ namespace firecgi {
|
|||||||
|
|
||||||
class Connection {
|
class Connection {
|
||||||
public:
|
public:
|
||||||
Connection(int sock, const sockaddr_in6& client_addr, const std::function<void(std::unique_ptr<Request>)>& callback, const std::unordered_set<std::string_view>& headers);
|
Connection(int sock, const sockaddr_in6& client_addr, const std::function<void(Request*)>& callback, const std::unordered_set<std::string_view>& headers);
|
||||||
~Connection();
|
~Connection();
|
||||||
|
|
||||||
[[nodiscard]] int Read();
|
[[nodiscard]] int Read();
|
||||||
@@ -21,14 +21,13 @@ class Connection {
|
|||||||
|
|
||||||
private:
|
private:
|
||||||
const int sock_;
|
const int sock_;
|
||||||
const std::function<void(std::unique_ptr<Request>)>& callback_;
|
const std::function<void(Request*)>& callback_;
|
||||||
const std::unordered_set<std::string_view>& headers_;
|
const std::unordered_set<std::string_view>& headers_;
|
||||||
|
firebuf::StreamBuffer buf_;
|
||||||
|
Request request_;
|
||||||
|
|
||||||
uint64_t requests_ = 0;
|
uint64_t requests_ = 0;
|
||||||
|
|
||||||
firebuf::StreamBuffer buf_;
|
|
||||||
|
|
||||||
std::unique_ptr<Request> request_;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace firecgi
|
} // namespace firecgi
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ int main(int argc, char *argv[]) {
|
|||||||
google::InitGoogleLogging(argv[0]);
|
google::InitGoogleLogging(argv[0]);
|
||||||
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
gflags::ParseCommandLineFlags(&argc, &argv, true);
|
||||||
|
|
||||||
firecgi::Server server(FLAGS_port, [](std::unique_ptr<firecgi::Request> request) {
|
firecgi::Server server(FLAGS_port, [](firecgi::Request* request) {
|
||||||
request->WriteHeader("Content-Type", "text/plain");
|
request->WriteHeader("Content-Type", "text/plain");
|
||||||
request->WriteBody("Hello world");
|
request->WriteBody("Hello world");
|
||||||
request->End();
|
request->End();
|
||||||
|
|||||||
2
firebuf
2
firebuf
Submodule firebuf updated: acc75058c6...fa20ad9d29
@@ -11,7 +11,7 @@
|
|||||||
|
|
||||||
namespace firecgi {
|
namespace firecgi {
|
||||||
|
|
||||||
Server::Server(int port, const std::function<void(std::unique_ptr<Request>)>& callback, int threads, const std::unordered_set<std::string_view>& headers)
|
Server::Server(int port, const std::function<void(Request*)>& callback, int threads, const std::unordered_set<std::string_view>& headers)
|
||||||
: port_(port),
|
: port_(port),
|
||||||
callback_(callback),
|
callback_(callback),
|
||||||
threads_(threads),
|
threads_(threads),
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ namespace firecgi {
|
|||||||
|
|
||||||
class Server {
|
class Server {
|
||||||
public:
|
public:
|
||||||
Server(int port, const std::function<void(std::unique_ptr<Request>)>& callback, int threads=1, const std::unordered_set<std::string_view>& headers={});
|
Server(int port, const std::function<void(Request*)>& callback, int threads=1, const std::unordered_set<std::string_view>& headers={});
|
||||||
void Serve();
|
void Serve();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@@ -19,7 +19,7 @@ class Server {
|
|||||||
void ServeInt();
|
void ServeInt();
|
||||||
|
|
||||||
const int port_;
|
const int port_;
|
||||||
const std::function<void(std::unique_ptr<Request>)> callback_;
|
const std::function<void(Request*)> callback_;
|
||||||
const int threads_;
|
const int threads_;
|
||||||
const std::unordered_set<std::string_view> headers_;
|
const std::unordered_set<std::string_view> headers_;
|
||||||
};
|
};
|
||||||
|
|||||||
13
request.cc
13
request.cc
@@ -16,11 +16,18 @@ template<class T> void AppendVec(const T& obj, std::vector<iovec>* vec) {
|
|||||||
|
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
Request::Request(uint16_t request_id, Connection* conn)
|
Request::Request(Connection* conn)
|
||||||
: request_id_(request_id),
|
: conn_(conn),
|
||||||
conn_(conn),
|
|
||||||
out_buf_(max_record_len) {}
|
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() {
|
uint16_t Request::RequestId() {
|
||||||
return request_id_;
|
return request_id_;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -12,7 +12,9 @@ class Connection;
|
|||||||
|
|
||||||
class Request {
|
class Request {
|
||||||
public:
|
public:
|
||||||
Request(uint16_t request_id, Connection *conn);
|
Request(Connection *conn);
|
||||||
|
|
||||||
|
void NewRequest(uint16_t request_id);
|
||||||
|
|
||||||
uint16_t RequestId();
|
uint16_t RequestId();
|
||||||
|
|
||||||
@@ -30,14 +32,14 @@ class Request {
|
|||||||
Header OutputHeader();
|
Header OutputHeader();
|
||||||
iovec OutputVec();
|
iovec OutputVec();
|
||||||
|
|
||||||
const uint16_t request_id_;
|
|
||||||
Connection *conn_;
|
Connection *conn_;
|
||||||
|
uint16_t request_id_ = 0;
|
||||||
|
|
||||||
std::unordered_map<std::string, std::string> params_;
|
std::unordered_map<std::string, std::string> params_;
|
||||||
std::string in_;
|
std::string in_;
|
||||||
|
|
||||||
firebuf::Buffer out_buf_;
|
firebuf::Buffer out_buf_;
|
||||||
bool body_written_ = false;
|
bool body_written_;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace firecgi
|
} // namespace firecgi
|
||||||
|
|||||||
Reference in New Issue
Block a user