Skip to content
Merged
Show file tree
Hide file tree
Changes from 12 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
4fff814
add unix domain socket
na-trium-144 Apr 11, 2024
d962b01
add handle_upgrade for unix socket
na-trium-144 Apr 12, 2024
190cf3d
set reuse addr false
na-trium-144 Apr 16, 2024
76f8c58
add example for unix socket
na-trium-144 Apr 20, 2024
89df049
fix unittesterror
na-trium-144 Apr 20, 2024
40127cc
Merge remote-tracking branch 'origin/unix_socket' into unix_socket
na-trium-144 Apr 20, 2024
fc8a00d
add unix_socket test
na-trium-144 Apr 20, 2024
a0ce00c
no need to use windows api
na-trium-144 Apr 20, 2024
a117692
fix ssladaptor
na-trium-144 Apr 21, 2024
f8aece3
Merge remote-tracking branch 'origin/unix_socket' into unix_socket
na-trium-144 Apr 21, 2024
5f5372e
Merge branch 'master' into unix_socket
na-trium-144 Jun 4, 2024
0bdbeaa
rename unix_path to local_socket_path
na-trium-144 Jun 5, 2024
bdc1e6d
Merge branch 'master' into unix_socket
The-EDev Oct 25, 2024
f563217
fix build errors and warnings
na-trium-144 Dec 16, 2024
76f57c9
Merge branch 'master' into unix_socket
gittiver Jan 10, 2025
f6f488d
Merge branch 'master' into unix_socket
gittiver Jan 24, 2025
36f4e73
Merge remote-tracking branch 'origin/master' into unix_socket
na-trium-144 Jun 9, 2025
45d3fd5
fix build errors
na-trium-144 Jun 9, 2025
9976407
fix build errors with boost asio
na-trium-144 Jun 10, 2025
27b2577
fix bad_descriptor error on acceptor.set_option
na-trium-144 Jun 10, 2025
11bf7a0
fix error handling on close, reduce unnecessary acceptor methods
na-trium-144 Jun 11, 2025
0bca330
Merge branch 'master' into unix_socket
gittiver Jun 11, 2025
ce262a2
fixed remaining line from conflict.
gittiver Jun 11, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions examples/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,10 @@ add_executable(example_file_upload example_file_upload.cpp)
add_warnings_optimizations(example_file_upload)
target_link_libraries(example_file_upload PUBLIC Crow::Crow)

add_executable(example_unix_socket example_unix_socket.cpp)
add_warnings_optimizations(example_unix_socket)
target_link_libraries(example_unix_socket PUBLIC Crow::Crow)

if(MSVC)
add_executable(example_vs example_vs.cpp)
add_warnings_optimizations(example_vs)
Expand Down
18 changes: 18 additions & 0 deletions examples/example_unix_socket.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
#include "crow.h"

#include <sys/stat.h>

int main()
{
crow::SimpleApp app;

CROW_ROUTE(app, "/")
([]() {
return "Hello, world!";
});

std::string local_socket_path = "example.sock";
unlink(local_socket_path.c_str());
app.local_socket_path(local_socket_path).run();

}
1 change: 1 addition & 0 deletions include/crow.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include "crow/TinySHA1.hpp"
#include "crow/settings.h"
#include "crow/socket_adaptors.h"
#include "crow/socket_acceptors.h"
#include "crow/json.h"
#include "crow/mustache.h"
#include "crow/logging.h"
Expand Down
57 changes: 47 additions & 10 deletions include/crow/app.h
Original file line number Diff line number Diff line change
Expand Up @@ -202,11 +202,12 @@ namespace crow
using self_t = Crow;

/// \brief The HTTP server
using server_t = Server<Crow, SocketAdaptor, Middlewares...>;

using server_t = Server<Crow, TCPAcceptor, SocketAdaptor, Middlewares...>;
/// \brief An HTTP server that runs on unix domain socket
using unix_server_t = Server<Crow, UnixSocketAcceptor, UnixSocketAdaptor, Middlewares...>;
#ifdef CROW_ENABLE_SSL
/// \brief An HTTP server that runs on SSL with an SSLAdaptor
using ssl_server_t = Server<Crow, SSLAdaptor, Middlewares...>;
using ssl_server_t = Server<Crow, TCPAcceptor, SSLAdaptor, Middlewares...>;
#endif
Crow()
{}
Expand Down Expand Up @@ -344,6 +345,20 @@ namespace crow
return bindaddr_;
}

/// \brief Disable tcp/ip and use unix domain socket instead
self_t& local_socket_path(std::string path)
{
bindaddr_ = path;
use_unix_ = true;
return *this;
}

/// \brief Get the unix domain socket path
std::string local_socket_path()
{
return bindaddr_;
}

/// \brief Run the server on multiple threads using all available threads
self_t& multithreaded()
{
Expand Down Expand Up @@ -502,7 +517,8 @@ namespace crow
#ifdef CROW_ENABLE_SSL
if (ssl_used_)
{
ssl_server_ = std::move(std::unique_ptr<ssl_server_t>(new ssl_server_t(this, bindaddr_, port_, server_name_, &middlewares_, concurrency_, timeout_, &ssl_context_)));
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();
for (auto snum : signals_)
Expand All @@ -515,14 +531,30 @@ namespace crow
else
#endif
{
server_ = std::move(std::unique_ptr<server_t>(new server_t(this, bindaddr_, port_, server_name_, &middlewares_, concurrency_, timeout_, nullptr)));
server_->set_tick_function(tick_interval_, tick_function_);
for (auto snum : signals_)
if (use_unix_)
{
server_->signal_add(snum);
UnixSocketAcceptor::endpoint endpoint(bindaddr_);
unix_server_ = std::move(std::unique_ptr<unix_server_t>(new unix_server_t(this, endpoint, server_name_, &middlewares_, concurrency_, timeout_, nullptr)));
unix_server_->set_tick_function(tick_interval_, tick_function_);
for (auto snum : signals_)
{
unix_server_->signal_add(snum);
}
notify_server_start();
unix_server_->run();
}
else
{
TCPAcceptor::endpoint endpoint(asio::ip::address::from_string(bindaddr_), port_);
server_ = std::move(std::unique_ptr<server_t>(new server_t(this, endpoint, server_name_, &middlewares_, concurrency_, timeout_, nullptr)));
server_->set_tick_function(tick_interval_, tick_function_);
for (auto snum : signals_)
{
server_->signal_add(snum);
}
notify_server_start();
server_->run();
}
notify_server_start();
server_->run();
}
}

Expand Down Expand Up @@ -556,6 +588,7 @@ namespace crow
websocket->close("Server Application Terminated");
}
if (server_) { server_->stop(); }
if (unix_server_) { unix_server_->stop(); }
}
}

Expand Down Expand Up @@ -696,6 +729,8 @@ namespace crow
}
if (server_)
server_->wait_for_start();
else if (unix_server_)
unix_server_->wait_for_start();
#ifdef CROW_ENABLE_SSL
else if (ssl_server_)
ssl_server_->wait_for_start();
Expand Down Expand Up @@ -735,6 +770,7 @@ namespace crow
uint64_t max_payload_{UINT64_MAX};
std::string server_name_ = std::string("Crow/") + VERSION;
std::string bindaddr_ = "0.0.0.0";
bool use_unix_ = false;
size_t res_stream_threshold_ = 1048576;
Router router_;
bool static_routes_added_{false};
Expand All @@ -756,6 +792,7 @@ namespace crow
#endif

std::unique_ptr<server_t> server_;
std::unique_ptr<unix_server_t> unix_server_;

std::vector<int> signals_{SIGINT, SIGTERM};

Expand Down
2 changes: 1 addition & 1 deletion include/crow/http_connection.h
Original file line number Diff line number Diff line change
Expand Up @@ -145,7 +145,7 @@ namespace crow
req_.middleware_container = static_cast<void*>(middlewares_);
req_.io_service = &adaptor_.get_io_service();

req_.remote_ip_address = adaptor_.remote_endpoint().address().to_string();
req_.remote_ip_address = adaptor_.address();

add_keep_alive_ = req_.keep_alive;
close_connection_ = req_.close_connection;
Expand Down
19 changes: 9 additions & 10 deletions include/crow/http_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,20 @@ namespace crow // NOTE: Already documented in "crow/app.h"
using error_code = asio::error_code;
#endif
using tcp = asio::ip::tcp;
using stream_protocol = asio::local::stream_protocol;

template<typename Handler, typename Adaptor = SocketAdaptor, typename... Middlewares>
template<typename Handler, typename Acceptor = TCPAcceptor, typename Adaptor = SocketAdaptor, typename... Middlewares>
class Server
{
public:
Server(Handler* handler, std::string bindaddr, uint16_t port, 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_service_, tcp::endpoint(asio::ip::address::from_string(bindaddr), port)),
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_service_, endpoint),
signals_(io_service_),
tick_timer_(io_service_),
handler_(handler),
concurrency_(concurrency),
timeout_(timeout),
server_name_(server_name),
port_(port),
bindaddr_(bindaddr),
task_queue_length_pool_(concurrency_ - 1),
middlewares_(middlewares),
adaptor_ctx_(adaptor_ctx)
Expand Down Expand Up @@ -150,11 +149,10 @@ namespace crow // NOTE: Already documented in "crow/app.h"
});
}

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


CROW_LOG_INFO << server_name_ << " server is running at " << (handler_->ssl_used() ? "https://" : "http://") << bindaddr_ << ":" << acceptor_.local_endpoint().port() << " using " << concurrency_ << " threads";
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 @@ -240,7 +238,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
is, handler_, server_name_, middlewares_,
get_cached_date_str_pool_[service_idx], *task_timer_pool_[service_idx], adaptor_ctx_, task_queue_length_pool_[service_idx]);

acceptor_.async_accept(
acceptor_.raw_acceptor().async_accept(
p->socket(),
[this, p, &is, service_idx](error_code ec) {
if (!ec)
Expand Down Expand Up @@ -273,7 +271,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
asio::io_service io_service_;
std::vector<detail::task_timer*> task_timer_pool_;
std::vector<std::function<std::string()>> get_cached_date_str_pool_;
tcp::acceptor acceptor_;
Acceptor acceptor_;
bool shutting_down_ = false;
bool server_started_{false};
std::condition_variable cv_started_;
Expand All @@ -288,6 +286,7 @@ namespace crow // NOTE: Already documented in "crow/app.h"
std::string server_name_;
uint16_t port_;
std::string bindaddr_;
bool use_unix_;
std::vector<std::atomic<unsigned int>> task_queue_length_pool_;

std::chrono::milliseconds tick_interval_;
Expand Down
10 changes: 10 additions & 0 deletions include/crow/routing.h
Original file line number Diff line number Diff line change
Expand Up @@ -118,6 +118,11 @@ namespace crow // NOTE: Already documented in "crow/app.h"
res = response(404);
res.end();
}
virtual void handle_upgrade(const request&, response& res, UnixSocketAdaptor&&)
{
res = response(404);
res.end();
}
#ifdef CROW_ENABLE_SSL
virtual void handle_upgrade(const request&, response& res, SSLAdaptor&&)
{
Expand Down Expand Up @@ -463,6 +468,11 @@ namespace crow // NOTE: Already documented in "crow/app.h"
max_payload_ = max_payload_override_ ? max_payload_ : app_->websocket_max_payload();
new crow::websocket::Connection<SocketAdaptor, App>(req, std::move(adaptor), app_, max_payload_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
}
void handle_upgrade(const request& req, response&, UnixSocketAdaptor&& adaptor) override
{
max_payload_ = max_payload_override_ ? max_payload_ : app_->websocket_max_payload();
new crow::websocket::Connection<UnixSocketAdaptor, App>(req, std::move(adaptor), app_, max_payload_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
}
#ifdef CROW_ENABLE_SSL
void handle_upgrade(const request& req, response&, SSLAdaptor&& adaptor) override
{
Expand Down
54 changes: 54 additions & 0 deletions include/crow/socket_acceptors.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#pragma once
#ifndef ASIO_STANDALONE
#define ASIO_STANDALONE
#endif
#include <asio.hpp>

namespace crow
{
using tcp = asio::ip::tcp;
using stream_protocol = asio::local::stream_protocol;

struct TCPAcceptor
{
using endpoint = tcp::endpoint;
tcp::acceptor acceptor_;
TCPAcceptor(asio::io_service& io_service, const endpoint& endpoint):
acceptor_(io_service, endpoint) {}

int16_t port() const
{
return acceptor_.local_endpoint().port();
}
std::string url_display(bool ssl_used) const
{
return (ssl_used ? "https://" : "http://") + acceptor_.local_endpoint().address().to_string() + ":" + std::to_string(acceptor_.local_endpoint().port());
}
tcp::acceptor& raw_acceptor()
{
return acceptor_;
}
};

struct UnixSocketAcceptor
{
using endpoint = stream_protocol::endpoint;
stream_protocol::acceptor acceptor_;
UnixSocketAcceptor(asio::io_service& io_service, const endpoint& endpoint):
acceptor_(io_service, endpoint, false) {}
// reuse addr must be false (https://github.com/chriskohlhoff/asio/issues/622)

int16_t port() const
{
return 0;
}
std::string url_display(bool) const
{
return acceptor_.local_endpoint().path();
}
stream_protocol::acceptor& raw_acceptor()
{
return acceptor_;
}
};
} // namespace crow
Loading