mirror of
https://github.com/CrowCpp/Crow.git
synced 2024-06-07 21:10:44 +00:00
commit
b140cdf58b
@ -12,7 +12,7 @@ namespace crow
|
|||||||
{
|
{
|
||||||
namespace detail
|
namespace detail
|
||||||
{
|
{
|
||||||
///Fast timer queue for fixed tick value.
|
/// Fast timer queue for fixed tick value.
|
||||||
class dumb_timer_queue
|
class dumb_timer_queue
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@ -31,6 +31,7 @@ namespace crow
|
|||||||
self->dq_[index].second = nullptr;
|
self->dq_[index].second = nullptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a function to the queue.
|
||||||
key add(std::function<void()> f)
|
key add(std::function<void()> f)
|
||||||
{
|
{
|
||||||
dq_.emplace_back(std::chrono::steady_clock::now(), std::move(f));
|
dq_.emplace_back(std::chrono::steady_clock::now(), std::move(f));
|
||||||
@ -40,6 +41,7 @@ namespace crow
|
|||||||
return {this, ret};
|
return {this, ret};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Process the queue: take functions out in time intervals and execute them.
|
||||||
void process()
|
void process()
|
||||||
{
|
{
|
||||||
if (!io_service_)
|
if (!io_service_)
|
||||||
|
@ -353,7 +353,7 @@ namespace crow
|
|||||||
}
|
}
|
||||||
prepare_buffers();
|
prepare_buffers();
|
||||||
CROW_LOG_INFO << "Response: " << this << ' ' << req_.raw_url << ' ' << res.code << ' ' << close_connection_;
|
CROW_LOG_INFO << "Response: " << this << ' ' << req_.raw_url << ' ' << res.code << ' ' << close_connection_;
|
||||||
if (res.file_info.path.size())
|
if (res.is_static_type())
|
||||||
{
|
{
|
||||||
do_write_static();
|
do_write_static();
|
||||||
}else {
|
}else {
|
||||||
|
@ -8,6 +8,7 @@
|
|||||||
|
|
||||||
namespace crow
|
namespace crow
|
||||||
{
|
{
|
||||||
|
/// Find and return the value associated with the key. (returns an empty string if nothing is found)
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline const std::string& get_header_value(const T& headers, const std::string& key)
|
inline const std::string& get_header_value(const T& headers, const std::string& key)
|
||||||
{
|
{
|
||||||
@ -21,24 +22,27 @@ namespace crow
|
|||||||
|
|
||||||
struct DetachHelper;
|
struct DetachHelper;
|
||||||
|
|
||||||
|
/// An HTTP request.
|
||||||
struct request
|
struct request
|
||||||
{
|
{
|
||||||
HTTPMethod method;
|
HTTPMethod method;
|
||||||
std::string raw_url;
|
std::string raw_url; /// The full URL containing the host.
|
||||||
std::string url;
|
std::string url; /// The Endpoint.
|
||||||
query_string url_params;
|
query_string url_params; /// The parameters associated with the request. (everything after the `?`)
|
||||||
ci_map headers;
|
ci_map headers;
|
||||||
std::string body;
|
std::string body;
|
||||||
std::string remoteIpAddress;
|
std::string remoteIpAddress; /// The IP address from which the request was sent.
|
||||||
|
|
||||||
void* middleware_context{};
|
void* middleware_context{};
|
||||||
boost::asio::io_service* io_service{};
|
boost::asio::io_service* io_service{};
|
||||||
|
|
||||||
|
/// Construct an empty request. (sets the method to `GET`)
|
||||||
request()
|
request()
|
||||||
: method(HTTPMethod::Get)
|
: method(HTTPMethod::Get)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Construct a request with all values assigned.
|
||||||
request(HTTPMethod method, std::string raw_url, std::string url, query_string url_params, ci_map headers, std::string body)
|
request(HTTPMethod method, std::string raw_url, std::string url, query_string url_params, ci_map headers, std::string body)
|
||||||
: method(method), raw_url(std::move(raw_url)), url(std::move(url)), url_params(std::move(url_params)), headers(std::move(headers)), body(std::move(body))
|
: method(method), raw_url(std::move(raw_url)), url(std::move(url)), url_params(std::move(url_params)), headers(std::move(headers)), body(std::move(body))
|
||||||
{
|
{
|
||||||
@ -54,12 +58,14 @@ namespace crow
|
|||||||
return crow::get_header_value(headers, key);
|
return crow::get_header_value(headers, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send the request with a completion handler and return immediately.
|
||||||
template<typename CompletionHandler>
|
template<typename CompletionHandler>
|
||||||
void post(CompletionHandler handler)
|
void post(CompletionHandler handler)
|
||||||
{
|
{
|
||||||
io_service->post(handler);
|
io_service->post(handler);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Send the request with a completion handler.
|
||||||
template<typename CompletionHandler>
|
template<typename CompletionHandler>
|
||||||
void dispatch(CompletionHandler handler)
|
void dispatch(CompletionHandler handler)
|
||||||
{
|
{
|
||||||
|
@ -19,23 +19,26 @@ namespace crow
|
|||||||
{
|
{
|
||||||
template <typename Adaptor, typename Handler, typename ... Middlewares>
|
template <typename Adaptor, typename Handler, typename ... Middlewares>
|
||||||
class Connection;
|
class Connection;
|
||||||
|
|
||||||
|
/// HTTP response
|
||||||
struct response
|
struct response
|
||||||
{
|
{
|
||||||
template <typename Adaptor, typename Handler, typename ... Middlewares>
|
template <typename Adaptor, typename Handler, typename ... Middlewares>
|
||||||
friend class crow::Connection;
|
friend class crow::Connection;
|
||||||
|
|
||||||
int code{200};
|
int code{200}; /// The Status code for the response.
|
||||||
std::string body;
|
std::string body; /// The actual payload containing the response data.
|
||||||
json::wvalue json_value;
|
json::wvalue json_value; /// if the response body is JSON, this would be it.
|
||||||
|
ci_map headers; /// HTTP headers.
|
||||||
// `headers' stores HTTP headers.
|
|
||||||
ci_map headers;
|
|
||||||
|
|
||||||
|
/// Set the value of an existing header in the response.
|
||||||
void set_header(std::string key, std::string value)
|
void set_header(std::string key, std::string value)
|
||||||
{
|
{
|
||||||
headers.erase(key);
|
headers.erase(key);
|
||||||
headers.emplace(std::move(key), std::move(value));
|
headers.emplace(std::move(key), std::move(value));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Add a new header to the response.
|
||||||
void add_header(std::string key, std::string value)
|
void add_header(std::string key, std::string value)
|
||||||
{
|
{
|
||||||
headers.emplace(std::move(key), std::move(value));
|
headers.emplace(std::move(key), std::move(value));
|
||||||
@ -81,6 +84,7 @@ namespace crow
|
|||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the response has completed (whether response.end() has been called)
|
||||||
bool is_completed() const noexcept
|
bool is_completed() const noexcept
|
||||||
{
|
{
|
||||||
return completed_;
|
return completed_;
|
||||||
@ -106,6 +110,7 @@ namespace crow
|
|||||||
body += body_part;
|
body += body_part;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Set the response completion flag and call the handler (to send the response).
|
||||||
void end()
|
void end()
|
||||||
{
|
{
|
||||||
if (!completed_)
|
if (!completed_)
|
||||||
@ -119,27 +124,34 @@ namespace crow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Same as end() except it adds a body part right before ending.
|
||||||
void end(const std::string& body_part)
|
void end(const std::string& body_part)
|
||||||
{
|
{
|
||||||
body += body_part;
|
body += body_part;
|
||||||
end();
|
end();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Check if the connection is still alive (usually by checking the socket status).
|
||||||
bool is_alive()
|
bool is_alive()
|
||||||
{
|
{
|
||||||
return is_alive_helper_ && is_alive_helper_();
|
return is_alive_helper_ && is_alive_helper_();
|
||||||
}
|
}
|
||||||
/* adding static file support here
|
|
||||||
* middlware must call res.set_static_file_info(filename)
|
|
||||||
* you must add route starting with /your/restricted/path/<string>
|
|
||||||
*/
|
|
||||||
|
|
||||||
|
/// Check whether the response has a static file defined.
|
||||||
|
bool is_static_type()
|
||||||
|
{
|
||||||
|
return file_info.path.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
/// This constains metadata (coming from the `stat` command) related to any static files associated with this response.
|
||||||
|
|
||||||
|
/// Either a static file or a string body can be returned as 1 response.
|
||||||
|
///
|
||||||
struct static_file_info{
|
struct static_file_info{
|
||||||
std::string path = "";
|
std::string path = "";
|
||||||
struct stat statbuf;
|
struct stat statbuf;
|
||||||
int statResult;
|
int statResult;
|
||||||
};
|
};
|
||||||
static_file_info file_info;
|
|
||||||
|
|
||||||
///Return a static file as the response body
|
///Return a static file as the response body
|
||||||
void set_static_file_info(std::string path){
|
void set_static_file_info(std::string path){
|
||||||
@ -168,6 +180,7 @@ namespace crow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stream a static file.
|
||||||
template<typename Adaptor>
|
template<typename Adaptor>
|
||||||
void do_stream_file(Adaptor& adaptor)
|
void do_stream_file(Adaptor& adaptor)
|
||||||
{
|
{
|
||||||
@ -178,6 +191,7 @@ namespace crow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Stream the response body (send the body in chunks).
|
||||||
template<typename Adaptor>
|
template<typename Adaptor>
|
||||||
void do_stream_body(Adaptor& adaptor)
|
void do_stream_body(Adaptor& adaptor)
|
||||||
{
|
{
|
||||||
@ -187,13 +201,13 @@ namespace crow
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* static file support end */
|
|
||||||
private:
|
private:
|
||||||
bool completed_{};
|
bool completed_{};
|
||||||
std::function<void()> complete_request_handler_;
|
std::function<void()> complete_request_handler_;
|
||||||
std::function<bool()> is_alive_helper_;
|
std::function<bool()> is_alive_helper_;
|
||||||
|
static_file_info file_info;
|
||||||
|
|
||||||
//In case of a JSON object, set the Content-Type header
|
/// In case of a JSON object, set the Content-Type header.
|
||||||
void json_mode()
|
void json_mode()
|
||||||
{
|
{
|
||||||
set_header("Content-Type", "application/json");
|
set_header("Content-Type", "application/json");
|
||||||
|
@ -14,6 +14,7 @@ namespace crow
|
|||||||
using namespace boost;
|
using namespace boost;
|
||||||
using tcp = asio::ip::tcp;
|
using tcp = asio::ip::tcp;
|
||||||
|
|
||||||
|
///A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
|
||||||
struct SocketAdaptor
|
struct SocketAdaptor
|
||||||
{
|
{
|
||||||
using context = void;
|
using context = void;
|
||||||
@ -27,11 +28,13 @@ namespace crow
|
|||||||
return GET_IO_SERVICE(socket_);
|
return GET_IO_SERVICE(socket_);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the TCP socket handling data trasfers, regardless of what layer is handling transfers on top of the socket.
|
||||||
tcp::socket& raw_socket()
|
tcp::socket& raw_socket()
|
||||||
{
|
{
|
||||||
return socket_;
|
return socket_;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Get the object handling data transfers, this can be either a TCP socket or an SSL stream (if SSL is enabled).
|
||||||
tcp::socket& socket()
|
tcp::socket& socket()
|
||||||
{
|
{
|
||||||
return socket_;
|
return socket_;
|
||||||
|
Loading…
Reference in New Issue
Block a user