3 #include <unordered_map>
10 #define _CRT_INTERNAL_NONSTDC_NAMES 1
13 #if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
14 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
17 #include "crow/http_request.h"
18 #include "crow/ci_map.h"
19 #include "crow/socket_adaptors.h"
20 #include "crow/logging.h"
21 #include "crow/mime_types.h"
22 #include "crow/returnable.h"
27 template<
typename Adaptor,
typename Handler,
typename... Middlewares>
35 template<
typename Adaptor,
typename Handler,
typename... Middlewares>
44 #ifdef CROW_ENABLE_COMPRESSION
54 headers.emplace(std::move(key), std::move(value));
60 headers.emplace(std::move(key), std::move(value));
63 const std::string& get_header_value(
const std::string& key)
69 static bool validate_mime_type(
const std::string& candidate) noexcept
73 std::array<std::string, 10> valid_parent_types = {
74 "application/",
"audio/",
"font/",
"example/",
75 "image/",
"message/",
"model/",
"multipart/",
77 for (
const std::string& parent : valid_parent_types)
82 if (candidate.size() <= parent.size())
89 if (strncmp(parent.c_str(), candidate.c_str(), parent.size()) == 0)
100 static std::string get_mime_type(
const std::string& contentType)
102 const auto mimeTypeIterator = mime_types.find(contentType);
103 if (mimeTypeIterator != mime_types.end())
105 return mimeTypeIterator->second;
107 else if (validate_mime_type(contentType))
113 CROW_LOG_WARNING <<
"Unable to interpret mime type for content type '" << contentType <<
"'. Defaulting to text/plain.";
121 explicit response(
int code_) :
code(code_) {}
122 response(std::string body_) :
body(std::move(body_)) {}
123 response(
int code_, std::string body_) :
code(code_),
body(std::move(body_)) {}
125 response(returnable&& value)
128 set_header(
"Content-Type", value.content_type);
130 response(returnable& value)
133 set_header(
"Content-Type", value.content_type);
135 response(
int code_, returnable& value):
139 set_header(
"Content-Type", value.content_type);
141 response(
int code_, returnable&& value):
144 set_header(
"Content-Type", std::move(value.content_type));
147 response(response&& r)
149 *
this = std::move(r);
152 response(std::string contentType, std::string body_):
153 body(std::move(body_))
155 set_header(
"Content-Type", get_mime_type(contentType));
158 response(
int code_, std::string contentType, std::string body_):
161 set_header(
"Content-Type", get_mime_type(contentType));
164 response& operator=(
const response& r) =
delete;
166 response& operator=(response&& r) noexcept
168 body = std::move(r.body);
170 headers = std::move(r.headers);
171 completed_ = r.completed_;
172 file_info = std::move(r.file_info);
188 file_info = static_file_info{};
215 void moved(
const std::string& location)
231 void write(
const std::string& body_part)
248 if (complete_request_handler_)
250 complete_request_handler_();
258 void end(
const std::string& body_part)
267 return is_alive_helper_ && is_alive_helper_();
273 return file_info.path.size();
282 std::string path =
"";
290 utility::sanitize_filename(path);
297 file_info.path = path;
298 file_info.statResult = stat(file_info.path.c_str(), &file_info.statbuf);
299 #ifdef CROW_ENABLE_COMPRESSION
302 if (file_info.statResult == 0 && S_ISREG(file_info.statbuf.st_mode))
304 std::size_t last_dot = path.find_last_of(
".");
305 std::string extension = path.substr(last_dot + 1);
307 this->
add_header(
"Content-Length", std::to_string(file_info.statbuf.st_size));
309 if (!extension.empty())
311 this->
add_header(
"Content-Type", get_mime_type(extension));
317 file_info.path.clear();
323 std::function<void()> complete_request_handler_;
324 std::function<bool()> is_alive_helper_;
325 static_file_info file_info;
An HTTP connection.
Definition: http_connection.h:48
Handles matching requests to existing rules and upgrade requests.
Definition: routing.h:1268
The main namespace of the library. In this namespace is defined the most important classes and functi...
const std::string & get_header_value(const T &headers, const std::string &key)
Find and return the value associated with the key. (returns an empty string if nothing is found)
Definition: http_request.h:24
This constains metadata (coming from the stat command) related to any static files associated with th...
Definition: http_response.h:281
HTTP response.
Definition: http_response.h:34
void end(const std::string &body_part)
Same as end() except it adds a body part right before ending.
Definition: http_response.h:258
void add_header(std::string key, std::string value)
Add a new header to the response.
Definition: http_response.h:58
bool skip_body
Whether this is a response to a HEAD request.
Definition: http_response.h:47
void moved(const std::string &location)
Return a "Found (Moved Temporarily)" response.
Definition: http_response.h:215
void set_static_file_info(std::string path)
Return a static file as the response body.
Definition: http_response.h:288
bool manual_length_header
Whether Crow should automatically add a "Content-Length" header.
Definition: http_response.h:48
void redirect_perm(const std::string &location)
Return a "Permanent Redirect" response.
Definition: http_response.h:205
void moved_perm(const std::string &location)
Return a "Moved Permanently" response.
Definition: http_response.h:225
bool is_completed() const noexcept
Check if the response has completed (whether response.end() has been called)
Definition: http_response.h:177
int code
The Status code for the response.
Definition: http_response.h:40
void set_header(std::string key, std::string value)
Set the value of an existing header in the response.
Definition: http_response.h:51
void end()
Set the response completion flag and call the handler (to send the response).
Definition: http_response.h:237
void redirect(const std::string &location)
Return a "Temporary Redirect" response.
Definition: http_response.h:195
bool is_alive()
Check if the connection is still alive (usually by checking the socket status).
Definition: http_response.h:265
void set_static_file_info_unsafe(std::string path)
Return a static file as the response body without sanitizing the path (use set_static_file_info inste...
Definition: http_response.h:295
ci_map headers
HTTP headers.
Definition: http_response.h:42
std::string body
The actual payload containing the response data.
Definition: http_response.h:41
bool compressed
If compression is enabled and this is false, the individual response will not be compressed.
Definition: http_response.h:45
bool is_static_type()
Check whether the response has a static file defined.
Definition: http_response.h:271