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
|
||||
{
|
||||
///Fast timer queue for fixed tick value.
|
||||
/// Fast timer queue for fixed tick value.
|
||||
class dumb_timer_queue
|
||||
{
|
||||
public:
|
||||
@ -31,6 +31,7 @@ namespace crow
|
||||
self->dq_[index].second = nullptr;
|
||||
}
|
||||
|
||||
/// Add a function to the queue.
|
||||
key add(std::function<void()> f)
|
||||
{
|
||||
dq_.emplace_back(std::chrono::steady_clock::now(), std::move(f));
|
||||
@ -40,6 +41,7 @@ namespace crow
|
||||
return {this, ret};
|
||||
}
|
||||
|
||||
/// Process the queue: take functions out in time intervals and execute them.
|
||||
void process()
|
||||
{
|
||||
if (!io_service_)
|
||||
|
@ -353,7 +353,7 @@ namespace crow
|
||||
}
|
||||
prepare_buffers();
|
||||
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();
|
||||
}else {
|
||||
|
@ -8,6 +8,7 @@
|
||||
|
||||
namespace crow
|
||||
{
|
||||
/// Find and return the value associated with the key. (returns an empty string if nothing is found)
|
||||
template <typename T>
|
||||
inline const std::string& get_header_value(const T& headers, const std::string& key)
|
||||
{
|
||||
@ -21,24 +22,27 @@ namespace crow
|
||||
|
||||
struct DetachHelper;
|
||||
|
||||
/// An HTTP request.
|
||||
struct request
|
||||
{
|
||||
HTTPMethod method;
|
||||
std::string raw_url;
|
||||
std::string url;
|
||||
query_string url_params;
|
||||
std::string raw_url; /// The full URL containing the host.
|
||||
std::string url; /// The Endpoint.
|
||||
query_string url_params; /// The parameters associated with the request. (everything after the `?`)
|
||||
ci_map headers;
|
||||
std::string body;
|
||||
std::string remoteIpAddress;
|
||||
std::string remoteIpAddress; /// The IP address from which the request was sent.
|
||||
|
||||
void* middleware_context{};
|
||||
boost::asio::io_service* io_service{};
|
||||
|
||||
/// Construct an empty request. (sets the method to `GET`)
|
||||
request()
|
||||
: 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)
|
||||
: 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);
|
||||
}
|
||||
|
||||
/// Send the request with a completion handler and return immediately.
|
||||
template<typename CompletionHandler>
|
||||
void post(CompletionHandler handler)
|
||||
{
|
||||
io_service->post(handler);
|
||||
}
|
||||
|
||||
/// Send the request with a completion handler.
|
||||
template<typename CompletionHandler>
|
||||
void dispatch(CompletionHandler handler)
|
||||
{
|
||||
|
@ -19,23 +19,26 @@ namespace crow
|
||||
{
|
||||
template <typename Adaptor, typename Handler, typename ... Middlewares>
|
||||
class Connection;
|
||||
|
||||
/// HTTP response
|
||||
struct response
|
||||
{
|
||||
template <typename Adaptor, typename Handler, typename ... Middlewares>
|
||||
friend class crow::Connection;
|
||||
|
||||
int code{200};
|
||||
std::string body;
|
||||
json::wvalue json_value;
|
||||
|
||||
// `headers' stores HTTP headers.
|
||||
ci_map headers;
|
||||
int code{200}; /// The Status code for the response.
|
||||
std::string body; /// The actual payload containing the response data.
|
||||
json::wvalue json_value; /// if the response body is JSON, this would be it.
|
||||
ci_map headers; /// HTTP headers.
|
||||
|
||||
/// Set the value of an existing header in the response.
|
||||
void set_header(std::string key, std::string value)
|
||||
{
|
||||
headers.erase(key);
|
||||
headers.emplace(std::move(key), std::move(value));
|
||||
}
|
||||
|
||||
/// Add a new header to the response.
|
||||
void add_header(std::string key, std::string value)
|
||||
{
|
||||
headers.emplace(std::move(key), std::move(value));
|
||||
@ -81,6 +84,7 @@ namespace crow
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// Check if the response has completed (whether response.end() has been called)
|
||||
bool is_completed() const noexcept
|
||||
{
|
||||
return completed_;
|
||||
@ -106,6 +110,7 @@ namespace crow
|
||||
body += body_part;
|
||||
}
|
||||
|
||||
/// Set the response completion flag and call the handler (to send the response).
|
||||
void end()
|
||||
{
|
||||
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)
|
||||
{
|
||||
body += body_part;
|
||||
end();
|
||||
}
|
||||
|
||||
/// Check if the connection is still alive (usually by checking the socket status).
|
||||
bool is_alive()
|
||||
{
|
||||
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{
|
||||
std::string path = "";
|
||||
struct stat statbuf;
|
||||
int statResult;
|
||||
};
|
||||
static_file_info file_info;
|
||||
|
||||
///Return a static file as the response body
|
||||
void set_static_file_info(std::string path){
|
||||
@ -168,6 +180,7 @@ namespace crow
|
||||
}
|
||||
}
|
||||
|
||||
/// Stream a static file.
|
||||
template<typename 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>
|
||||
void do_stream_body(Adaptor& adaptor)
|
||||
{
|
||||
@ -187,13 +201,13 @@ namespace crow
|
||||
}
|
||||
}
|
||||
|
||||
/* static file support end */
|
||||
private:
|
||||
bool completed_{};
|
||||
std::function<void()> complete_request_handler_;
|
||||
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()
|
||||
{
|
||||
set_header("Content-Type", "application/json");
|
||||
|
@ -14,6 +14,7 @@ namespace crow
|
||||
using namespace boost;
|
||||
using tcp = asio::ip::tcp;
|
||||
|
||||
///A wrapper for the asio::ip::tcp::socket and asio::ssl::stream
|
||||
struct SocketAdaptor
|
||||
{
|
||||
using context = void;
|
||||
@ -27,11 +28,13 @@ namespace crow
|
||||
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()
|
||||
{
|
||||
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()
|
||||
{
|
||||
return socket_;
|
||||
|
Loading…
Reference in New Issue
Block a user