kenba / via-httplib Goto Github PK
View Code? Open in Web Editor NEWA library for embedding an HTTP or HTTPS server in C++ applications.
License: Boost Software License 1.0
A library for embedding an HTTP or HTTPS server in C++ applications.
License: Boost Software License 1.0
via/comms/connection.hpp:476:66: error: ‘asio::ip::tcp::socket’ has no member named ‘native’
use native_handle. The method 'native' was deprecated earlier and removed in later versions of asio.
Platform: windows 10 64-bit
The example client crashes during shutdown because the mutex associated withh http_client is closed earlier when the service goes out of scope. The http_client, declared global, destructs after io_service is destructed.
I'll submit a pull request. Hopefully I fixed the problem correctly.
The bool connection::send_data(Container packet)
method isn't currently used so neither is the tx_queue_
member variable.
Since the Container
template variable is only used by send_data
and tx_queue_
, this provides an opportunity to remove the Container
template variable from the connection
class.
C++ 17 introduced hardware_destructive_interference_size as the minimum offset between two objects to avoid false sharing.
This value should be used in the threadsafe_hash_map
class instead of cache_line_size.
I need to reply to a request with data from a file stream. i.e. I don't want to put the entire response in a buffer for the reply. Is there a way to do this that I am not seeing?
When the message_headers
class was changed to take template parameters, the parse
function was not updated.
This effectively fixes MAX_HEADER_NUMBER
to 8 and MAX_HEADER_LENGTH
to 1024.
I have a case where using via-httplib as an HTTPS server, the handshake will fail due to unsupported TLS version/cipher specs:
Client Hello:
Secure Sockets Layer
SSLv2 Record Layer: Client Hello
[Version: SSL 2.0 (0x0002)]
Length: 53
Handshake Message Type: Client Hello (1)
Version: TLS 1.0 (0x0301)
Cipher Spec Length: 12
Session ID Length: 0
Challenge Length: 32
Cipher Specs (4 specs)
Cipher Spec: TLS_RSA_WITH_AES_128_CBC_SHA (0x00002f)
Cipher Spec: TLS_DHE_RSA_WITH_AES_128_CBC_SHA (0x000033)
Cipher Spec: TLS_DHE_DSS_WITH_AES_128_CBC_SHA (0x000032)
Cipher Spec: TLS_DH_anon_WITH_AES_128_CBC_SHA (0x000034)
Challenge
Handshake Failure:
TLSv1 Record Layer: Alert (Level: Fatal, Description: Handshake Failure)
Content Type: Alert (21)
Version: TLS 1.0 (0x0301)
Length: 2
Alert Message
Level: Fatal (2)
Description: Handshake Failure (40)
I think this failure is expected since the client is attempting to use a deprecated version of SSL/ciphers.
The issue is with how the library handles this. Even though the client does not try to reconnect, the error_handler loops indefinitely:
error_handler
asio.ssl:336130315
error_handler
asio.ssl:336462231
error_handler
asio.ssl:336462231
error_handler
asio.ssl:336462231
error_handler
asio.ssl:336462231
error_handler
asio.ssl:336462231
Is there some call that I am missing?
When testing the thread_pool_http_server.cpp
example using Apache Benchmark, the HTTP server crashes, e.g.:
ab -n 10000 -c 1000 192.168.1.64:80/hello
or
ab -n 10000 -c 1000 -k 192.168.1.64:80/hello
The ASIO async_connect
iterator overload is deprecated, see: async_connect.
Use the ASIO async_connect
range overload instead, see: async_connect.
Example file : example_https_server.cpp
Error C4996 'boost::asio::basic_socket<Protocol,StreamSocketService>::cancel': By default, this function always fails with operation_not_supported when used on Windows XP, Windows Server 2003, or earlier. Consult documentation for details. Test_via-http c:\users\johndoe\documents\via-httplib\include\via\comms\ssl\ssl_tcp_adaptor.hpp 188
An SSL server currently can only set the certificate and key from files.
It should also be able to read them from memory.
standalone asio and Boost.Asio have diverged as Chris Kohlhoff concentrates on incorporating changes for the Networking Library Proposal, N4612 in standalone asio. See Niall Douglas's answer here.
Since standalone asio is more "up to date" than boost asio, via-httplib
should give users the choice in the main code base and not just by choosing a (out of date) branch.
In C++20 asio
permits a receive buffer to be a local variable in a coroutine, see: talking-async.
To prepare for migrating to coroutines, a receive event should call a new receive_callback_type
with a pointer to the receive buffer and the number of bytes received, instead of calling the current event_callback_type
with a RECEIVED
event id.
A part of the fix for issue #11 was to add mutexes to server
and http_server
to protect connections_
and http_connections_
respectively during concurrent access.
The mutexes provided a quick and simple solution to the issue but std::mutex
is notoriously slow.
More efficient, thread-safe
(ideally lock free
) containers should be used for connections_
and http_connections_
so that the mutexes can be removed.
Whenever a server accept_handler
receives a new client connection it currently accepts it.
The accept_handler
provides the first opportunity to determine whether to filter (i.e. accept or reject) a client connection depending upon whether client is in an "allowlist" (a.k.a "whitelist") or a "blocklist" (a.k.a. "blacklist").
The server
class should have a new connection filter function pointer, called by the accept_handler
and set able by a new method to enable users to filter client connections before performing an SSL handshake. The default should be to accept all incoming connections.
Hello. I use internal request router in my project, and it works fine. But since I tried to add multithreading, I regularly get error: event_handler error: connection not found
.
And sometimes I got SEGFAULT in via::comms::connection
constructor:
...
rx_buffer_(new Container(rx_buffer_size_, 0))
...
Here is my code snippet:
using http_server_type = via::http_server<via::comms::tcp_adaptor, std::string, true>;
using MethodHandler = std::function<void(const HttpRequest&, HttpResponse&)>;
class RestServer {
...
std::unique_ptr<http_server_type> server_;
std::vector<std::thread> workers_;
ASIO::io_service io_;
};
RestServer::RestServer(uint16_t port, uint8_t maxThreads)
{
server_.reset(new http_server_type(io_));
route("/resource1", resource1_);
route("/resource2", resource2_);
...
start(port, maxThreads);
}
void RestServer::routeMethod(const std::string& path,
via::http::request_method::id method,
MethodHandler handler)
{
auto& router = server_->request_router();
router.add_method(method, path, [handler]
(const via::http::rx_request& req,
const via::http::Parameters& params,
const std::string& data,
std::string& response_body)
{
HttpRequest request(params, data);
HttpResponse response;
// Call my handler
handler(request, response);
via::http::tx_response res(static_cast<via::http::response_status::code>(response.getStatus()));
res.add_header(via::http::header_field::id::CONTENT_TYPE, response.getContentType());
response_body = std::move(response.getBody());
return res;
});
}
void RestServer::route(const std::string& path, HttpResource& resource)
{
using namespace via::http::request_method;
using namespace std::placeholders;
routeMethod(path, GET, std::bind(&HttpResource::onGet, &resource, _1, _2));
routeMethod(path, POST, std::bind(&HttpResource::onPost, &resource, _1, _2));
routeMethod(path, PUT, std::bind(&HttpResource::onPut, &resource, _1, _2));
routeMethod(path, DELETE, std::bind(&HttpResource::onDelete, &resource, _1, _2));
}
void RestServer::start(uint16_t port, uint8_t maxThreads)
{
ASIO_ERROR_CODE error(server_->accept_connections(port));
if (error)
{
LOG_ERROR << error.message();
throw std::runtime_error("Can not start HTTP server");
}
for (uint8_t i = 0; i < maxThreads; i++)
workers_.emplace_back([this] { io_.run(); });
}
So, is it possible to use internal router in multi-threaded server?
Best regards.
Hi!
Here's one serious issue.
If we try to connect to some unopened port on localhost, we end up here:
connection.hpp:181
with errno 111 (connection refused), and go here:
http_client.hpp:188
But the connection_ is not connected() yet, and period_ == 0, so we just do nothing.
And this is a problem, since error just gets ignored and thus client can not handle it.
A part of the fix for issue #11 was to add mutexes to server
and http_server
to protect 'connections_' and http_connections_
respectively during concurrent access.
The mutexes provided a quick and simple solution to the issue but std::mutex
is notoriously slow.
The connections_mutex_
and http_connections_mutex_
should not be locked when use_strand == false
.
I cannot for the life of me figure out what the redundant modulo operator is for on this line:
And on the decode side too.
Every time I do the math, it just comes out redundant. Can you explain it a bit for me?
The OpenSSL
macro SSL_R_SHORT_READ
is not defined in the 1.1.x versions of the library.
This macro is tested in the is_disconnect
function in ssl_tcp_adaptor.hpp
and so it fails to compile when built with 1.1.x versions of the OpenSSL library.
The async_connect
iterator function is deprecated, see: async_connect
The async_connect
range function is preferred, see: async_connect
The comms server
shold use the async_connect
range function instead of the iterator function.
This should enable the next_socket_
member variable to be removed, since the range function callback contains the newly accepted socket.
The HTTP connection
class is only used by the tcp_adaptor
and ssl_tcp_adaptor
which are simply wrappers around the ASIO::ip::tcp::socket
and ASIO::ssl::streamASIO::ip::tcp::socket respectively.
The overall design could be simplified by redesigning the connection
class to use the asio tcp and ssl sockets directly.
The ssl_context()
singleton in the ssl_tcp_adaptor
class prohibits clients and servers in the same application using different ssl_contexts and it limits users to a specific ssl::context::method.
The singleton should be removed and replaced by passing a reference to an ASIO::ssl::context
in the ssl_tcp_adaptor
class constructor.
This change will ripple through all of the connection, server and associated http_client
and http_server
classes requiring all their constructors in HTTP_SSL
mode to take a reference to an ASIO::ssl::context
.
This change will break the API for HTTPS servers and clients.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.