Skip to content

Commit

Permalink
Merge branch 'master' into unix_socket
Browse files Browse the repository at this point in the history
  • Loading branch information
gittiver authored Jan 24, 2025
2 parents 76f57c9 + 96ed14a commit f6f488d
Show file tree
Hide file tree
Showing 9 changed files with 220 additions and 38 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ jobs:
windows-latest,
macos-latest,
ubuntu-20.04,
ubuntu-24.04,
ubuntu-22.04,
macos-13
]
# ubuntu-18.04 does not work due to compile error on asio
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/submit_coverage.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
if: github.event.workflow_run.conclusion == 'success'
steps:
- name: Download artifact
uses: dawidd6/action-download-artifact@v7
uses: dawidd6/action-download-artifact@v8
with:
workflow: ${{ github.event.workflow_run.workflow_id }}
workflow_conclusion: success
Expand Down
5 changes: 4 additions & 1 deletion docs/guides/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,10 @@ Crow allows users to handle requests that may not come from the network. This is

req.url = "/place";

app.handle(req, res); //res will contain a code of 200, and a response body of "hi"
app.handle_full(req, res);
// res will contain:
// res.code == 200
// res.body == "hi"
}
```
Expand Down
39 changes: 28 additions & 11 deletions include/crow/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -380,7 +380,7 @@ namespace crow
}

/// \brief Get the number of threads that server is using
std::uint16_t concurrency()
std::uint16_t concurrency() const
{
return concurrency_;
}
Expand Down Expand Up @@ -521,12 +521,18 @@ namespace crow
#endif
validate();

error_code ec;
asio::ip::address addr = asio::ip::make_address(bindaddr_,ec);
if (ec){
CROW_LOG_ERROR << ec.message() << " - Can not create valid ip address from string: \"" << bindaddr_ << "\"";
return;
}
tcp::endpoint endpoint(addr, port_);
#ifdef CROW_ENABLE_SSL
if (ssl_used_)
{

router_.using_ssl = true;
TCPAcceptor::endpoint endpoint(asio::ip::address::from_string(bindaddr_), port_);
ssl_server_ = std::move(std::unique_ptr<ssl_server_t>(new ssl_server_t(this, endpoint, server_name_, &middlewares_, concurrency_, timeout_, &ssl_context_)));
ssl_server_->set_tick_function(tick_interval_, tick_function_);
ssl_server_->signal_clear();
Expand Down Expand Up @@ -729,21 +735,32 @@ namespace crow
}

/// \brief Wait until the server has properly started
void wait_for_server_start()
std::cv_status wait_for_server_start(std::chrono::milliseconds wait_timeout = std::chrono::milliseconds(3000))
{
std::cv_status status = std::cv_status::no_timeout;
auto wait_until = std::chrono::steady_clock::now() + wait_timeout;
{
std::unique_lock<std::mutex> lock(start_mutex_);
while (!server_started_)
cv_started_.wait(lock);
while (!server_started_ && (status == std::cv_status::no_timeout))
{
status = cv_started_.wait_until(lock, wait_until);
}
}
if (server_)
server_->wait_for_start();
else if (unix_server_)
unix_server_->wait_for_start();
if (status == std::cv_status::no_timeout)
{
if (server_) {
status = server_->wait_for_start(wait_until);
} else if (unix_server_) {
status = unix_server_->wait_for_start(wait_until);
}
#ifdef CROW_ENABLE_SSL
else if (ssl_server_)
ssl_server_->wait_for_start();
else if (ssl_server_)
{
status = ssl_server_->wait_for_start(wait_until);
}
#endif
}
return status;
}

private:
Expand Down
4 changes: 2 additions & 2 deletions include/crow/http_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ namespace crow
buffers_.clear();
static std::string expect_100_continue = "HTTP/1.1 100 Continue\r\n\r\n";
buffers_.emplace_back(expect_100_continue.data(), expect_100_continue.size());
do_write();
do_write_sync(buffers_);
}
}

Expand Down Expand Up @@ -425,7 +425,7 @@ namespace crow
res_body_copy_.swap(res.body);
buffers_.emplace_back(res_body_copy_.data(), res_body_copy_.size());

do_write();
do_write_sync(buffers_);

if (need_to_start_read_after_complete_)
{
Expand Down
34 changes: 20 additions & 14 deletions include/crow/http_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,14 @@ namespace crow // NOTE: Already documented in "crow/app.h"
class Server
{
public:
Server(Handler* handler, typename Acceptor::endpoint endpoint, std::string server_name = std::string("Crow/") + VERSION, std::tuple<Middlewares...>* middlewares = nullptr, uint16_t concurrency = 1, uint8_t timeout = 5, typename Adaptor::context* adaptor_ctx = nullptr):
acceptor_(io_context_, endpoint),
Server(Handler* handler,
typename Acceptor::endpoint endpoint,
std::string server_name = std::string("Crow/") + VERSION,
std::tuple<Middlewares...>* middlewares = nullptr,
uint16_t concurrency = 1,
uint8_t timeout = 5,
typename Adaptor::context* adaptor_ctx = nullptr):
acceptor_(io_context_,endpoint),
signals_(io_context_),
tick_timer_(io_context_),
handler_(handler),
Expand Down Expand Up @@ -148,11 +154,10 @@ namespace crow // NOTE: Already documented in "crow/app.h"
on_tick();
});
}

port_ = acceptor_.port();
handler_->port(port_);

CROW_LOG_INFO << server_name_ << " server is running at " << acceptor_.url_display(handler_->ssl_used()) << " using " << concurrency_ << " threads";
handler_->port(acceptor_.local_endpoint().port());
CROW_LOG_INFO << server_name_
<< " server is running at " << acceptor_.url_display(handler_->ssl_used())
<< " using " << concurrency_ << " threads";
CROW_LOG_INFO << "Call `app.loglevel(crow::LogLevel::Warning)` to hide Info level logs.";

signals_.async_wait(
Expand Down Expand Up @@ -190,16 +195,19 @@ namespace crow // NOTE: Already documented in "crow/app.h"
io_context_.stop(); // Close main io_service
}

uint16_t port(){
uint16_t port() const {
return acceptor_.local_endpoint().port();
}

/// Wait until the server has properly started
void wait_for_start()
/// Wait until the server has properly started or until timeout
std::cv_status wait_for_start(std::chrono::steady_clock::time_point wait_until)
{
std::unique_lock<std::mutex> lock(start_mutex_);
while (!server_started_)
cv_started_.wait(lock);

std::cv_status status = std::cv_status::no_timeout;
while (!server_started_ && ( status==std::cv_status::no_timeout ))
status = cv_started_.wait_until(lock,wait_until);
return status;
}

void signal_clear()
Expand Down Expand Up @@ -288,8 +296,6 @@ namespace crow // NOTE: Already documented in "crow/app.h"
uint16_t concurrency_{2};
std::uint8_t timeout_;
std::string server_name_;
uint16_t port_;
std::string bindaddr_;
bool use_unix_;
std::vector<std::atomic<unsigned int>> task_queue_length_pool_;

Expand Down
11 changes: 9 additions & 2 deletions include/crow/routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -445,7 +445,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
void handle_upgrade(const request& req, response&, SocketAdaptor&& adaptor) override
{
max_payload_ = max_payload_override_ ? max_payload_ : app_->websocket_max_payload();
new crow::websocket::Connection<SocketAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
new crow::websocket::Connection<SocketAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_, mirror_protocols_);
}
void handle_upgrade(const request& req, response&, UnixSocketAdaptor&& adaptor) override
{
Expand All @@ -455,7 +455,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
#ifdef CROW_ENABLE_SSL
void handle_upgrade(const request& req, response&, SSLAdaptor&& adaptor) override
{
new crow::websocket::Connection<SSLAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
new crow::websocket::Connection<SSLAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_, mirror_protocols_);
}
#endif

Expand Down Expand Up @@ -508,13 +508,20 @@ namespace crow // NOTE: Already documented in "crow/app.h"
return *this;
}

self_t& mirrorprotocols(bool mirror_protocols = true)
{
mirror_protocols_ = mirror_protocols;
return *this;
}

protected:
App* app_;
std::function<void(crow::websocket::connection&)> open_handler_;
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler_;
std::function<void(crow::websocket::connection&, const std::string&, uint16_t)> close_handler_;
std::function<void(crow::websocket::connection&, const std::string&)> error_handler_;
std::function<bool(const crow::request&, void**)> accept_handler_;
bool mirror_protocols_ = false;
uint64_t max_payload_;
bool max_payload_override_ = false;
std::vector<std::string> subprotocols_;
Expand Down
8 changes: 7 additions & 1 deletion include/crow/websocket.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@ namespace crow // NOTE: Already documented in "crow/app.h"
std::function<void(crow::websocket::connection&, const std::string&, bool)> message_handler,
std::function<void(crow::websocket::connection&, const std::string&, uint16_t)> close_handler,
std::function<void(crow::websocket::connection&, const std::string&)> error_handler,
std::function<bool(const crow::request&, void**)> accept_handler):
std::function<bool(const crow::request&, void**)> accept_handler,
bool mirror_protocols):
adaptor_(std::move(adaptor)),
handler_(handler),
max_payload_bytes_(max_payload),
Expand Down Expand Up @@ -145,6 +146,11 @@ namespace crow // NOTE: Already documented in "crow/app.h"
}
}

if (mirror_protocols & !requested_subprotocols_header.empty())
{
subprotocol_ = requested_subprotocols_header;
}

if (accept_handler_)
{
void* ud = nullptr;
Expand Down
Loading

0 comments on commit f6f488d

Please sign in to comment.