methods()
: crow::CORSRules
diff --git a/master/reference/functions_rela.html b/master/reference/functions_rela.html
index 8e7f2b53e..db446f13c 100644
--- a/master/reference/functions_rela.html
+++ b/master/reference/functions_rela.html
@@ -97,7 +97,7 @@
diff --git a/master/reference/http__connection_8h_source.html b/master/reference/http__connection_8h_source.html
index 5654660b3..469de2ca4 100644
--- a/master/reference/http__connection_8h_source.html
+++ b/master/reference/http__connection_8h_source.html
@@ -145,7 +145,7 @@
46 template<
typename Adaptor,
typename Handler,
typename... Middlewares>
- 47 class Connection:
public std::enable_shared_from_this<Connection<Adaptor, Handler, Middlewares...>>
+ 47 class Connection :
public std::enable_shared_from_this<Connection<Adaptor, Handler, Middlewares...>>
@@ -295,448 +295,447 @@
- 197 auto self = this->shared_from_this();
- 198 res.complete_request_handler_ = [
self] {
- 199 self->complete_request();
-
- 201 need_to_call_after_handlers_ =
true;
- 202 handler_->handle(req_, res, routing_handle_result_);
-
- 204 res.set_header(
"connection",
"Keep-Alive");
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 220 CROW_LOG_INFO <<
"Response: " <<
this <<
' ' << req_.raw_url <<
' ' << res.code <<
' ' << close_connection_;
- 221 res.is_alive_helper_ =
nullptr;
-
- 223 if (need_to_call_after_handlers_)
-
- 225 need_to_call_after_handlers_ =
false;
-
-
- 228 detail::after_handlers_call_helper<
-
- 230 (
static_cast<int>(
sizeof...(Middlewares)) - 1),
-
- 232 decltype(*middlewares_)>({}, *middlewares_, ctx_, req_, res);
-
- 234 #ifdef CROW_ENABLE_COMPRESSION
- 235 if (handler_->compression_used())
-
- 237 std::string accept_encoding = req_.get_header_value(
"Accept-Encoding");
- 238 if (!accept_encoding.empty() && res.compressed)
-
- 240 switch (handler_->compression_algorithm())
-
- 242 case compression::DEFLATE:
- 243 if (accept_encoding.find(
"deflate") != std::string::npos)
-
- 245 res.body = compression::compress_string(res.body, compression::algorithm::DEFLATE);
- 246 res.set_header(
"Content-Encoding",
"deflate");
-
-
- 249 case compression::GZIP:
- 250 if (accept_encoding.find(
"gzip") != std::string::npos)
-
- 252 res.body = compression::compress_string(res.body, compression::algorithm::GZIP);
- 253 res.set_header(
"Content-Encoding",
"gzip");
-
-
-
-
-
-
-
-
-
- 263 std::string location = res.get_header_value(
"Location");
- 264 if (!location.empty() && location.find(
"://", 0) == std::string::npos)
-
- 266 #ifdef CROW_ENABLE_SSL
- 267 if (handler_->ssl_used())
- 268 location.insert(0,
"https://" + req_.get_header_value(
"Host"));
-
-
- 271 location.insert(0,
"http://" + req_.get_header_value(
"Host"));
- 272 res.set_header(
"location", location);
-
-
-
-
- 277 if (res.is_static_type())
-
-
-
-
-
-
-
-
-
-
- 288 void prepare_buffers()
-
- 290 res.complete_request_handler_ =
nullptr;
- 291 res.is_alive_helper_ =
nullptr;
-
- 293 if (!adaptor_.is_open())
-
-
-
-
-
-
-
- 301 static std::unordered_map<int, std::string> statusCodes = {
- 302 {status::CONTINUE,
"HTTP/1.1 100 Continue\r\n"},
- 303 {status::SWITCHING_PROTOCOLS,
"HTTP/1.1 101 Switching Protocols\r\n"},
-
- 305 {status::OK,
"HTTP/1.1 200 OK\r\n"},
- 306 {status::CREATED,
"HTTP/1.1 201 Created\r\n"},
- 307 {status::ACCEPTED,
"HTTP/1.1 202 Accepted\r\n"},
- 308 {status::NON_AUTHORITATIVE_INFORMATION,
"HTTP/1.1 203 Non-Authoritative Information\r\n"},
- 309 {status::NO_CONTENT,
"HTTP/1.1 204 No Content\r\n"},
- 310 {status::RESET_CONTENT,
"HTTP/1.1 205 Reset Content\r\n"},
- 311 {status::PARTIAL_CONTENT,
"HTTP/1.1 206 Partial Content\r\n"},
-
- 313 {status::MULTIPLE_CHOICES,
"HTTP/1.1 300 Multiple Choices\r\n"},
- 314 {status::MOVED_PERMANENTLY,
"HTTP/1.1 301 Moved Permanently\r\n"},
- 315 {status::FOUND,
"HTTP/1.1 302 Found\r\n"},
- 316 {status::SEE_OTHER,
"HTTP/1.1 303 See Other\r\n"},
- 317 {status::NOT_MODIFIED,
"HTTP/1.1 304 Not Modified\r\n"},
- 318 {status::TEMPORARY_REDIRECT,
"HTTP/1.1 307 Temporary Redirect\r\n"},
- 319 {status::PERMANENT_REDIRECT,
"HTTP/1.1 308 Permanent Redirect\r\n"},
-
- 321 {status::BAD_REQUEST,
"HTTP/1.1 400 Bad Request\r\n"},
- 322 {status::UNAUTHORIZED,
"HTTP/1.1 401 Unauthorized\r\n"},
- 323 {status::FORBIDDEN,
"HTTP/1.1 403 Forbidden\r\n"},
- 324 {status::NOT_FOUND,
"HTTP/1.1 404 Not Found\r\n"},
- 325 {status::METHOD_NOT_ALLOWED,
"HTTP/1.1 405 Method Not Allowed\r\n"},
- 326 {status::NOT_ACCEPTABLE,
"HTTP/1.1 406 Not Acceptable\r\n"},
- 327 {status::PROXY_AUTHENTICATION_REQUIRED,
"HTTP/1.1 407 Proxy Authentication Required\r\n"},
- 328 {status::CONFLICT,
"HTTP/1.1 409 Conflict\r\n"},
- 329 {status::GONE,
"HTTP/1.1 410 Gone\r\n"},
- 330 {status::PAYLOAD_TOO_LARGE,
"HTTP/1.1 413 Payload Too Large\r\n"},
- 331 {status::UNSUPPORTED_MEDIA_TYPE,
"HTTP/1.1 415 Unsupported Media Type\r\n"},
- 332 {status::RANGE_NOT_SATISFIABLE,
"HTTP/1.1 416 Range Not Satisfiable\r\n"},
- 333 {status::EXPECTATION_FAILED,
"HTTP/1.1 417 Expectation Failed\r\n"},
- 334 {status::PRECONDITION_REQUIRED,
"HTTP/1.1 428 Precondition Required\r\n"},
- 335 {status::TOO_MANY_REQUESTS,
"HTTP/1.1 429 Too Many Requests\r\n"},
- 336 {status::UNAVAILABLE_FOR_LEGAL_REASONS,
"HTTP/1.1 451 Unavailable For Legal Reasons\r\n"},
-
- 338 {status::INTERNAL_SERVER_ERROR,
"HTTP/1.1 500 Internal Server Error\r\n"},
- 339 {status::NOT_IMPLEMENTED,
"HTTP/1.1 501 Not Implemented\r\n"},
- 340 {status::BAD_GATEWAY,
"HTTP/1.1 502 Bad Gateway\r\n"},
- 341 {status::SERVICE_UNAVAILABLE,
"HTTP/1.1 503 Service Unavailable\r\n"},
- 342 {status::GATEWAY_TIMEOUT,
"HTTP/1.1 504 Gateway Timeout\r\n"},
- 343 {status::VARIANT_ALSO_NEGOTIATES,
"HTTP/1.1 506 Variant Also Negotiates\r\n"},
-
-
- 346 static const std::string seperator =
": ";
-
-
- 349 buffers_.reserve(4 * (res.headers.size() + 5) + 3);
-
- 351 if (!statusCodes.count(res.code))
-
- 353 CROW_LOG_WARNING <<
this <<
" status code "
- 354 <<
"(" << res.code <<
")"
- 355 <<
" not defined, returning 500 instead";
-
-
-
- 359 auto& status = statusCodes.find(res.code)->second;
- 360 buffers_.emplace_back(status.data(), status.size());
-
- 362 if (res.code >= 400 && res.body.empty())
- 363 res.body = statusCodes[res.code].substr(9);
-
- 365 for (
auto& kv : res.headers)
-
- 367 buffers_.emplace_back(kv.first.data(), kv.first.size());
- 368 buffers_.emplace_back(seperator.data(), seperator.size());
- 369 buffers_.emplace_back(kv.second.data(), kv.second.size());
- 370 buffers_.emplace_back(crlf.data(), crlf.size());
-
-
- 373 if (!res.manual_length_header && !res.headers.count(
"content-length"))
-
- 375 content_length_ = std::to_string(res.body.size());
- 376 static std::string content_length_tag =
"Content-Length: ";
- 377 buffers_.emplace_back(content_length_tag.data(), content_length_tag.size());
- 378 buffers_.emplace_back(content_length_.data(), content_length_.size());
- 379 buffers_.emplace_back(crlf.data(), crlf.size());
-
- 381 if (!res.headers.count(
"server"))
-
- 383 static std::string server_tag =
"Server: ";
- 384 buffers_.emplace_back(server_tag.data(), server_tag.size());
- 385 buffers_.emplace_back(server_name_.data(), server_name_.size());
- 386 buffers_.emplace_back(crlf.data(), crlf.size());
-
- 388 if (!res.headers.count(
"date"))
-
- 390 static std::string date_tag =
"Date: ";
- 391 date_str_ = get_cached_date_str();
- 392 buffers_.emplace_back(date_tag.data(), date_tag.size());
- 393 buffers_.emplace_back(date_str_.data(), date_str_.size());
- 394 buffers_.emplace_back(crlf.data(), crlf.size());
-
-
-
- 398 static std::string keep_alive_tag =
"Connection: Keep-Alive";
- 399 buffers_.emplace_back(keep_alive_tag.data(), keep_alive_tag.size());
- 400 buffers_.emplace_back(crlf.data(), crlf.size());
-
-
- 403 buffers_.emplace_back(crlf.data(), crlf.size());
-
-
- 406 void do_write_static()
-
- 408 asio::write(adaptor_.socket(), buffers_);
-
- 410 if (res.file_info.statResult == 0)
-
- 412 std::ifstream is(res.file_info.path.c_str(), std::ios::in | std::ios::binary);
- 413 std::vector<asio::const_buffer> buffers{1};
-
- 415 is.read(buf,
sizeof(buf));
- 416 while (is.gcount() > 0)
-
- 418 buffers[0] = asio::buffer(buf, is.gcount());
- 419 do_write_sync(buffers);
- 420 is.read(buf,
sizeof(buf));
-
-
- 423 if (close_connection_)
-
- 425 adaptor_.shutdown_readwrite();
-
- 427 CROW_LOG_DEBUG <<
this <<
" from write (static)";
-
-
-
-
-
-
-
-
- 436 void do_write_general()
-
- 438 if (res.body.length() < res_stream_threshold_)
-
- 440 res_body_copy_.swap(res.body);
- 441 buffers_.emplace_back(res_body_copy_.data(), res_body_copy_.size());
-
-
-
- 445 if (need_to_start_read_after_complete_)
-
- 447 need_to_start_read_after_complete_ =
false;
-
-
-
-
-
-
- 454 asio::write(adaptor_.socket(), buffers_);
- 455 cancel_deadline_timer();
- 456 if (res.body.length() > 0)
-
- 458 std::vector<asio::const_buffer> buffers{1};
- 459 const uint8_t *data =
reinterpret_cast<const uint8_t*
>(res.body.data());
- 460 size_t length = res.body.length();
- 461 for(
size_t transferred = 0; transferred < length;)
-
- 463 size_t to_transfer = CROW_MIN(16384UL, length-transferred);
- 464 buffers[0] = asio::const_buffer(data+transferred, to_transfer);
- 465 do_write_sync(buffers);
- 466 transferred += to_transfer;
-
-
- 469 if (close_connection_)
-
- 471 adaptor_.shutdown_readwrite();
-
- 473 CROW_LOG_DEBUG <<
this <<
" from write (res_stream)";
-
-
-
-
-
-
-
-
-
-
-
- 485 auto self = this->shared_from_this();
- 486 adaptor_.socket().async_read_some(
- 487 asio::buffer(buffer_),
- 488 [
self](
const error_code& ec, std::size_t bytes_transferred) {
- 489 bool error_while_reading =
true;
-
-
- 492 bool ret =
self->parser_.feed(self->buffer_.data(), bytes_transferred);
- 493 if (ret && self->adaptor_.is_open())
-
- 495 error_while_reading = false;
-
-
-
- 499 if (error_while_reading)
-
- 501 self->cancel_deadline_timer();
- 502 self->parser_.done();
- 503 self->adaptor_.shutdown_read();
- 504 self->adaptor_.close();
- 505 CROW_LOG_DEBUG <<
self <<
" from read(1) with description: \"" << http_errno_description(
static_cast<http_errno
>(self->parser_.http_errno)) <<
'\"';
-
- 507 else if (self->close_connection_)
-
- 509 self->cancel_deadline_timer();
- 510 self->parser_.done();
-
-
- 513 else if (!self->need_to_call_after_handlers_)
-
- 515 self->start_deadline();
-
-
-
-
-
- 521 self->need_to_start_read_after_complete_ =
true;
-
-
-
-
-
-
- 528 auto self = this->shared_from_this();
-
- 530 adaptor_.socket(), buffers_,
- 531 [
self](
const error_code& ec, std::size_t ) {
-
- 533 self->res_body_copy_.clear();
- 534 if (!self->continue_requested)
-
- 536 self->parser_.clear();
-
-
-
- 540 self->continue_requested = false;
-
-
-
-
- 545 if (self->close_connection_)
-
- 547 self->adaptor_.shutdown_write();
- 548 self->adaptor_.close();
- 549 CROW_LOG_DEBUG << self <<
" from write(1)";
-
-
-
-
- 554 CROW_LOG_DEBUG <<
self <<
" from write(2)";
-
-
-
-
- 559 inline void do_write_sync(std::vector<asio::const_buffer>& buffers)
-
-
- 562 asio::write(adaptor_.socket(), buffers, [&](error_code ec, std::size_t) {
-
-
-
-
-
-
- 569 CROW_LOG_ERROR << ec <<
" - happened while sending buffers";
- 570 CROW_LOG_DEBUG << this <<
" from write (sync)(2)";
-
-
-
-
-
- 576 void cancel_deadline_timer()
-
- 578 CROW_LOG_DEBUG <<
this <<
" timer cancelled: " << &task_timer_ <<
' ' << task_id_;
- 579 task_timer_.cancel(task_id_);
-
-
- 582 void start_deadline()
-
- 584 cancel_deadline_timer();
-
- 586 auto self = this->shared_from_this();
- 587 task_id_ = task_timer_.schedule([
self] {
- 588 if (!self->adaptor_.is_open())
-
-
-
- 592 self->adaptor_.shutdown_readwrite();
- 593 self->adaptor_.close();
-
- 595 CROW_LOG_DEBUG <<
this <<
" timer added: " << &task_timer_ <<
' ' << task_id_;
-
-
-
-
-
-
- 602 std::array<char, 4096> buffer_;
-
- 604 HTTPParser<Connection> parser_;
- 605 std::unique_ptr<routing_handle_result> routing_handle_result_;
-
-
-
- 609 bool close_connection_ =
false;
-
- 611 const std::string& server_name_;
- 612 std::vector<asio::const_buffer> buffers_;
-
- 614 std::string content_length_;
- 615 std::string date_str_;
- 616 std::string res_body_copy_;
-
- 618 detail::task_timer::identifier_type task_id_{};
-
- 620 bool continue_requested{};
- 621 bool need_to_call_after_handlers_{};
- 622 bool need_to_start_read_after_complete_{};
- 623 bool add_keep_alive_{};
-
- 625 std::tuple<Middlewares...>* middlewares_;
- 626 detail::context<Middlewares...> ctx_;
-
- 628 std::function<std::string()>& get_cached_date_str;
- 629 detail::task_timer& task_timer_;
-
- 631 size_t res_stream_threshold_;
-
- 633 std::atomic<unsigned int>& queue_length_;
-
-
-
+ 197 res.complete_request_handler_ = [
self] {
+ 198 self->complete_request();
+
+ 200 need_to_call_after_handlers_ =
true;
+ 201 handler_->handle(req_, res, routing_handle_result_);
+
+ 203 res.set_header(
"connection",
"Keep-Alive");
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 219 CROW_LOG_INFO <<
"Response: " <<
this <<
' ' << req_.raw_url <<
' ' << res.code <<
' ' << close_connection_;
+ 220 res.is_alive_helper_ =
nullptr;
+
+ 222 if (need_to_call_after_handlers_)
+
+ 224 need_to_call_after_handlers_ =
false;
+
+
+ 227 detail::after_handlers_call_helper<
+
+ 229 (
static_cast<int>(
sizeof...(Middlewares)) - 1),
+
+ 231 decltype(*middlewares_)>({}, *middlewares_, ctx_, req_, res);
+
+ 233 #ifdef CROW_ENABLE_COMPRESSION
+ 234 if (handler_->compression_used())
+
+ 236 std::string accept_encoding = req_.get_header_value(
"Accept-Encoding");
+ 237 if (!accept_encoding.empty() && res.compressed)
+
+ 239 switch (handler_->compression_algorithm())
+
+ 241 case compression::DEFLATE:
+ 242 if (accept_encoding.find(
"deflate") != std::string::npos)
+
+ 244 res.body = compression::compress_string(res.body, compression::algorithm::DEFLATE);
+ 245 res.set_header(
"Content-Encoding",
"deflate");
+
+
+ 248 case compression::GZIP:
+ 249 if (accept_encoding.find(
"gzip") != std::string::npos)
+
+ 251 res.body = compression::compress_string(res.body, compression::algorithm::GZIP);
+ 252 res.set_header(
"Content-Encoding",
"gzip");
+
+
+
+
+
+
+
+
+
+ 262 std::string location = res.get_header_value(
"Location");
+ 263 if (!location.empty() && location.find(
"://", 0) == std::string::npos)
+
+ 265 #ifdef CROW_ENABLE_SSL
+ 266 if (handler_->ssl_used())
+ 267 location.insert(0,
"https://" + req_.get_header_value(
"Host"));
+
+
+ 270 location.insert(0,
"http://" + req_.get_header_value(
"Host"));
+ 271 res.set_header(
"location", location);
+
+
+
+
+ 276 if (res.is_static_type())
+
+
+
+
+
+
+
+
+
+
+ 287 void prepare_buffers()
+
+ 289 res.complete_request_handler_ =
nullptr;
+ 290 res.is_alive_helper_ =
nullptr;
+
+ 292 if (!adaptor_.is_open())
+
+
+
+
+
+
+
+ 300 static std::unordered_map<int, std::string> statusCodes = {
+ 301 {status::CONTINUE,
"HTTP/1.1 100 Continue\r\n"},
+ 302 {status::SWITCHING_PROTOCOLS,
"HTTP/1.1 101 Switching Protocols\r\n"},
+
+ 304 {status::OK,
"HTTP/1.1 200 OK\r\n"},
+ 305 {status::CREATED,
"HTTP/1.1 201 Created\r\n"},
+ 306 {status::ACCEPTED,
"HTTP/1.1 202 Accepted\r\n"},
+ 307 {status::NON_AUTHORITATIVE_INFORMATION,
"HTTP/1.1 203 Non-Authoritative Information\r\n"},
+ 308 {status::NO_CONTENT,
"HTTP/1.1 204 No Content\r\n"},
+ 309 {status::RESET_CONTENT,
"HTTP/1.1 205 Reset Content\r\n"},
+ 310 {status::PARTIAL_CONTENT,
"HTTP/1.1 206 Partial Content\r\n"},
+
+ 312 {status::MULTIPLE_CHOICES,
"HTTP/1.1 300 Multiple Choices\r\n"},
+ 313 {status::MOVED_PERMANENTLY,
"HTTP/1.1 301 Moved Permanently\r\n"},
+ 314 {status::FOUND,
"HTTP/1.1 302 Found\r\n"},
+ 315 {status::SEE_OTHER,
"HTTP/1.1 303 See Other\r\n"},
+ 316 {status::NOT_MODIFIED,
"HTTP/1.1 304 Not Modified\r\n"},
+ 317 {status::TEMPORARY_REDIRECT,
"HTTP/1.1 307 Temporary Redirect\r\n"},
+ 318 {status::PERMANENT_REDIRECT,
"HTTP/1.1 308 Permanent Redirect\r\n"},
+
+ 320 {status::BAD_REQUEST,
"HTTP/1.1 400 Bad Request\r\n"},
+ 321 {status::UNAUTHORIZED,
"HTTP/1.1 401 Unauthorized\r\n"},
+ 322 {status::FORBIDDEN,
"HTTP/1.1 403 Forbidden\r\n"},
+ 323 {status::NOT_FOUND,
"HTTP/1.1 404 Not Found\r\n"},
+ 324 {status::METHOD_NOT_ALLOWED,
"HTTP/1.1 405 Method Not Allowed\r\n"},
+ 325 {status::NOT_ACCEPTABLE,
"HTTP/1.1 406 Not Acceptable\r\n"},
+ 326 {status::PROXY_AUTHENTICATION_REQUIRED,
"HTTP/1.1 407 Proxy Authentication Required\r\n"},
+ 327 {status::CONFLICT,
"HTTP/1.1 409 Conflict\r\n"},
+ 328 {status::GONE,
"HTTP/1.1 410 Gone\r\n"},
+ 329 {status::PAYLOAD_TOO_LARGE,
"HTTP/1.1 413 Payload Too Large\r\n"},
+ 330 {status::UNSUPPORTED_MEDIA_TYPE,
"HTTP/1.1 415 Unsupported Media Type\r\n"},
+ 331 {status::RANGE_NOT_SATISFIABLE,
"HTTP/1.1 416 Range Not Satisfiable\r\n"},
+ 332 {status::EXPECTATION_FAILED,
"HTTP/1.1 417 Expectation Failed\r\n"},
+ 333 {status::PRECONDITION_REQUIRED,
"HTTP/1.1 428 Precondition Required\r\n"},
+ 334 {status::TOO_MANY_REQUESTS,
"HTTP/1.1 429 Too Many Requests\r\n"},
+ 335 {status::UNAVAILABLE_FOR_LEGAL_REASONS,
"HTTP/1.1 451 Unavailable For Legal Reasons\r\n"},
+
+ 337 {status::INTERNAL_SERVER_ERROR,
"HTTP/1.1 500 Internal Server Error\r\n"},
+ 338 {status::NOT_IMPLEMENTED,
"HTTP/1.1 501 Not Implemented\r\n"},
+ 339 {status::BAD_GATEWAY,
"HTTP/1.1 502 Bad Gateway\r\n"},
+ 340 {status::SERVICE_UNAVAILABLE,
"HTTP/1.1 503 Service Unavailable\r\n"},
+ 341 {status::GATEWAY_TIMEOUT,
"HTTP/1.1 504 Gateway Timeout\r\n"},
+ 342 {status::VARIANT_ALSO_NEGOTIATES,
"HTTP/1.1 506 Variant Also Negotiates\r\n"},
+
+
+ 345 static const std::string seperator =
": ";
+
+
+ 348 buffers_.reserve(4 * (res.headers.size() + 5) + 3);
+
+ 350 if (!statusCodes.count(res.code))
+
+ 352 CROW_LOG_WARNING <<
this <<
" status code "
+ 353 <<
"(" << res.code <<
")"
+ 354 <<
" not defined, returning 500 instead";
+
+
+
+ 358 auto& status = statusCodes.find(res.code)->second;
+ 359 buffers_.emplace_back(status.data(), status.size());
+
+ 361 if (res.code >= 400 && res.body.empty())
+ 362 res.body = statusCodes[res.code].substr(9);
+
+ 364 for (
auto& kv : res.headers)
+
+ 366 buffers_.emplace_back(kv.first.data(), kv.first.size());
+ 367 buffers_.emplace_back(seperator.data(), seperator.size());
+ 368 buffers_.emplace_back(kv.second.data(), kv.second.size());
+ 369 buffers_.emplace_back(crlf.data(), crlf.size());
+
+
+ 372 if (!res.manual_length_header && !res.headers.count(
"content-length"))
+
+ 374 content_length_ = std::to_string(res.body.size());
+ 375 static std::string content_length_tag =
"Content-Length: ";
+ 376 buffers_.emplace_back(content_length_tag.data(), content_length_tag.size());
+ 377 buffers_.emplace_back(content_length_.data(), content_length_.size());
+ 378 buffers_.emplace_back(crlf.data(), crlf.size());
+
+ 380 if (!res.headers.count(
"server"))
+
+ 382 static std::string server_tag =
"Server: ";
+ 383 buffers_.emplace_back(server_tag.data(), server_tag.size());
+ 384 buffers_.emplace_back(server_name_.data(), server_name_.size());
+ 385 buffers_.emplace_back(crlf.data(), crlf.size());
+
+ 387 if (!res.headers.count(
"date"))
+
+ 389 static std::string date_tag =
"Date: ";
+ 390 date_str_ = get_cached_date_str();
+ 391 buffers_.emplace_back(date_tag.data(), date_tag.size());
+ 392 buffers_.emplace_back(date_str_.data(), date_str_.size());
+ 393 buffers_.emplace_back(crlf.data(), crlf.size());
+
+
+
+ 397 static std::string keep_alive_tag =
"Connection: Keep-Alive";
+ 398 buffers_.emplace_back(keep_alive_tag.data(), keep_alive_tag.size());
+ 399 buffers_.emplace_back(crlf.data(), crlf.size());
+
+
+ 402 buffers_.emplace_back(crlf.data(), crlf.size());
+
+
+ 405 void do_write_static()
+
+ 407 asio::write(adaptor_.socket(), buffers_);
+
+ 409 if (res.file_info.statResult == 0)
+
+ 411 std::ifstream is(res.file_info.path.c_str(), std::ios::in | std::ios::binary);
+ 412 std::vector<asio::const_buffer> buffers{1};
+
+ 414 is.read(buf,
sizeof(buf));
+ 415 while (is.gcount() > 0)
+
+ 417 buffers[0] = asio::buffer(buf, is.gcount());
+ 418 do_write_sync(buffers);
+ 419 is.read(buf,
sizeof(buf));
+
+
+ 422 if (close_connection_)
+
+ 424 adaptor_.shutdown_readwrite();
+
+ 426 CROW_LOG_DEBUG <<
this <<
" from write (static)";
+
+
+
+
+
+
+
+
+ 435 void do_write_general()
+
+ 437 if (res.body.length() < res_stream_threshold_)
+
+ 439 res_body_copy_.swap(res.body);
+ 440 buffers_.emplace_back(res_body_copy_.data(), res_body_copy_.size());
+
+
+
+ 444 if (need_to_start_read_after_complete_)
+
+ 446 need_to_start_read_after_complete_ =
false;
+
+
+
+
+
+
+ 453 asio::write(adaptor_.socket(), buffers_);
+ 454 cancel_deadline_timer();
+ 455 if (res.body.length() > 0)
+
+ 457 std::vector<asio::const_buffer> buffers{1};
+ 458 const uint8_t* data =
reinterpret_cast<const uint8_t*
>(res.body.data());
+ 459 size_t length = res.body.length();
+ 460 for (
size_t transferred = 0; transferred < length;)
+
+ 462 size_t to_transfer = CROW_MIN(16384UL, length - transferred);
+ 463 buffers[0] = asio::const_buffer(data + transferred, to_transfer);
+ 464 do_write_sync(buffers);
+ 465 transferred += to_transfer;
+
+
+ 468 if (close_connection_)
+
+ 470 adaptor_.shutdown_readwrite();
+
+ 472 CROW_LOG_DEBUG <<
this <<
" from write (res_stream)";
+
+
+
+
+
+
+
+
+
+
+
+ 484 auto self = this->shared_from_this();
+ 485 adaptor_.socket().async_read_some(
+ 486 asio::buffer(buffer_),
+ 487 [
self](
const error_code& ec, std::size_t bytes_transferred) {
+ 488 bool error_while_reading =
true;
+
+
+ 491 bool ret =
self->parser_.feed(self->buffer_.data(), bytes_transferred);
+ 492 if (ret && self->adaptor_.is_open())
+
+ 494 error_while_reading = false;
+
+
+
+ 498 if (error_while_reading)
+
+ 500 self->cancel_deadline_timer();
+ 501 self->parser_.done();
+ 502 self->adaptor_.shutdown_read();
+ 503 self->adaptor_.close();
+ 504 CROW_LOG_DEBUG <<
self <<
" from read(1) with description: \"" << http_errno_description(
static_cast<http_errno
>(self->parser_.http_errno)) <<
'\"';
+
+ 506 else if (self->close_connection_)
+
+ 508 self->cancel_deadline_timer();
+ 509 self->parser_.done();
+
+
+ 512 else if (!self->need_to_call_after_handlers_)
+
+ 514 self->start_deadline();
+
+
+
+
+
+ 520 self->need_to_start_read_after_complete_ =
true;
+
+
+
+
+
+
+ 527 auto self = this->shared_from_this();
+
+ 529 adaptor_.socket(), buffers_,
+ 530 [
self](
const error_code& ec, std::size_t ) {
+
+ 532 self->res_body_copy_.clear();
+ 533 if (!self->continue_requested)
+
+ 535 self->parser_.clear();
+
+
+
+ 539 self->continue_requested = false;
+
+
+
+
+ 544 if (self->close_connection_)
+
+ 546 self->adaptor_.shutdown_write();
+ 547 self->adaptor_.close();
+ 548 CROW_LOG_DEBUG << self <<
" from write(1)";
+
+
+
+
+ 553 CROW_LOG_DEBUG <<
self <<
" from write(2)";
+
+
+
+
+ 558 inline void do_write_sync(std::vector<asio::const_buffer>& buffers)
+
+
+ 561 asio::write(adaptor_.socket(), buffers, [&](error_code ec, std::size_t) {
+
+
+
+
+
+
+ 568 CROW_LOG_ERROR << ec <<
" - happened while sending buffers";
+ 569 CROW_LOG_DEBUG << this <<
" from write (sync)(2)";
+
+
+
+
+
+ 575 void cancel_deadline_timer()
+
+ 577 CROW_LOG_DEBUG <<
this <<
" timer cancelled: " << &task_timer_ <<
' ' << task_id_;
+ 578 task_timer_.cancel(task_id_);
+
+
+ 581 void start_deadline()
+
+ 583 cancel_deadline_timer();
+
+ 585 auto self = this->shared_from_this();
+ 586 task_id_ = task_timer_.schedule([
self] {
+ 587 if (!self->adaptor_.is_open())
+
+
+
+ 591 self->adaptor_.shutdown_readwrite();
+ 592 self->adaptor_.close();
+
+ 594 CROW_LOG_DEBUG <<
this <<
" timer added: " << &task_timer_ <<
' ' << task_id_;
+
+
+
+
+
+
+ 601 std::array<char, 4096> buffer_;
+
+ 603 HTTPParser<Connection> parser_;
+ 604 std::unique_ptr<routing_handle_result> routing_handle_result_;
+
+
+
+ 608 bool close_connection_ =
false;
+
+ 610 const std::string& server_name_;
+ 611 std::vector<asio::const_buffer> buffers_;
+
+ 613 std::string content_length_;
+ 614 std::string date_str_;
+ 615 std::string res_body_copy_;
+
+ 617 detail::task_timer::identifier_type task_id_{};
+
+ 619 bool continue_requested{};
+ 620 bool need_to_call_after_handlers_{};
+ 621 bool need_to_start_read_after_complete_{};
+ 622 bool add_keep_alive_{};
+
+ 624 std::tuple<Middlewares...>* middlewares_;
+ 625 detail::context<Middlewares...> ctx_;
+
+ 627 std::function<std::string()>& get_cached_date_str;
+ 628 detail::task_timer& task_timer_;
+
+ 630 size_t res_stream_threshold_;
+
+ 632 std::atomic<unsigned int>& queue_length_;
+
+
+
An HTTP connection.
Definition: http_connection.h:48
-void complete_request()
Call the after handle middleware and send the write the response to the connection.
Definition: http_connection.h:218
+void complete_request()
Call the after handle middleware and send the write the response to the connection.
Definition: http_connection.h:217
decltype(std::declval< Adaptor >().raw_socket()) & socket()
The TCP socket on top of which the connection is established.
Definition: http_connection.h:87
Definition: task_timer.h:36
The main namespace of the library. In this namespace is defined the most important classes and functi...
diff --git a/master/reference/http__request_8h_source.html b/master/reference/http__request_8h_source.html
index e07a2bc5a..2da87fcc5 100644
--- a/master/reference/http__request_8h_source.html
+++ b/master/reference/http__request_8h_source.html
@@ -157,8 +157,8 @@
- 59 request(HTTPMethod method, std::string
raw_url, std::string
url,
query_string url_params, ci_map headers, std::string body,
unsigned char http_major,
unsigned char http_minor,
bool has_keep_alive,
bool has_close_connection,
bool is_upgrade):
- 60 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)), http_ver_major(http_major), http_ver_minor(http_minor),
keep_alive(has_keep_alive),
close_connection(has_close_connection),
upgrade(is_upgrade)
+ 59 request(HTTPMethod method_, std::string raw_url_, std::string url_,
query_string url_params_, ci_map headers_, std::string body_,
unsigned char http_major,
unsigned char http_minor,
bool has_keep_alive,
bool has_close_connection,
bool is_upgrade):
+ 60 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_)), http_ver_major(http_major), http_ver_minor(http_minor),
keep_alive(has_keep_alive),
close_connection(has_close_connection),
upgrade(is_upgrade)
63 void add_header(std::string key, std::string value)
@@ -204,7 +204,6 @@
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
An HTTP request.
Definition: http_request.h:36
-request(HTTPMethod method, std::string raw_url, std::string url, query_string url_params, ci_map headers, std::string body, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade)
Construct a request with all values assigned.
Definition: http_request.h:59
void post(CompletionHandler handler)
Send data to whoever made this request with a completion handler and return immediately.
Definition: http_request.h:89
bool close_connection
Whether or not the server should shut down the TCP connection once a response is sent.
Definition: http_request.h:46
bool keep_alive
Whether or not the server should send a connection: Keep-Alive header to the client.
Definition: http_request.h:45
@@ -213,6 +212,7 @@
request()
Construct an empty request. (sets the method to GET)
Definition: http_request.h:54
std::string url
The endpoint without any parameters.
Definition: http_request.h:39
std::string remote_ip_address
The IP address from which the request was sent.
Definition: http_request.h:43
+request(HTTPMethod method_, std::string raw_url_, std::string url_, query_string url_params_, ci_map headers_, std::string body_, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade)
Construct a request with all values assigned.
Definition: http_request.h:59
void dispatch(CompletionHandler handler)
Send data to whoever made this request with a completion handler.
Definition: http_request.h:96
bool upgrade
Whether or noth the server should change the HTTP connection to a different connection.
Definition: http_request.h:47
const query_string get_body_params() const
Get the body as parameters in QS format.
Definition: http_request.h:82
diff --git a/master/reference/http__response_8h_source.html b/master/reference/http__response_8h_source.html
index 0a8feec05..89baae9e6 100644
--- a/master/reference/http__response_8h_source.html
+++ b/master/reference/http__response_8h_source.html
@@ -112,7 +112,7 @@
13 #if !defined(S_ISREG) && defined(S_IFMT) && defined(S_IFREG)
- 14 #define S_ISREG(m) (((m)&S_IFMT) == S_IFREG)
+ 14 #define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
17 #include "crow/http_request.h"
@@ -219,9 +219,9 @@
-
-
-
+ 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)
@@ -233,14 +233,14 @@
133 set_header(
"Content-Type", value.content_type);
- 135 response(
int code, returnable& value):
-
+ 135 response(
int code_, returnable& value):
+
139 set_header(
"Content-Type", value.content_type);
- 141 response(
int code, returnable&& value):
-
+ 141 response(
int code_, returnable&& value):
+
144 set_header(
"Content-Type", std::move(value.content_type));
@@ -250,14 +250,14 @@
149 *
this = std::move(r);
- 152 response(std::string contentType, std::string
body):
-
+ 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):
-
+ 158 response(
int code_, std::string contentType, std::string body_):
+
161 set_header(
"Content-Type", get_mime_type(contentType));
@@ -427,7 +427,7 @@
An HTTP connection.
Definition: http_connection.h:48
-Handles matching requests to existing rules and upgrade requests.
Definition: routing.h:1264
+Handles matching requests to existing rules and upgrade requests.
Definition: routing.h:1267
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
diff --git a/master/reference/json_8h_source.html b/master/reference/json_8h_source.html
index 6d6793368..c7b5c7c5e 100644
--- a/master/reference/json_8h_source.html
+++ b/master/reference/json_8h_source.html
@@ -135,2077 +135,2080 @@
- 37 inline void escape(
const std::string& str, std::string& ret)
+ 37 static inline char to_hex(
char c)
- 39 ret.reserve(ret.size() + str.size() + str.size() / 4);
-
-
-
-
- 44 case '"': ret +=
"\\\"";
break;
- 45 case '\\': ret +=
"\\\\";
break;
- 46 case '\n': ret +=
"\\n";
break;
- 47 case '\b': ret +=
"\\b";
break;
- 48 case '\f': ret +=
"\\f";
break;
- 49 case '\r': ret +=
"\\r";
break;
- 50 case '\t': ret +=
"\\t";
break;
-
- 52 if (c >= 0 && c < 0x20)
-
-
- 55 auto to_hex = [](
char c) {
-
-
-
-
-
- 61 ret += to_hex(c / 16);
- 62 ret += to_hex(c % 16);
-
-
-
-
-
-
-
- 70 inline std::string escape(
const std::string& str)
-
-
-
-
-
-
- 77 enum class type : char
-
-
-
-
-
-
-
-
-
-
-
- 89 inline const char* get_type_str(type t)
-
-
-
- 93 case type::Number:
return "Number";
- 94 case type::False:
return "False";
- 95 case type::True:
return "True";
- 96 case type::List:
return "List";
- 97 case type::String:
return "String";
- 98 case type::Object:
return "Object";
- 99 case type::Function:
return "Function";
- 100 default:
return "Unknown";
-
-
-
- 104 enum class num_type : char
-
-
-
-
-
- 110 Double_precision_floating_point
-
-
-
- 114 rvalue
load(
const char* data,
size_t size);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 158 operator std::string()
const
-
- 160 return std::string(
s_,
e_);
-
-
-
- 164 const char* begin()
const {
return s_; }
- 165 const char* end()
const {
return e_; }
- 166 size_t size()
const {
return end() - begin(); }
-
- 168 using iterator =
const char*;
- 169 using const_iterator =
const char*;
-
-
-
-
- 174 friend std::ostream& operator<<(std::ostream& os,
const r_string& s)
-
- 176 os << static_cast<std::string>(s);
-
-
-
-
- 181 void force(
char* s, uint32_t length)
-
-
-
-
-
-
-
- 189 friend bool operator==(
const r_string& l,
const r_string& r);
- 190 friend bool operator==(
const std::string& l,
const r_string& r);
- 191 friend bool operator==(
const r_string& l,
const std::string& r);
-
- 193 template<
typename T,
typename U>
- 194 inline static bool equals(
const T& l,
const U& r)
-
- 196 if (l.size() != r.size())
-
-
- 199 for (
size_t i = 0; i < l.size(); i++)
-
- 201 if (*(l.begin() + i) != *(r.begin() + i))
-
-
-
-
-
-
-
- 209 inline bool operator<(
const r_string& l,
const r_string& r)
-
- 211 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
-
-
- 214 inline bool operator<(
const r_string& l,
const std::string& r)
-
- 216 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
-
-
- 219 inline bool operator<(
const std::string& l,
const r_string& r)
-
- 221 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
-
-
- 224 inline bool operator>(
const r_string& l,
const r_string& r)
-
- 226 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
-
-
- 229 inline bool operator>(
const r_string& l,
const std::string& r)
-
- 231 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
-
-
- 234 inline bool operator>(
const std::string& l,
const r_string& r)
-
- 236 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
-
-
- 239 inline bool operator==(
const r_string& l,
const r_string& r)
-
- 241 return r_string::equals(l, r);
-
-
- 244 inline bool operator==(
const r_string& l,
const std::string& r)
-
- 246 return r_string::equals(l, r);
-
-
- 249 inline bool operator==(
const std::string& l,
const r_string& r)
-
- 251 return r_string::equals(l, r);
-
-
- 254 inline bool operator!=(
const r_string& l,
const r_string& r)
-
-
-
-
- 259 inline bool operator!=(
const r_string& l,
const std::string& r)
-
-
-
-
- 264 inline bool operator!=(
const std::string& l,
const r_string& r)
-
-
-
-
-
-
-
-
-
-
-
-
- 277 static const int cached_bit = 2;
- 278 static const int error_bit = 4;
-
-
-
-
-
-
-
- 286 lsize_{}, lremain_{}, t_{
t}
-
-
- 289 rvalue(type
t,
char*
s,
char* e) noexcept:
- 290 start_{
s}, end_{e}, t_{
t}
-
- 292 determine_num_type();
-
-
-
- 296 start_(r.start_), end_(r.end_), key_(r.key_), t_(r.t_), nt_(r.nt_), option_(r.option_)
-
-
-
-
-
-
- 303 *
this = std::move(r);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 321 key_ = std::move(r.key_);
- 322 l_ = std::move(r.l_);
-
- 324 lremain_ = r.lremain_;
-
-
-
-
-
-
- 331 explicit operator bool()
const noexcept
-
- 333 return (option_ & error_bit) == 0;
-
-
- 336 explicit operator int64_t()
const
-
-
-
-
- 341 explicit operator uint64_t()
const
-
-
-
-
- 346 explicit operator int()
const
-
- 348 return static_cast<int>(
i());
-
-
-
- 352 explicit operator std::string()
const
-
- 354 #ifndef CROW_JSON_NO_ERROR_CHECK
- 355 if (
t() == type::Object ||
t() == type::List)
- 356 throw std::runtime_error(
"json type container");
-
-
-
-
- 361 return std::string(
s());
-
- 363 return std::string(
"null");
-
- 365 return std::string(
"true");
-
- 367 return std::string(
"false");
-
- 369 return std::string(start_, end_ - start_);
-
-
-
-
-
-
- 376 #ifndef CROW_JSON_NO_ERROR_CHECK
- 377 if (option_ & error_bit)
-
- 379 throw std::runtime_error(
"invalid json object");
-
-
-
-
-
-
-
-
- 388 #ifndef CROW_JSON_NO_ERROR_CHECK
- 389 if (option_ & error_bit)
-
- 391 throw std::runtime_error(
"invalid json object");
-
-
-
-
-
-
-
-
- 400 #ifndef CROW_JSON_NO_ERROR_CHECK
-
-
-
-
- 405 return utility::lexical_cast<int64_t>(start_, end_ - start_);
-
- 407 const std::string msg =
"expected number, got: " + std::string(get_type_str(
t()));
- 408 throw std::runtime_error(msg);
-
-
- 411 return utility::lexical_cast<int64_t>(start_, end_ - start_);
-
-
-
-
-
- 417 #ifndef CROW_JSON_NO_ERROR_CHECK
-
-
-
-
- 422 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
-
- 424 throw std::runtime_error(std::string(
"expected number, got: ") + get_type_str(
t()));
-
-
- 427 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
-
-
-
-
-
- 433 #ifndef CROW_JSON_NO_ERROR_CHECK
- 434 if (
t() != type::Number)
- 435 throw std::runtime_error(
"value is not number");
-
- 437 return utility::lexical_cast<double>(start_, end_ - start_);
-
-
-
-
-
- 443 #ifndef CROW_JSON_NO_ERROR_CHECK
- 444 if (
t() != type::True &&
t() != type::False)
- 445 throw std::runtime_error(
"value is not boolean");
-
- 447 return t() == type::True;
-
-
-
-
-
- 453 #ifndef CROW_JSON_NO_ERROR_CHECK
- 454 if (
t() != type::String)
- 455 throw std::runtime_error(
"value is not string");
-
-
-
-
-
-
- 462 std::vector<rvalue>
lo()
const
-
- 464 #ifndef CROW_JSON_NO_ERROR_CHECK
- 465 if (
t() != type::Object &&
t() != type::List)
- 466 throw std::runtime_error(
"value is not a container");
-
- 468 std::vector<rvalue> ret;
-
- 470 for (uint32_t
i = 0;
i < lsize_;
i++)
-
- 472 ret.emplace_back(l_[
i]);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 490 case '"': *tail++ =
'"';
break;
- 491 case '\\': *tail++ =
'\\';
break;
- 492 case '/': *tail++ =
'/';
break;
- 493 case 'b': *tail++ =
'\b';
break;
- 494 case 'f': *tail++ =
'\f';
break;
- 495 case 'n': *tail++ =
'\n';
break;
- 496 case 'r': *tail++ =
'\r';
break;
- 497 case 't': *tail++ =
'\t';
break;
-
-
- 500 auto from_hex = [](
char c) {
-
-
-
-
-
-
-
- 508 (from_hex(head[1]) << 12) +
- 509 (from_hex(head[2]) << 8) +
- 510 (from_hex(head[3]) << 4) +
-
-
-
- 514 *tail++ = 0xE0 | (code >> 12);
- 515 *tail++ = 0x80 | ((code >> 6) & 0x3F);
- 516 *tail++ = 0x80 | (code & 0x3F);
-
- 518 else if (code >= 0x80)
-
- 520 *tail++ = 0xC0 | (code >> 6);
- 521 *tail++ = 0x80 | (code & 0x3F);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 543 bool has(
const char* str)
const
-
- 545 return has(std::string(str));
-
-
- 548 bool has(
const std::string& str)
const
-
-
-
-
-
- 554 return l.key_ < r.key_;
-
- 556 bool operator()(
const rvalue& l,
const std::string& r)
const
-
-
-
- 560 bool operator()(
const std::string& l,
const rvalue& r)
const
-
-
-
-
-
-
- 567 std::sort(begin(), end(), Pred());
-
-
- 570 auto it = lower_bound(begin(), end(), str, Pred());
- 571 return it != end() && it->key_ == str;
-
-
- 574 int count(
const std::string& str)
-
- 576 return has(str) ? 1 : 0;
-
-
- 579 rvalue* begin()
const
-
- 581 #ifndef CROW_JSON_NO_ERROR_CHECK
- 582 if (
t() != type::Object &&
t() != type::List)
- 583 throw std::runtime_error(
"value is not a container");
-
-
-
-
-
- 589 #ifndef CROW_JSON_NO_ERROR_CHECK
- 590 if (
t() != type::Object &&
t() != type::List)
- 591 throw std::runtime_error(
"value is not a container");
-
- 593 return l_.get() + lsize_;
-
-
- 596 const detail::r_string& key()
const
-
-
-
-
-
-
- 603 if (
t() == type::String)
-
- 605 #ifndef CROW_JSON_NO_ERROR_CHECK
- 606 if (
t() != type::Object &&
t() != type::List)
- 607 throw std::runtime_error(
"value is not a container");
-
-
-
-
- 612 const rvalue& operator[](
int index)
const
-
- 614 #ifndef CROW_JSON_NO_ERROR_CHECK
- 615 if (
t() != type::List)
- 616 throw std::runtime_error(
"value is not a list");
- 617 if (index >=
static_cast<int>(lsize_) || index < 0)
- 618 throw std::runtime_error(
"list out of bound");
-
-
-
-
- 623 const rvalue& operator[](
size_t index)
const
-
- 625 #ifndef CROW_JSON_NO_ERROR_CHECK
- 626 if (
t() != type::List)
- 627 throw std::runtime_error(
"value is not a list");
-
- 629 throw std::runtime_error(
"list out of bound");
-
-
-
-
- 634 const rvalue& operator[](
const char* str)
const
-
- 636 return this->operator[](std::string(str));
-
-
- 639 const rvalue& operator[](
const std::string& str)
const
-
- 641 #ifndef CROW_JSON_NO_ERROR_CHECK
- 642 if (
t() != type::Object)
- 643 throw std::runtime_error(
"value is not an object");
-
-
-
- 647 bool operator()(
const rvalue& l,
const rvalue& r)
const
-
- 649 return l.key_ < r.key_;
-
- 651 bool operator()(
const rvalue& l,
const std::string& r)
const
-
-
-
- 655 bool operator()(
const std::string& l,
const rvalue& r)
const
-
-
-
-
-
-
- 662 std::sort(begin(), end(), Pred());
-
-
- 665 auto it = lower_bound(begin(), end(), str, Pred());
- 666 if (it != end() && it->key_ == str)
-
- 668 #ifndef CROW_JSON_NO_ERROR_CHECK
- 669 throw std::runtime_error(
"cannot find key");
-
- 671 static rvalue nullValue;
-
-
-
-
-
-
- 678 option_ |= error_bit;
-
-
-
-
- 683 return (option_ & error_bit) != 0;
-
-
- 686 std::vector<std::string> keys()
const
-
- 688 #ifndef CROW_JSON_NO_ERROR_CHECK
- 689 if (
t() != type::Object)
- 690 throw std::runtime_error(
"value is not an object");
-
- 692 std::vector<std::string> ret;
-
- 694 for (uint32_t
i = 0;
i < lsize_;
i++)
-
- 696 ret.emplace_back(std::string(l_[
i].key()));
-
-
-
-
-
- 702 bool is_cached()
const
-
- 704 return (option_ & cached_bit) != 0;
-
- 706 void set_cached()
const
-
- 708 option_ |= cached_bit;
-
- 710 void copy_l(
const rvalue& r)
-
- 712 if (r.t() != type::Object && r.t() != type::List)
-
-
-
- 716 l_.reset(
new rvalue[lsize_]);
- 717 std::copy(r.begin(), r.end(), begin());
-
-
- 720 void emplace_back(rvalue&& v)
-
-
-
- 724 int new_size = lsize_ + lsize_;
- 725 if (new_size - lsize_ > 60000)
- 726 new_size = lsize_ + 60000;
-
-
- 729 rvalue* p =
new rvalue[new_size];
-
- 731 for (
auto& x : *
this)
- 732 *p2++ = std::move(x);
-
- 734 lremain_ = new_size - lsize_;
-
- 736 l_[lsize_++] = std::move(v);
-
-
-
-
- 741 void determine_num_type()
-
- 743 if (t_ != type::Number)
-
- 745 nt_ = num_type::Null;
-
-
-
- 749 const std::size_t len = end_ - start_;
- 750 const bool has_minus = std::memchr(start_,
'-', len) !=
nullptr;
- 751 const bool has_e = std::memchr(start_,
'e', len) !=
nullptr || std::memchr(start_,
'E', len) !=
nullptr;
- 752 const bool has_dec_sep = std::memchr(start_,
'.', len) !=
nullptr;
- 753 if (has_dec_sep || has_e)
- 754 nt_ = num_type::Floating_point;
-
- 756 nt_ = num_type::Signed_integer;
-
- 758 nt_ = num_type::Unsigned_integer;
-
-
- 761 mutable char* start_;
-
- 763 detail::r_string key_;
- 764 std::unique_ptr<rvalue[]> l_;
-
-
-
- 768 num_type nt_{num_type::Null};
- 769 mutable uint8_t option_{0};
-
- 771 friend rvalue load_nocopy_internal(
char* data,
size_t size);
- 772 friend rvalue load(
const char* data,
size_t size);
- 773 friend std::ostream& operator<<(std::ostream& os,
const rvalue& r)
-
-
-
-
- 778 case type::Null: os <<
"null";
break;
- 779 case type::False: os <<
"false";
break;
- 780 case type::True: os <<
"true";
break;
-
-
-
-
- 785 case num_type::Floating_point: os << r.d();
break;
- 786 case num_type::Double_precision_floating_point: os << r.d();
break;
- 787 case num_type::Signed_integer: os << r.i();
break;
- 788 case num_type::Unsigned_integer: os << r.u();
break;
- 789 case num_type::Null:
throw std::runtime_error(
"Number with num_type Null");
-
-
-
- 793 case type::String: os <<
'"' << r.s() <<
'"';
break;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 816 os <<
'"' << escape(x.key_) <<
"\":";
-
-
-
-
-
-
- 823 case type::Function: os <<
"custom function";
break;
-
-
-
-
-
-
-
-
- 832 inline bool operator==(
const rvalue& l,
const std::string& r)
-
-
-
-
- 837 inline bool operator==(
const std::string& l,
const rvalue& r)
-
-
-
-
- 842 inline bool operator!=(
const rvalue& l,
const std::string& r)
-
-
-
-
- 847 inline bool operator!=(
const std::string& l,
const rvalue& r)
-
-
-
-
- 852 inline bool operator==(
const rvalue& l,
double r)
-
-
-
-
- 857 inline bool operator==(
double l,
const rvalue& r)
-
-
-
-
- 862 inline bool operator!=(
const rvalue& l,
double r)
-
-
-
-
- 867 inline bool operator!=(
double l,
const rvalue& r)
-
-
-
-
-
- 873 inline rvalue load_nocopy_internal(
char* data,
size_t size)
-
-
- 876 static constexpr
unsigned max_depth = 10000;
-
-
-
-
- 881 Parser(
char* data,
size_t ):
-
-
-
-
-
-
- 888 if (CROW_UNLIKELY(*data != c))
-
-
-
-
-
-
-
- 896 while (*data ==
' ' || *data ==
'\t' || *data ==
'\r' || *data ==
'\n')
-
-
-
- 900 rvalue decode_string()
-
- 902 if (CROW_UNLIKELY(!consume(
'"')))
-
-
- 905 uint8_t has_escaping = 0;
-
-
- 908 if (CROW_LIKELY(*data !=
'"' && *data !=
'\\' && *data !=
'\0'))
-
-
-
- 912 else if (*data ==
'"')
-
-
- 915 *(start - 1) = has_escaping;
-
- 917 return {type::String, start, data - 1};
-
- 919 else if (*data ==
'\\')
-
-
-
-
-
-
-
- 927 auto check = [](
char c) {
- 928 return (
'0' <= c && c <=
'9') ||
- 929 (
'a' <= c && c <=
'f') ||
- 930 (
'A' <= c && c <=
'F');
-
- 932 if (!(check(*(data + 1)) &&
- 933 check(*(data + 2)) &&
- 934 check(*(data + 3)) &&
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 960 rvalue decode_list(
unsigned depth)
-
- 962 rvalue ret(type::List);
- 963 if (CROW_UNLIKELY(!consume(
'[')) || CROW_UNLIKELY(depth > max_depth))
-
-
-
-
-
- 969 if (CROW_UNLIKELY(*data ==
']'))
-
-
-
-
-
-
-
- 977 auto v = decode_value(depth + 1);
- 978 if (CROW_UNLIKELY(!v))
-
-
-
-
-
- 984 ret.emplace_back(std::move(v));
-
-
-
-
-
- 990 if (CROW_UNLIKELY(!consume(
',')))
-
-
-
-
-
-
-
-
-
- 1000 rvalue decode_number()
-
-
-
- 1004 enum NumberParsingState
-
-
-
-
-
-
-
-
-
-
- 1015 while (CROW_LIKELY(state != Invalid))
-
-
-
-
- 1020 state =
static_cast<NumberParsingState
>(
"\2\2\7\3\4\6\6"[state]);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1047 state =
static_cast<NumberParsingState
>(
"\3\3\7\3\4\6\6"[state]);
- 1048 while (*(data + 1) >=
'0' && *(data + 1) <=
'9')
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1068 state =
static_cast<NumberParsingState
>(
"\7\7\4\4\7\7\7"[state]);
-
-
-
-
-
-
-
-
-
-
- 1079 state =
static_cast<NumberParsingState
>(
"\1\7\7\7\7\6\7"[state]);
-
-
-
-
-
-
-
-
-
-
-
-
- 1092 state =
static_cast<NumberParsingState
>(
"\7\7\7\7\7\6\7"[state]);
-
-
-
-
-
-
-
-
-
- 1102 state =
static_cast<NumberParsingState
>(
"\7\7\7\5\5\7\7"[state]);
-
-
-
-
-
-
-
-
-
- 1112 if (CROW_LIKELY(state == NumberParsingState::ZeroFirst ||
- 1113 state == NumberParsingState::Digits ||
- 1114 state == NumberParsingState::DigitsAfterPoints ||
- 1115 state == NumberParsingState::DigitsAfterE))
- 1116 return {type::Number, start, data};
-
-
-
-
-
-
-
-
-
-
- 1127 rvalue decode_value(
unsigned depth)
-
-
-
-
- 1132 return decode_list(depth + 1);
-
- 1134 return decode_object(depth + 1);
-
- 1136 return decode_string();
-
-
-
-
-
-
-
- 1144 return {type::True};
-
-
-
-
-
-
-
-
-
-
-
- 1156 return {type::False};
-
-
-
-
-
-
-
-
-
-
- 1167 return {type::Null};
-
-
-
-
-
-
-
-
- 1176 return decode_number();
-
-
-
-
- 1181 rvalue decode_object(
unsigned depth)
-
- 1183 rvalue ret(type::Object);
- 1184 if (CROW_UNLIKELY(!consume(
'{')) || CROW_UNLIKELY(depth > max_depth))
-
-
-
-
-
-
+
+
+
+
+
+
+ 45 inline void escape(
const std::string& str, std::string& ret)
+
+ 47 ret.reserve(ret.size() + str.size() + str.size() / 4);
+
+
+
+
+ 52 case '"': ret +=
"\\\"";
break;
+ 53 case '\\': ret +=
"\\\\";
break;
+ 54 case '\n': ret +=
"\\n";
break;
+ 55 case '\b': ret +=
"\\b";
break;
+ 56 case '\f': ret +=
"\\f";
break;
+ 57 case '\r': ret +=
"\\r";
break;
+ 58 case '\t': ret +=
"\\t";
break;
+
+ 60 if (c >= 0 && c < 0x20)
+
+
+ 63 ret += to_hex(c / 16);
+ 64 ret += to_hex(c % 16);
+
+
+
+
+
+
+
+ 72 inline std::string escape(
const std::string& str)
+
+
+
+
+
+
+ 79 enum class type : char
+
+
+
+
+
+
+
+
+
+
+
+ 91 inline const char* get_type_str(type t)
+
+
+
+ 95 case type::Number:
return "Number";
+ 96 case type::False:
return "False";
+ 97 case type::True:
return "True";
+ 98 case type::List:
return "List";
+ 99 case type::String:
return "String";
+ 100 case type::Object:
return "Object";
+ 101 case type::Function:
return "Function";
+ 102 default:
return "Unknown";
+
+
+
+ 106 enum class num_type : char
+
+
+
+
+
+ 112 Double_precision_floating_point
+
+
+
+ 116 rvalue
load(
const char* data,
size_t size);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 160 operator std::string()
const
+
+ 162 return std::string(
s_,
e_);
+
+
+
+ 166 const char* begin()
const {
return s_; }
+ 167 const char* end()
const {
return e_; }
+ 168 size_t size()
const {
return end() - begin(); }
+
+ 170 using iterator =
const char*;
+ 171 using const_iterator =
const char*;
+
+
+
+
+ 176 friend std::ostream& operator<<(std::ostream& os,
const r_string& s)
+
+ 178 os << static_cast<std::string>(s);
+
+
+
+
+ 183 void force(
char* s, uint32_t length)
+
+
+
+
+
+
+
+ 191 friend bool operator==(
const r_string& l,
const r_string& r);
+ 192 friend bool operator==(
const std::string& l,
const r_string& r);
+ 193 friend bool operator==(
const r_string& l,
const std::string& r);
+
+ 195 template<
typename T,
typename U>
+ 196 inline static bool equals(
const T& l,
const U& r)
+
+ 198 if (l.size() != r.size())
+
+
+ 201 for (
size_t i = 0; i < l.size(); i++)
+
+ 203 if (*(l.begin() + i) != *(r.begin() + i))
+
+
+
+
+
+
+
+ 211 inline bool operator<(
const r_string& l,
const r_string& r)
+
+ 213 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+
+
+ 216 inline bool operator<(
const r_string& l,
const std::string& r)
+
+ 218 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+
+
+ 221 inline bool operator<(
const std::string& l,
const r_string& r)
+
+ 223 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+
+
+ 226 inline bool operator>(
const r_string& l,
const r_string& r)
+
+ 228 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+
+
+ 231 inline bool operator>(
const r_string& l,
const std::string& r)
+
+ 233 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+
+
+ 236 inline bool operator>(
const std::string& l,
const r_string& r)
+
+ 238 return std::lexicographical_compare(l.begin(), l.end(), r.begin(), r.end());
+
+
+ 241 inline bool operator==(
const r_string& l,
const r_string& r)
+
+ 243 return r_string::equals(l, r);
+
+
+ 246 inline bool operator==(
const r_string& l,
const std::string& r)
+
+ 248 return r_string::equals(l, r);
+
+
+ 251 inline bool operator==(
const std::string& l,
const r_string& r)
+
+ 253 return r_string::equals(l, r);
+
+
+ 256 inline bool operator!=(
const r_string& l,
const r_string& r)
+
+
+
+
+ 261 inline bool operator!=(
const r_string& l,
const std::string& r)
+
+
+
+
+ 266 inline bool operator!=(
const std::string& l,
const r_string& r)
+
+
+
+
+
+
+
+
+
+
+
+
+ 279 static const int cached_bit = 2;
+ 280 static const int error_bit = 4;
+
+
+
+
+
+
+
+ 288 lsize_{}, lremain_{}, t_{
t}
+
+
+ 291 rvalue(type
t,
char*
s,
char* e) noexcept:
+ 292 start_{
s}, end_{e}, t_{
t}
+
+ 294 determine_num_type();
+
+
+
+ 298 start_(r.start_), end_(r.end_), key_(r.key_), t_(r.t_), nt_(r.nt_), option_(r.option_)
+
+
+
+
+
+
+ 305 *
this = std::move(r);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 323 key_ = std::move(r.key_);
+ 324 l_ = std::move(r.l_);
+
+ 326 lremain_ = r.lremain_;
+
+
+
+
+
+
+ 333 explicit operator bool()
const noexcept
+
+ 335 return (option_ & error_bit) == 0;
+
+
+ 338 explicit operator int64_t()
const
+
+
+
+
+ 343 explicit operator uint64_t()
const
+
+
+
+
+ 348 explicit operator int()
const
+
+ 350 return static_cast<int>(
i());
+
+
+
+ 354 explicit operator std::string()
const
+
+ 356 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 357 if (
t() == type::Object ||
t() == type::List)
+ 358 throw std::runtime_error(
"json type container");
+
+
+
+
+ 363 return std::string(
s());
+
+ 365 return std::string(
"null");
+
+ 367 return std::string(
"true");
+
+ 369 return std::string(
"false");
+
+ 371 return std::string(start_, end_ - start_);
+
+
+
+
+
+
+ 378 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 379 if (option_ & error_bit)
+
+ 381 throw std::runtime_error(
"invalid json object");
+
+
+
+
+
+
+
+
+ 390 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 391 if (option_ & error_bit)
+
+ 393 throw std::runtime_error(
"invalid json object");
+
+
+
+
+
+
+
+
+ 402 #ifndef CROW_JSON_NO_ERROR_CHECK
+
+
+
+
+ 407 return utility::lexical_cast<int64_t>(start_, end_ - start_);
+
+ 409 const std::string msg =
"expected number, got: " + std::string(get_type_str(
t()));
+ 410 throw std::runtime_error(msg);
+
+
+ 413 return utility::lexical_cast<int64_t>(start_, end_ - start_);
+
+
+
+
+
+ 419 #ifndef CROW_JSON_NO_ERROR_CHECK
+
+
+
+
+ 424 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
+
+ 426 throw std::runtime_error(std::string(
"expected number, got: ") + get_type_str(
t()));
+
+
+ 429 return utility::lexical_cast<uint64_t>(start_, end_ - start_);
+
+
+
+
+
+ 435 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 436 if (
t() != type::Number)
+ 437 throw std::runtime_error(
"value is not number");
+
+ 439 return utility::lexical_cast<double>(start_, end_ - start_);
+
+
+
+
+
+ 445 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 446 if (
t() != type::True &&
t() != type::False)
+ 447 throw std::runtime_error(
"value is not boolean");
+
+ 449 return t() == type::True;
+
+
+
+
+
+ 455 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 456 if (
t() != type::String)
+ 457 throw std::runtime_error(
"value is not string");
+
+
+
+
+
+
+ 464 std::vector<rvalue>
lo()
const
+
+ 466 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 467 if (
t() != type::Object &&
t() != type::List)
+ 468 throw std::runtime_error(
"value is not a container");
+
+ 470 std::vector<rvalue> ret;
+
+ 472 for (uint32_t
i = 0;
i < lsize_;
i++)
+
+ 474 ret.emplace_back(l_[
i]);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 492 case '"': *tail++ =
'"';
break;
+ 493 case '\\': *tail++ =
'\\';
break;
+ 494 case '/': *tail++ =
'/';
break;
+ 495 case 'b': *tail++ =
'\b';
break;
+ 496 case 'f': *tail++ =
'\f';
break;
+ 497 case 'n': *tail++ =
'\n';
break;
+ 498 case 'r': *tail++ =
'\r';
break;
+ 499 case 't': *tail++ =
'\t';
break;
+
+
+ 502 auto from_hex = [](
char c) {
+
+
+
+
+
+
+
+ 510 (from_hex(head[1]) << 12) +
+ 511 (from_hex(head[2]) << 8) +
+ 512 (from_hex(head[3]) << 4) +
+
+
+
+ 516 *tail++ = 0xE0 | (code >> 12);
+ 517 *tail++ = 0x80 | ((code >> 6) & 0x3F);
+ 518 *tail++ = 0x80 | (code & 0x3F);
+
+ 520 else if (code >= 0x80)
+
+ 522 *tail++ = 0xC0 | (code >> 6);
+ 523 *tail++ = 0x80 | (code & 0x3F);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 545 bool has(
const char* str)
const
+
+ 547 return has(std::string(str));
+
+
+ 550 bool has(
const std::string& str)
const
+
+
+
+
+
+ 556 return l.key_ < r.key_;
+
+ 558 bool operator()(
const rvalue& l,
const std::string& r)
const
+
+
+
+ 562 bool operator()(
const std::string& l,
const rvalue& r)
const
+
+
+
+
+
+
+ 569 std::sort(begin(), end(), Pred());
+
+
+ 572 auto it = lower_bound(begin(), end(), str, Pred());
+ 573 return it != end() && it->key_ == str;
+
+
+ 576 int count(
const std::string& str)
+
+ 578 return has(str) ? 1 : 0;
+
+
+ 581 rvalue* begin()
const
+
+ 583 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 584 if (
t() != type::Object &&
t() != type::List)
+ 585 throw std::runtime_error(
"value is not a container");
+
+
+
+
+
+ 591 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 592 if (
t() != type::Object &&
t() != type::List)
+ 593 throw std::runtime_error(
"value is not a container");
+
+ 595 return l_.get() + lsize_;
+
+
+ 598 const detail::r_string& key()
const
+
+
+
+
+
+
+ 605 if (
t() == type::String)
+
+ 607 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 608 if (
t() != type::Object &&
t() != type::List)
+ 609 throw std::runtime_error(
"value is not a container");
+
+
+
+
+ 614 const rvalue& operator[](
int index)
const
+
+ 616 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 617 if (
t() != type::List)
+ 618 throw std::runtime_error(
"value is not a list");
+ 619 if (index >=
static_cast<int>(lsize_) || index < 0)
+ 620 throw std::runtime_error(
"list out of bound");
+
+
+
+
+ 625 const rvalue& operator[](
size_t index)
const
+
+ 627 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 628 if (
t() != type::List)
+ 629 throw std::runtime_error(
"value is not a list");
+
+ 631 throw std::runtime_error(
"list out of bound");
+
+
+
+
+ 636 const rvalue& operator[](
const char* str)
const
+
+ 638 return this->operator[](std::string(str));
+
+
+ 641 const rvalue& operator[](
const std::string& str)
const
+
+ 643 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 644 if (
t() != type::Object)
+ 645 throw std::runtime_error(
"value is not an object");
+
+
+
+ 649 bool operator()(
const rvalue& l,
const rvalue& r)
const
+
+ 651 return l.key_ < r.key_;
+
+ 653 bool operator()(
const rvalue& l,
const std::string& r)
const
+
+
+
+ 657 bool operator()(
const std::string& l,
const rvalue& r)
const
+
+
+
+
+
+
+ 664 std::sort(begin(), end(), Pred());
+
+
+ 667 auto it = lower_bound(begin(), end(), str, Pred());
+ 668 if (it != end() && it->key_ == str)
+
+ 670 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 671 throw std::runtime_error(
"cannot find key");
+
+ 673 static rvalue nullValue;
+
+
+
+
+
+
+ 680 option_ |= error_bit;
+
+
+
+
+ 685 return (option_ & error_bit) != 0;
+
+
+ 688 std::vector<std::string> keys()
const
+
+ 690 #ifndef CROW_JSON_NO_ERROR_CHECK
+ 691 if (
t() != type::Object)
+ 692 throw std::runtime_error(
"value is not an object");
+
+ 694 std::vector<std::string> ret;
+
+ 696 for (uint32_t
i = 0;
i < lsize_;
i++)
+
+ 698 ret.emplace_back(std::string(l_[
i].key()));
+
+
+
+
+
+ 704 bool is_cached()
const
+
+ 706 return (option_ & cached_bit) != 0;
+
+ 708 void set_cached()
const
+
+ 710 option_ |= cached_bit;
+
+ 712 void copy_l(
const rvalue& r)
+
+ 714 if (r.t() != type::Object && r.t() != type::List)
+
+
+
+ 718 l_.reset(
new rvalue[lsize_]);
+ 719 std::copy(r.begin(), r.end(), begin());
+
+
+ 722 void emplace_back(rvalue&& v)
+
+
+
+ 726 int new_size = lsize_ + lsize_;
+ 727 if (new_size - lsize_ > 60000)
+ 728 new_size = lsize_ + 60000;
+
+
+ 731 rvalue* p =
new rvalue[new_size];
+
+ 733 for (
auto& x : *
this)
+ 734 *p2++ = std::move(x);
+
+ 736 lremain_ = new_size - lsize_;
+
+ 738 l_[lsize_++] = std::move(v);
+
+
+
+
+ 743 void determine_num_type()
+
+ 745 if (t_ != type::Number)
+
+ 747 nt_ = num_type::Null;
+
+
+
+ 751 const std::size_t len = end_ - start_;
+ 752 const bool has_minus = std::memchr(start_,
'-', len) !=
nullptr;
+ 753 const bool has_e = std::memchr(start_,
'e', len) !=
nullptr || std::memchr(start_,
'E', len) !=
nullptr;
+ 754 const bool has_dec_sep = std::memchr(start_,
'.', len) !=
nullptr;
+ 755 if (has_dec_sep || has_e)
+ 756 nt_ = num_type::Floating_point;
+
+ 758 nt_ = num_type::Signed_integer;
+
+ 760 nt_ = num_type::Unsigned_integer;
+
+
+ 763 mutable char* start_;
+
+ 765 detail::r_string key_;
+ 766 std::unique_ptr<rvalue[]> l_;
+
+
+
+ 770 num_type nt_{num_type::Null};
+ 771 mutable uint8_t option_{0};
+
+ 773 friend rvalue load_nocopy_internal(
char* data,
size_t size);
+ 774 friend rvalue load(
const char* data,
size_t size);
+ 775 friend std::ostream& operator<<(std::ostream& os,
const rvalue& r)
+
+
+
+
+ 780 case type::Null: os <<
"null";
break;
+ 781 case type::False: os <<
"false";
break;
+ 782 case type::True: os <<
"true";
break;
+
+
+
+
+ 787 case num_type::Floating_point: os << r.d();
break;
+ 788 case num_type::Double_precision_floating_point: os << r.d();
break;
+ 789 case num_type::Signed_integer: os << r.i();
break;
+ 790 case num_type::Unsigned_integer: os << r.u();
break;
+ 791 case num_type::Null:
throw std::runtime_error(
"Number with num_type Null");
+
+
+
+ 795 case type::String: os <<
'"' << r.s() <<
'"';
break;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 818 os <<
'"' << escape(x.key_) <<
"\":";
+
+
+
+
+
+
+ 825 case type::Function: os <<
"custom function";
break;
+
+
+
+
+
+
+
+
+ 834 inline bool operator==(
const rvalue& l,
const std::string& r)
+
+
+
+
+ 839 inline bool operator==(
const std::string& l,
const rvalue& r)
+
+
+
+
+ 844 inline bool operator!=(
const rvalue& l,
const std::string& r)
+
+
+
+
+ 849 inline bool operator!=(
const std::string& l,
const rvalue& r)
+
+
+
+
+ 854 inline bool operator==(
const rvalue& l,
double r)
+
+
+
+
+ 859 inline bool operator==(
double l,
const rvalue& r)
+
+
+
+
+ 864 inline bool operator!=(
const rvalue& l,
double r)
+
+
+
+
+ 869 inline bool operator!=(
double l,
const rvalue& r)
+
+
+
+
+
+ 875 inline rvalue load_nocopy_internal(
char* data,
size_t size)
+
+
+ 878 static constexpr
unsigned max_depth = 10000;
+
+
+
+
+ 883 Parser(
char* data_,
size_t ):
+
+
+
+
+
+
+ 890 if (CROW_UNLIKELY(*data != c))
+
+
+
+
+
+
+
+ 898 while (*data ==
' ' || *data ==
'\t' || *data ==
'\r' || *data ==
'\n')
+
+
+
+ 902 rvalue decode_string()
+
+ 904 if (CROW_UNLIKELY(!consume(
'"')))
+
+
+ 907 uint8_t has_escaping = 0;
+
+
+ 910 if (CROW_LIKELY(*data !=
'"' && *data !=
'\\' && *data !=
'\0'))
+
+
+
+ 914 else if (*data ==
'"')
+
+
+ 917 *(start - 1) = has_escaping;
+
+ 919 return {type::String, start, data - 1};
+
+ 921 else if (*data ==
'\\')
+
+
+
+
+
+
+
+ 929 auto check = [](
char c) {
+ 930 return (
'0' <= c && c <=
'9') ||
+ 931 (
'a' <= c && c <=
'f') ||
+ 932 (
'A' <= c && c <=
'F');
+
+ 934 if (!(check(*(data + 1)) &&
+ 935 check(*(data + 2)) &&
+ 936 check(*(data + 3)) &&
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 962 rvalue decode_list(
unsigned depth)
+
+ 964 rvalue ret(type::List);
+ 965 if (CROW_UNLIKELY(!consume(
'[')) || CROW_UNLIKELY(depth > max_depth))
+
+
+
+
+
+ 971 if (CROW_UNLIKELY(*data ==
']'))
+
+
+
+
+
+
+
+ 979 auto v = decode_value(depth + 1);
+ 980 if (CROW_UNLIKELY(!v))
+
+
+
+
+
+ 986 ret.emplace_back(std::move(v));
+
+
+
+
+
+ 992 if (CROW_UNLIKELY(!consume(
',')))
+
+
+
+
+
+
+
+
+
+ 1002 rvalue decode_number()
+
+
+
+ 1006 enum NumberParsingState
+
+
+
+
+
+
+
+
+
+
+ 1017 while (CROW_LIKELY(state != Invalid))
+
+
+
+
+ 1022 state =
static_cast<NumberParsingState
>(
"\2\2\7\3\4\6\6"[state]);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1049 state =
static_cast<NumberParsingState
>(
"\3\3\7\3\4\6\6"[state]);
+ 1050 while (*(data + 1) >=
'0' && *(data + 1) <=
'9')
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1070 state =
static_cast<NumberParsingState
>(
"\7\7\4\4\7\7\7"[state]);
+
+
+
+
+
+
+
+
+
+
+ 1081 state =
static_cast<NumberParsingState
>(
"\1\7\7\7\7\6\7"[state]);
+
+
+
+
+
+
+
+
+
+
+
+
+ 1094 state =
static_cast<NumberParsingState
>(
"\7\7\7\7\7\6\7"[state]);
+
+
+
+
+
+
+
+
+
+ 1104 state =
static_cast<NumberParsingState
>(
"\7\7\7\5\5\7\7"[state]);
+
+
+
+
+
+
+
+
+
+ 1114 if (CROW_LIKELY(state == NumberParsingState::ZeroFirst ||
+ 1115 state == NumberParsingState::Digits ||
+ 1116 state == NumberParsingState::DigitsAfterPoints ||
+ 1117 state == NumberParsingState::DigitsAfterE))
+ 1118 return {type::Number, start, data};
+
+
+
+
+
+
+
+
+
+
+ 1129 rvalue decode_value(
unsigned depth)
+
+
+
+
+ 1134 return decode_list(depth + 1);
+
+ 1136 return decode_object(depth + 1);
+
+ 1138 return decode_string();
+
+
+
+
+
+
+
+ 1146 return {type::True};
+
+
+
+
+
+
+
+
+
+
+
+ 1158 return {type::False};
+
+
+
+
+
+
+
+
+
+
+ 1169 return {type::Null};
+
+
+
+
+
+
+
+
+ 1178 return decode_number();
+
+
+
+
+ 1183 rvalue decode_object(
unsigned depth)
+
+ 1185 rvalue ret(type::Object);
+ 1186 if (CROW_UNLIKELY(!consume(
'{')) || CROW_UNLIKELY(depth > max_depth))
+
+
+
+
- 1192 if (CROW_UNLIKELY(*data ==
'}'))
-
-
-
-
-
-
-
- 1200 auto t = decode_string();
- 1201 if (CROW_UNLIKELY(!t))
-
-
-
-
-
-
- 1208 if (CROW_UNLIKELY(!consume(
':')))
-
-
-
-
-
-
-
-
-
-
- 1219 auto v = decode_value(depth + 1);
- 1220 if (CROW_UNLIKELY(!v))
-
-
-
-
-
-
- 1227 v.key_ = std::move(key);
- 1228 ret.emplace_back(std::move(v));
- 1229 if (CROW_UNLIKELY(*data ==
'}'))
-
-
-
-
- 1234 if (CROW_UNLIKELY(!consume(
',')))
-
-
-
-
-
-
-
-
-
-
-
-
- 1247 auto ret = decode_value(0);
+
+
+ 1194 if (CROW_UNLIKELY(*data ==
'}'))
+
+
+
+
+
+
+
+ 1202 auto t = decode_string();
+ 1203 if (CROW_UNLIKELY(!t))
+
+
+
+
+
+
+ 1210 if (CROW_UNLIKELY(!consume(
':')))
+
+
+
+
+
+
+
+
+
+
+ 1221 auto v = decode_value(depth + 1);
+ 1222 if (CROW_UNLIKELY(!v))
+
+
+
+
+
+
+ 1229 v.key_ = std::move(key);
+ 1230 ret.emplace_back(std::move(v));
+ 1231 if (CROW_UNLIKELY(*data ==
'}'))
+
+
+
+
+ 1236 if (CROW_UNLIKELY(!consume(
',')))
+
+
+
+
+
+
+
+
+
+
+
- 1249 if (ret && *data !=
'\0')
-
-
-
-
-
-
- 1256 return Parser(data, size).parse();
-
- 1258 inline rvalue
load(
const char* data,
size_t size)
-
- 1260 char* s =
new char[size + 1];
- 1261 memcpy(s, data, size);
-
- 1263 auto ret = load_nocopy_internal(s, size);
-
- 1265 ret.key_.force(s, size);
-
-
-
-
-
- 1271 inline rvalue
load(
const char* data)
-
- 1273 return load(data, strlen(data));
-
-
- 1276 inline rvalue
load(
const std::string& str)
-
- 1278 return load(str.data(), str.size());
-
-
- 1281 struct wvalue_reader;
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1295 #ifdef CROW_JSON_USE_MAP
- 1296 std::map<std::string, wvalue>;
-
- 1298 std::unordered_map<std::string, wvalue>;
-
-
- 1301 using list = std::vector<wvalue>;
+ 1249 auto ret = decode_value(0);
+
+ 1251 if (ret && *data !=
'\0')
+
+
+
+
+
+
+ 1258 return Parser(data, size).parse();
+
+ 1260 inline rvalue
load(
const char* data,
size_t size)
+
+ 1262 char* s =
new char[size + 1];
+ 1263 memcpy(s, data, size);
+
+ 1265 auto ret = load_nocopy_internal(s, size);
+
+ 1267 ret.key_.force(s, size);
+
+
+
+
+
+ 1273 inline rvalue
load(
const char* data)
+
+ 1275 return load(data, strlen(data));
+
+
+ 1278 inline rvalue
load(
const std::string& str)
+
+ 1280 return load(str.data(), str.size());
+
+
+ 1283 struct wvalue_reader;
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1297 #ifdef CROW_JSON_USE_MAP
+ 1298 std::map<std::string, wvalue>;
+
+ 1300 std::unordered_map<std::string, wvalue>;
+
- 1303 type t()
const {
return t_; }
-
-
-
-
-
- 1309 type t_{type::Null};
- 1310 num_type nt{num_type::Null};
-
-
-
-
-
-
-
- 1318 constexpr number() noexcept:
-
- 1320 constexpr number(std::uint64_t value) noexcept:
-
- 1322 constexpr number(std::int64_t value) noexcept:
-
- 1324 explicit constexpr number(
double value) noexcept:
-
- 1326 explicit constexpr number(
float value) noexcept:
+ 1303 using list = std::vector<wvalue>;
+
+ 1305 type t()
const {
return t_; }
+
+
+
+
+
+ 1311 type t_{type::Null};
+ 1312 num_type nt{num_type::Null};
+
+
+
+
+
+
+
+ 1320 constexpr number() noexcept:
+
+ 1322 constexpr number(std::uint64_t value) noexcept:
+
+ 1324 constexpr number(std::int64_t value) noexcept:
+
+ 1326 explicit constexpr number(
double value) noexcept:
-
-
- 1330 std::unique_ptr<list> l;
- 1331 std::unique_ptr<object> o;
- 1332 std::function<std::string(std::string&)> f;
-
-
-
- 1336 returnable(
"application/json") {}
-
- 1338 wvalue(std::nullptr_t):
- 1339 returnable(
"application/json"), t_(type::Null) {}
-
-
- 1342 returnable(
"application/json"), t_(value ? type::True : type::False) {}
-
- 1344 wvalue(std::uint8_t value):
- 1345 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
- 1346 wvalue(std::uint16_t value):
+ 1328 explicit constexpr number(
float value) noexcept:
+
+
+
+ 1332 std::unique_ptr<list> l;
+ 1333 std::unique_ptr<object> o;
+ 1334 std::function<std::string(std::string&)> f;
+
+
+
+ 1338 returnable(
"application/json") {}
+
+ 1340 wvalue(std::nullptr_t):
+ 1341 returnable(
"application/json"), t_(type::Null) {}
+
+
+ 1344 returnable(
"application/json"), t_(value ? type::True : type::False) {}
+
+ 1346 wvalue(std::uint8_t value):
1347 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
- 1348 wvalue(std::uint32_t value):
+ 1348 wvalue(std::uint16_t value):
1349 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
- 1350 wvalue(std::uint64_t value):
+ 1350 wvalue(std::uint32_t value):
1351 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
-
- 1353 wvalue(std::int8_t value):
- 1354 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
- 1355 wvalue(std::int16_t value):
+ 1352 wvalue(std::uint64_t value):
+ 1353 returnable(
"application/json"), t_(type::Number), nt(num_type::Unsigned_integer), num(static_cast<std::uint64_t>(value)) {}
+
+ 1355 wvalue(std::int8_t value):
1356 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
- 1357 wvalue(std::int32_t value):
+ 1357 wvalue(std::int16_t value):
1358 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
- 1359 wvalue(std::int64_t value):
+ 1359 wvalue(std::int32_t value):
1360 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
-
- 1362 wvalue(
float value):
- 1363 returnable(
"application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
- 1364 wvalue(
double value):
- 1365 returnable(
"application/json"), t_(type::Number), nt(num_type::Double_precision_floating_point), num(static_cast<double>(value)) {}
-
- 1367 wvalue(
char const* value):
- 1368 returnable(
"application/json"), t_(type::String), s(value) {}
-
- 1370 wvalue(std::string
const& value):
- 1371 returnable(
"application/json"), t_(type::String), s(value) {}
- 1372 wvalue(std::string&& value):
- 1373 returnable(
"application/json"), t_(type::String), s(std::move(value)) {}
-
- 1375 wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list):
- 1376 returnable(
"application/json"), t_(type::Object), o(new object(initializer_list)) {}
-
- 1378 wvalue(
object const& value):
- 1379 returnable(
"application/json"), t_(type::Object), o(new object(value)) {}
- 1380 wvalue(
object&& value):
- 1381 returnable(
"application/json"), t_(type::Object), o(new object(std::move(value))) {}
-
- 1383 wvalue(
const list& r):
- 1384 returnable(
"application/json")
-
-
- 1387 l = std::unique_ptr<list>(
new list{});
- 1388 l->reserve(r.size());
- 1389 for (
auto it = r.begin(); it != r.end(); ++it)
- 1390 l->emplace_back(*it);
-
-
- 1393 returnable(
"application/json")
-
-
- 1396 l = std::unique_ptr<list>(
new list{});
- 1397 l->reserve(r.size());
- 1398 for (
auto it = r.begin(); it != r.end(); ++it)
- 1399 l->emplace_back(*it);
-
-
-
-
-
-
-
-
-
-
-
-
- 1412 case type::Function:
-
-
-
- 1416 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
-
- 1418 else if (nt == num_type::Signed_integer)
-
-
-
-
-
-
-
-
- 1427 l = std::unique_ptr<list>(
new list{});
- 1428 l->reserve(r.size());
- 1429 for (
auto it = r.begin(); it != r.end(); ++it)
- 1430 l->emplace_back(*it);
-
-
- 1433 o = std::unique_ptr<object>(
new object{});
- 1434 for (
auto it = r.begin(); it != r.end(); ++it)
- 1435 o->emplace(it->key(), *it);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1452 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
-
- 1454 else if (nt == num_type::Signed_integer)
-
-
-
-
-
-
-
-
- 1463 l = std::unique_ptr<list>(
new list{});
- 1464 l->reserve(r.
size());
- 1465 for (
auto it = r.l->begin(); it != r.l->end(); ++it)
- 1466 l->emplace_back(*it);
-
-
- 1469 o = std::unique_ptr<object>(
new object{});
- 1470 o->insert(r.o->begin(), r.o->end());
-
- 1472 case type::Function:
-
-
-
-
-
- 1478 returnable(
"application/json")
-
- 1480 *
this = std::move(r);
-
-
- 1483 wvalue& operator=(wvalue&& r)
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1507 wvalue& operator=(std::nullptr_t)
-
-
-
-
- 1512 wvalue& operator=(
bool value)
-
-
-
-
-
-
-
-
-
- 1522 wvalue& operator=(
float value)
-
-
-
-
- 1527 nt = num_type::Floating_point;
-
-
-
- 1531 wvalue& operator=(
double value)
-
-
-
-
- 1536 nt = num_type::Double_precision_floating_point;
-
-
-
- 1540 wvalue& operator=(
unsigned short value)
-
-
-
-
- 1545 nt = num_type::Unsigned_integer;
-
-
-
- 1549 wvalue& operator=(
short value)
-
-
-
-
- 1554 nt = num_type::Signed_integer;
-
-
-
- 1558 wvalue& operator=(
long long value)
-
-
-
-
- 1563 nt = num_type::Signed_integer;
-
-
-
- 1567 wvalue& operator=(
long value)
-
-
-
-
- 1572 nt = num_type::Signed_integer;
-
-
-
- 1576 wvalue& operator=(
int value)
-
-
-
-
- 1581 nt = num_type::Signed_integer;
-
-
-
- 1585 wvalue& operator=(
unsigned long long value)
-
-
-
-
- 1590 nt = num_type::Unsigned_integer;
-
-
-
- 1594 wvalue& operator=(
unsigned long value)
-
-
-
-
- 1599 nt = num_type::Unsigned_integer;
-
-
-
- 1603 wvalue& operator=(
unsigned int value)
-
-
-
-
- 1608 nt = num_type::Unsigned_integer;
-
-
-
- 1612 wvalue& operator=(
const char* str)
-
-
-
-
-
-
-
- 1620 wvalue& operator=(
const std::string& str)
-
-
-
-
-
-
-
- 1628 wvalue& operator=(list&& v)
-
- 1630 if (t_ != type::List)
-
-
-
- 1634 l = std::unique_ptr<list>(
new list{});
-
- 1636 l->resize(v.size());
-
-
-
- 1640 (*l)[idx++] = std::move(x);
-
-
-
-
- 1645 template<
typename T>
- 1646 wvalue& operator=(
const std::vector<T>& v)
-
- 1648 if (t_ != type::List)
-
-
-
- 1652 l = std::unique_ptr<list>(
new list{});
-
- 1654 l->resize(v.size());
-
-
-
-
-
-
-
-
- 1663 wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
-
- 1665 if (t_ != type::Object)
-
-
-
- 1669 o = std::unique_ptr<object>(
new object(initializer_list));
-
-
-
- 1673 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
- 1674 o = std::unique_ptr<object>(
new object(initializer_list));
-
- 1676 (*o) = initializer_list;
-
-
-
-
-
- 1682 wvalue& operator=(
object const& value)
-
- 1684 if (t_ != type::Object)
-
-
-
- 1688 o = std::unique_ptr<object>(
new object(value));
-
-
-
- 1692 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
- 1693 o = std::unique_ptr<object>(
new object(value));
-
-
-
-
-
-
-
- 1701 wvalue& operator=(
object&& value)
-
- 1703 if (t_ != type::Object)
-
-
-
- 1707 o = std::unique_ptr<object>(
new object(std::move(value)));
-
-
-
- 1711 (*o) = std::move(value);
-
-
-
-
- 1716 wvalue& operator=(std::function<std::string(std::string&)>&& func)
-
-
- 1719 t_ = type::Function;
- 1720 f = std::move(func);
-
-
-
- 1724 wvalue& operator[](
unsigned index)
-
- 1726 if (t_ != type::List)
-
-
-
- 1730 l = std::unique_ptr<list>(
new list{});
- 1731 if (l->size() < index + 1)
- 1732 l->resize(index + 1);
-
-
-
- 1736 const wvalue& operator[](
unsigned index)
const
-
- 1738 return const_cast<wvalue*
>(
this)->
operator[](index);
-
-
- 1741 int count(
const std::string& str)
const
-
- 1743 if (t_ != type::Object)
-
-
+ 1361 wvalue(std::int64_t value):
+ 1362 returnable(
"application/json"), t_(type::Number), nt(num_type::Signed_integer), num(static_cast<std::int64_t>(value)) {}
+
+ 1364 wvalue(
float value):
+ 1365 returnable(
"application/json"), t_(type::Number), nt(num_type::Floating_point), num(static_cast<double>(value)) {}
+ 1366 wvalue(
double value):
+ 1367 returnable(
"application/json"), t_(type::Number), nt(num_type::Double_precision_floating_point), num(static_cast<double>(value)) {}
+
+ 1369 wvalue(
char const* value):
+ 1370 returnable(
"application/json"), t_(type::String), s(value) {}
+
+ 1372 wvalue(std::string
const& value):
+ 1373 returnable(
"application/json"), t_(type::String), s(value) {}
+ 1374 wvalue(std::string&& value):
+ 1375 returnable(
"application/json"), t_(type::String), s(std::move(value)) {}
+
+ 1377 wvalue(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list):
+ 1378 returnable(
"application/json"), t_(type::Object), o(new object(initializer_list)) {}
+
+ 1380 wvalue(
object const& value):
+ 1381 returnable(
"application/json"), t_(type::Object), o(new object(value)) {}
+ 1382 wvalue(
object&& value):
+ 1383 returnable(
"application/json"), t_(type::Object), o(new object(std::move(value))) {}
+
+ 1385 wvalue(
const list& r):
+ 1386 returnable(
"application/json")
+
+
+ 1389 l = std::unique_ptr<list>(
new list{});
+ 1390 l->reserve(r.size());
+ 1391 for (
auto it = r.begin(); it != r.end(); ++it)
+ 1392 l->emplace_back(*it);
+
+
+ 1395 returnable(
"application/json")
+
+
+ 1398 l = std::unique_ptr<list>(
new list{});
+ 1399 l->reserve(r.size());
+ 1400 for (
auto it = r.begin(); it != r.end(); ++it)
+ 1401 l->emplace_back(*it);
+
+
+
+
+
+
+
+
+
+
+
+
+ 1414 case type::Function:
+
+
+
+ 1418 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
+
+ 1420 else if (nt == num_type::Signed_integer)
+
+
+
+
+
+
+
+
+ 1429 l = std::unique_ptr<list>(
new list{});
+ 1430 l->reserve(r.size());
+ 1431 for (
auto it = r.begin(); it != r.end(); ++it)
+ 1432 l->emplace_back(*it);
+
+
+ 1435 o = std::unique_ptr<object>(
new object{});
+ 1436 for (
auto it = r.begin(); it != r.end(); ++it)
+ 1437 o->emplace(it->key(), *it);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1454 if (nt == num_type::Floating_point || nt == num_type::Double_precision_floating_point)
+
+ 1456 else if (nt == num_type::Signed_integer)
+
+
+
+
+
+
+
+
+ 1465 l = std::unique_ptr<list>(
new list{});
+ 1466 l->reserve(r.
size());
+ 1467 for (
auto it = r.l->begin(); it != r.l->end(); ++it)
+ 1468 l->emplace_back(*it);
+
+
+ 1471 o = std::unique_ptr<object>(
new object{});
+ 1472 o->insert(r.o->begin(), r.o->end());
+
+ 1474 case type::Function:
+
+
+
+
+
+ 1480 returnable(
"application/json")
+
+ 1482 *
this = std::move(r);
+
+
+ 1485 wvalue& operator=(wvalue&& r)
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1509 wvalue& operator=(std::nullptr_t)
+
+
+
+
+ 1514 wvalue& operator=(
bool value)
+
+
+
+
+
+
+
+
+
+ 1524 wvalue& operator=(
float value)
+
+
+
+
+ 1529 nt = num_type::Floating_point;
+
+
+
+ 1533 wvalue& operator=(
double value)
+
+
+
+
+ 1538 nt = num_type::Double_precision_floating_point;
+
+
+
+ 1542 wvalue& operator=(
unsigned short value)
+
+
+
+
+ 1547 nt = num_type::Unsigned_integer;
+
+
+
+ 1551 wvalue& operator=(
short value)
+
+
+
+
+ 1556 nt = num_type::Signed_integer;
+
+
+
+ 1560 wvalue& operator=(
long long value)
+
+
+
+
+ 1565 nt = num_type::Signed_integer;
+
+
+
+ 1569 wvalue& operator=(
long value)
+
+
+
+
+ 1574 nt = num_type::Signed_integer;
+
+
+
+ 1578 wvalue& operator=(
int value)
+
+
+
+
+ 1583 nt = num_type::Signed_integer;
+
+
+
+ 1587 wvalue& operator=(
unsigned long long value)
+
+
+
+
+ 1592 nt = num_type::Unsigned_integer;
+
+
+
+ 1596 wvalue& operator=(
unsigned long value)
+
+
+
+
+ 1601 nt = num_type::Unsigned_integer;
+
+
+
+ 1605 wvalue& operator=(
unsigned int value)
+
+
+
+
+ 1610 nt = num_type::Unsigned_integer;
+
+
+
+ 1614 wvalue& operator=(
const char* str)
+
+
+
+
+
+
+
+ 1622 wvalue& operator=(
const std::string& str)
+
+
+
+
+
+
+
+ 1630 wvalue& operator=(list&& v)
+
+ 1632 if (t_ != type::List)
+
+
+
+ 1636 l = std::unique_ptr<list>(
new list{});
+
+ 1638 l->resize(v.size());
+
+
+
+ 1642 (*l)[idx++] = std::move(x);
+
+
+
+
+ 1647 template<
typename T>
+ 1648 wvalue& operator=(
const std::vector<T>& v)
+
+ 1650 if (t_ != type::List)
+
+
+
+ 1654 l = std::unique_ptr<list>(
new list{});
+
+ 1656 l->resize(v.size());
+
+
+
+
+
+
+
+
+ 1665 wvalue& operator=(std::initializer_list<std::pair<std::string const, wvalue>> initializer_list)
+
+ 1667 if (t_ != type::Object)
+
+
+
+ 1671 o = std::unique_ptr<object>(
new object(initializer_list));
+
+
+
+ 1675 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
+ 1676 o = std::unique_ptr<object>(
new object(initializer_list));
+
+ 1678 (*o) = initializer_list;
+
+
+
+
+
+ 1684 wvalue& operator=(
object const& value)
+
+ 1686 if (t_ != type::Object)
+
+
+
+ 1690 o = std::unique_ptr<object>(
new object(value));
+
+
+
+ 1694 #if defined(__APPLE__) || defined(__MACH__) || defined(__FreeBSD__) || defined(__ANDROID__) || defined(_LIBCPP_VERSION)
+ 1695 o = std::unique_ptr<object>(
new object(value));
+
+
+
+
+
+
+
+ 1703 wvalue& operator=(
object&& value)
+
+ 1705 if (t_ != type::Object)
+
+
+
+ 1709 o = std::unique_ptr<object>(
new object(std::move(value)));
+
+
+
+ 1713 (*o) = std::move(value);
+
+
+
+
+ 1718 wvalue& operator=(std::function<std::string(std::string&)>&& func)
+
+
+ 1721 t_ = type::Function;
+ 1722 f = std::move(func);
+
+
+
+ 1726 wvalue& operator[](
unsigned index)
+
+ 1728 if (t_ != type::List)
+
+
+
+ 1732 l = std::unique_ptr<list>(
new list{});
+ 1733 if (l->size() < index + 1)
+ 1734 l->resize(index + 1);
+
+
+
+ 1738 const wvalue& operator[](
unsigned index)
const
+
+ 1740 return const_cast<wvalue*
>(
this)->
operator[](index);
+
+
+ 1743 int count(
const std::string& str)
const
+
+ 1745 if (t_ != type::Object)
- 1747 return o->count(str);
-
-
- 1750 wvalue& operator[](
const std::string& str)
-
- 1752 if (t_ != type::Object)
-
-
-
- 1756 o = std::unique_ptr<object>(
new object{});
-
-
-
- 1760 const wvalue& operator[](
const std::string& str)
const
-
- 1762 return const_cast<wvalue*
>(
this)->
operator[](str);
-
-
- 1765 std::vector<std::string> keys()
const
-
- 1767 if (t_ != type::Object)
-
- 1769 std::vector<std::string> result;
-
-
- 1772 result.push_back(kv.first);
-
-
-
-
- 1777 std::string execute(std::string txt =
"") const
-
- 1779 if (t_ != type::Function)
-
-
-
-
-
-
-
- 1787 if (t_ != type::List)
-
-
-
-
-
-
-
-
-
- 1797 case type::Null:
return 4;
- 1798 case type::False:
return 5;
- 1799 case type::True:
return 4;
- 1800 case type::Number:
return 30;
- 1801 case type::String:
return 2 + s.size() + s.size() / 2;
-
-
-
-
-
-
-
-
- 1810 sum += x.estimate_length();
-
-
-
-
-
-
-
-
-
-
-
-
- 1823 sum += 2 + kv.first.size() + kv.first.size() / 2;
- 1824 sum += kv.second.estimate_length();
-
-
-
-
- 1829 case type::Function:
-
-
-
-
-
-
- 1836 inline void dump_string(
const std::string& str, std::string& out)
const
-
-
-
+
+
+ 1749 return o->count(str);
+
+
+ 1752 wvalue& operator[](
const std::string& str)
+
+ 1754 if (t_ != type::Object)
+
+
+
+ 1758 o = std::unique_ptr<object>(
new object{});
+
+
+
+ 1762 const wvalue& operator[](
const std::string& str)
const
+
+ 1764 return const_cast<wvalue*
>(
this)->
operator[](str);
+
+
+ 1767 std::vector<std::string> keys()
const
+
+ 1769 if (t_ != type::Object)
+
+ 1771 std::vector<std::string> result;
+
+
+ 1774 result.push_back(kv.first);
+
+
+
+
+ 1779 std::string execute(std::string txt =
"") const
+
+ 1781 if (t_ != type::Function)
+
+
+
+
+
+
+
+ 1789 if (t_ != type::List)
+
+
+
+
+
+
+
+
+
+ 1799 case type::Null:
return 4;
+ 1800 case type::False:
return 5;
+ 1801 case type::True:
return 4;
+ 1802 case type::Number:
return 30;
+ 1803 case type::String:
return 2 + s.size() + s.size() / 2;
+
+
+
+
+
+
+
+
+ 1812 sum += x.estimate_length();
+
+
+
+
+
+
+
+
+
+
+
+
+ 1825 sum += 2 + kv.first.size() + kv.first.size() / 2;
+ 1826 sum += kv.second.estimate_length();
+
+
+
+
+ 1831 case type::Function:
+
+
+
+
+
+
+ 1838 inline void dump_string(
const std::string& str, std::string& out)
const
+
-
-
- 1843 inline void dump_indentation_part(std::string& out,
const int indent,
const char separator,
const int indent_level)
const
-
- 1845 out.push_back(
'\n');
- 1846 out.append(indent_level * indent, separator);
-
-
-
- 1850 inline void dump_internal(
const wvalue& v, std::string& out,
const int indent,
const char separator,
const int indent_level = 0)
const
-
-
-
- 1854 case type::Null: out +=
"null";
break;
- 1855 case type::False: out +=
"false";
break;
- 1856 case type::True: out +=
"true";
break;
-
-
- 1859 if (v.nt == num_type::Floating_point || v.nt == num_type::Double_precision_floating_point)
-
- 1861 if (isnan(v.num.d) || isinf(v.num.d))
-
-
- 1864 CROW_LOG_WARNING <<
"Invalid JSON value detected (" << v.num.d <<
"), value set to null";
-
-
-
-
-
-
-
-
-
- 1874 if (v.nt == num_type::Double_precision_floating_point)
-
-
- 1877 sprintf_s(outbuf,
sizeof(outbuf),
"%.*g", DECIMAL_DIG, v.num.d);
-
- 1879 snprintf(outbuf,
sizeof(outbuf),
"%.*g", DECIMAL_DIG, v.num.d);
-
-
-
-
-
- 1885 sprintf_s(outbuf,
sizeof(outbuf),
"%f", v.num.d);
-
- 1887 snprintf(outbuf,
sizeof(outbuf),
"%f", v.num.d);
-
-
- 1890 char *p = &outbuf[0], *o =
nullptr;
-
-
-
-
-
-
-
-
-
-
- 1901 char fch = *(p + 1);
-
- 1903 if (fch !=
'\0' && fch ==
'0') p++;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1930 else if (v.nt == num_type::Signed_integer)
-
- 1932 out += std::to_string(v.num.si);
-
-
-
- 1936 out += std::to_string(v.num.ui);
-
-
-
- 1940 case type::String: dump_string(v.s, out);
break;
-
-
-
-
-
-
- 1947 dump_indentation_part(out, indent, separator, indent_level + 1);
-
-
-
-
-
- 1953 for (
auto& x : *v.l)
-
-
-
-
-
-
-
- 1961 dump_indentation_part(out, indent, separator, indent_level + 1);
-
-
-
- 1965 dump_internal(x, out, indent, separator, indent_level + 1);
-
-
-
-
-
- 1971 dump_indentation_part(out, indent, separator, indent_level);
-
-
-
-
-
-
-
-
-
-
-
- 1983 dump_indentation_part(out, indent, separator, indent_level + 1);
-
-
-
-
-
- 1989 for (
auto& kv : *v.o)
-
-
-
-
-
-
- 1996 dump_indentation_part(out, indent, separator, indent_level + 1);
-
-
-
- 2000 dump_string(kv.first, out);
-
-
-
-
-
-
-
- 2008 dump_internal(kv.second, out, indent, separator, indent_level + 1);
-
-
-
-
-
- 2014 dump_indentation_part(out, indent, separator, indent_level);
-
-
-
-
-
-
- 2021 case type::Function:
- 2022 out +=
"custom function";
-
-
-
-
-
- 2028 std::string dump(
const int indent,
const char separator =
' ')
const
-
-
-
- 2032 dump_internal(*
this, ret, indent, separator);
-
-
-
- 2036 std::string dump()
const override
-
- 2038 static constexpr
int DontIndent = -1;
-
- 2040 return dump(DontIndent);
-
-
-
-
-
-
- 2047 int64_t get(int64_t fallback)
-
- 2049 if (ref.t() != type::Number || ref.nt == num_type::Floating_point ||
- 2050 ref.nt == num_type::Double_precision_floating_point)
-
-
-
-
- 2055 double get(
double fallback)
-
- 2057 if (ref.t() != type::Number || ref.nt != num_type::Floating_point ||
- 2058 ref.nt == num_type::Double_precision_floating_point)
-
-
-
-
- 2063 bool get(
bool fallback)
-
- 2065 if (ref.t() == type::True)
return true;
- 2066 if (ref.t() == type::False)
return false;
-
-
-
- 2070 std::string get(
const std::string& fallback)
-
- 2072 if (ref.t() != type::String)
return fallback;
-
-
-
-
-
+
+
+
+
+ 1845 inline void dump_indentation_part(std::string& out,
const int indent,
const char separator,
const int indent_level)
const
+
+ 1847 out.push_back(
'\n');
+ 1848 out.append(indent_level * indent, separator);
+
+
+
+ 1852 inline void dump_internal(
const wvalue& v, std::string& out,
const int indent,
const char separator,
const int indent_level = 0)
const
+
+
+
+ 1856 case type::Null: out +=
"null";
break;
+ 1857 case type::False: out +=
"false";
break;
+ 1858 case type::True: out +=
"true";
break;
+
+
+ 1861 if (v.nt == num_type::Floating_point || v.nt == num_type::Double_precision_floating_point)
+
+ 1863 if (isnan(v.num.d) || isinf(v.num.d))
+
+
+ 1866 CROW_LOG_WARNING <<
"Invalid JSON value detected (" << v.num.d <<
"), value set to null";
+
+
+
+
+
+
+
+
+
+ 1876 if (v.nt == num_type::Double_precision_floating_point)
+
+
+ 1879 sprintf_s(outbuf,
sizeof(outbuf),
"%.*g", DECIMAL_DIG, v.num.d);
+
+ 1881 snprintf(outbuf,
sizeof(outbuf),
"%.*g", DECIMAL_DIG, v.num.d);
+
+
+
+
+
+ 1887 sprintf_s(outbuf,
sizeof(outbuf),
"%f", v.num.d);
+
+ 1889 snprintf(outbuf,
sizeof(outbuf),
"%f", v.num.d);
+
+
+ 1892 char* p = &outbuf[0];
+ 1893 char* pos_first_trailing_0 =
nullptr;
+
+
+
+
+
+
+
+
+
+
+ 1904 char fch = *(p + 1);
+
+ 1906 if (fch !=
'\0' && fch ==
'0') p++;
+
+
+
+
+
+
+
+
+ 1915 pos_first_trailing_0 = p;
+
+
+
+
+
+
+ 1922 pos_first_trailing_0 =
nullptr;
+
+
+
+
+
+
+ 1929 if (pos_first_trailing_0 !=
nullptr)
+ 1930 *pos_first_trailing_0 =
'\0';
+
+
+ 1933 else if (v.nt == num_type::Signed_integer)
+
+ 1935 out += std::to_string(v.num.si);
+
+
+
+ 1939 out += std::to_string(v.num.ui);
+
+
+
+ 1943 case type::String: dump_string(v.s, out);
break;
+
+
+
+
+
+
+ 1950 dump_indentation_part(out, indent, separator, indent_level + 1);
+
+
+
+
+
+ 1956 for (
auto& x : *v.l)
+
+
+
+
+
+
+
+ 1964 dump_indentation_part(out, indent, separator, indent_level + 1);
+
+
+
+ 1968 dump_internal(x, out, indent, separator, indent_level + 1);
+
+
+
+
+
+ 1974 dump_indentation_part(out, indent, separator, indent_level);
+
+
+
+
+
+
+
+
+
+
+
+ 1986 dump_indentation_part(out, indent, separator, indent_level + 1);
+
+
+
+
+
+ 1992 for (
auto& kv : *v.o)
+
+
+
+
+
+
+ 1999 dump_indentation_part(out, indent, separator, indent_level + 1);
+
+
+
+ 2003 dump_string(kv.first, out);
+
+
+
+
+
+
+
+ 2011 dump_internal(kv.second, out, indent, separator, indent_level + 1);
+
+
+
+
+
+ 2017 dump_indentation_part(out, indent, separator, indent_level);
+
+
+
+
+
+
+ 2024 case type::Function:
+ 2025 out +=
"custom function";
+
+
+
+
+
+ 2031 std::string dump(
const int indent,
const char separator =
' ')
const
+
+
+
+ 2035 dump_internal(*
this, ret, indent, separator);
+
+
+
+ 2039 std::string dump()
const override
+
+ 2041 static constexpr
int DontIndent = -1;
+
+ 2043 return dump(DontIndent);
+
+
+
+
+
+
+ 2050 int64_t get(int64_t fallback)
+
+ 2052 if (ref.t() != type::Number || ref.nt == num_type::Floating_point ||
+ 2053 ref.nt == num_type::Double_precision_floating_point)
+
+
+
+
+ 2058 double get(
double fallback)
+
+ 2060 if (ref.t() != type::Number || ref.nt != num_type::Floating_point ||
+ 2061 ref.nt == num_type::Double_precision_floating_point)
+
+
+
+
+ 2066 bool get(
bool fallback)
+
+ 2068 if (ref.t() == type::True)
return true;
+ 2069 if (ref.t() == type::False)
return false;
+
+
+
+ 2073 std::string get(
const std::string& fallback)
+
+ 2075 if (ref.t() != type::String)
return fallback;
+
+
-
-
-
-
-
-JSON read value.
Definition: json.h:276
-int64_t i() const
The integer value.
Definition: json.h:398
-bool has(const char *str) const
Check if the json object has the passed string as a key.
Definition: json.h:543
-double d() const
The double precision floating-point number value.
Definition: json.h:431
-bool b() const
The boolean value.
Definition: json.h:441
-uint64_t u() const
The unsigned integer value.
Definition: json.h:415
-std::vector< rvalue > lo() const
The list or object value.
Definition: json.h:462
-void unescape() const
Convert escaped string character to their original form ("\\n" -> ' ').
Definition: json.h:478
-num_type nt() const
The number type of the JSON value.
Definition: json.h:386
-type t() const
The type of the JSON value.
Definition: json.h:374
-detail::r_string s() const
The string value.
Definition: json.h:451
-JSON write value.
Definition: json.h:1289
-wvalue(const rvalue &r)
Create a write value from a read value (useful for editing JSON strings).
Definition: json.h:1403
-std::size_t size() const
If the wvalue is a list, it returns the length of the list, otherwise it returns 1.
Definition: json.h:1785
-size_t estimate_length() const
Returns an estimated size of the value in bytes.
Definition: json.h:1793
-static crow::json::wvalue empty_object()
Create an empty json value (outputs "{}" instead of a "null" string)
Definition: json.h:1306
-void clear()
Used for compatibility, same as reset()
Definition: json.h:1495
+
+
+
+
+
+
+
+
+JSON read value.
Definition: json.h:278
+int64_t i() const
The integer value.
Definition: json.h:400
+bool has(const char *str) const
Check if the json object has the passed string as a key.
Definition: json.h:545
+double d() const
The double precision floating-point number value.
Definition: json.h:433
+bool b() const
The boolean value.
Definition: json.h:443
+uint64_t u() const
The unsigned integer value.
Definition: json.h:417
+std::vector< rvalue > lo() const
The list or object value.
Definition: json.h:464
+void unescape() const
Convert escaped string character to their original form ("\\n" -> ' ').
Definition: json.h:480
+num_type nt() const
The number type of the JSON value.
Definition: json.h:388
+type t() const
The type of the JSON value.
Definition: json.h:376
+detail::r_string s() const
The string value.
Definition: json.h:453
+JSON write value.
Definition: json.h:1291
+wvalue(const rvalue &r)
Create a write value from a read value (useful for editing JSON strings).
Definition: json.h:1405
+std::size_t size() const
If the wvalue is a list, it returns the length of the list, otherwise it returns 1.
Definition: json.h:1787
+size_t estimate_length() const
Returns an estimated size of the value in bytes.
Definition: json.h:1795
+static crow::json::wvalue empty_object()
Create an empty json value (outputs "{}" instead of a "null" string)
Definition: json.h:1308
+void clear()
Used for compatibility, same as reset()
Definition: json.h:1497
Compiled mustache template object.
Definition: mustache.h:134
template_t load(const std::string &filename)
Open, read and renders a file using a mustache compiler. It also sanitize the input before compilatio...
Definition: mustache.h:812
The main namespace of the library. In this namespace is defined the most important classes and functi...
-A read string implementation with comparison functionality.
Definition: json.h:120
-char * s_
Start.
Definition: json.h:171
-char * e_
End.
Definition: json.h:172
-
+A read string implementation with comparison functionality.
Definition: json.h:122
+char * s_
Start.
Definition: json.h:173
+char * e_
End.
Definition: json.h:174
+
An abstract class that allows any other class to be returned by a handler.
Definition: returnable.h:9
diff --git a/master/reference/middleware_8h_source.html b/master/reference/middleware_8h_source.html
index 7ec375d98..2c8de62e5 100644
--- a/master/reference/middleware_8h_source.html
+++ b/master/reference/middleware_8h_source.html
@@ -387,8 +387,8 @@
-
- 290 indices(indices), slider(0) {}
+
+ 290 indices(indices_), slider(0) {}
293 bool enabled(
int mw_index)
const
@@ -409,8 +409,8 @@
-
- 312 indices(indices), slider(
int(indices.size()) - 1) {}
+
+ 312 indices(indices_), slider(
int(indices_.size()) - 1) {}
315 bool enabled(
int mw_index)
const
diff --git a/master/reference/multipart_8h_source.html b/master/reference/multipart_8h_source.html
index 3dba54858..fe8ab57c5 100644
--- a/master/reference/multipart_8h_source.html
+++ b/master/reference/multipart_8h_source.html
@@ -228,8 +228,8 @@
-
-
+ 130 message(
const ci_map& headers_,
const std::string& boundary_,
const std::vector<part>& sections):
+
134 content_type =
"multipart/form-data; boundary=" +
boundary;
@@ -249,7 +249,7 @@
150 content_type =
"multipart/form-data; boundary=" +
boundary;
-
+ 151 parse_body(req.body);
@@ -269,109 +269,108 @@
168 return std::string();
- 171 void parse_body(std::string body, std::vector<part>& sections,
mp_map&
part_map)
+ 171 void parse_body(std::string body)
-
- 174 std::string delimiter = dd +
boundary;
-
-
- 177 while (body != (crlf))
-
- 179 size_t found = body.find(delimiter);
- 180 if (found == std::string::npos)
-
-
-
-
- 185 std::string section = body.substr(0, found);
-
-
-
- 189 body.erase(0, found + delimiter.length() + 2);
- 190 if (!section.empty())
-
- 192 part parsed_section(parse_section(section));
-
-
-
- 196 sections.push_back(std::move(parsed_section));
-
-
-
-
- 201 part parse_section(std::string& section)
-
- 203 struct part to_return;
-
- 205 size_t found = section.find(crlf + crlf);
- 206 std::string head_line = section.substr(0, found + 2);
- 207 section.erase(0, found + 4);
-
- 209 parse_section_head(head_line, to_return);
- 210 to_return.body = section.substr(0, section.length() - 2);
-
-
-
- 214 void parse_section_head(std::string& lines, part& part)
-
- 216 while (!lines.empty())
-
-
-
- 220 size_t found = lines.find(crlf);
- 221 std::string line = lines.substr(0, found);
-
- 223 lines.erase(0, found + 2);
-
-
-
- 227 size_t found = line.find(
"; ");
- 228 std::string header = line.substr(0, found);
- 229 if (found != std::string::npos)
- 230 line.erase(0, found + 2);
-
- 232 line = std::string();
-
- 234 size_t header_split = header.find(
": ");
- 235 key = header.substr(0, header_split);
-
- 237 to_add.value = header.substr(header_split + 2);
-
-
-
- 241 while (!line.empty())
-
- 243 size_t found = line.find(
"; ");
- 244 std::string param = line.substr(0, found);
- 245 if (found != std::string::npos)
- 246 line.erase(0, found + 2);
-
- 248 line = std::string();
-
- 250 size_t param_split = param.find(
'=');
-
- 252 std::string value = param.substr(param_split + 1);
-
- 254 to_add.params.emplace(param.substr(0, param_split), trim(value));
-
- 256 part.headers.emplace(key, to_add);
-
-
-
- 260 inline std::string trim(std::string&
string,
const char& excess =
'"')
const
-
- 262 if (
string.length() > 1 &&
string[0] == excess &&
string[
string.length() - 1] == excess)
- 263 return string.substr(1,
string.length() - 2);
-
-
-
- 267 inline std::string pad(std::string&
string,
const char& padding =
'"')
const
-
- 269 return (padding +
string + padding);
-
-
-
-
+ 173 std::string delimiter = dd +
boundary;
+
+
+ 176 while (body != (crlf))
+
+ 178 size_t found = body.find(delimiter);
+ 179 if (found == std::string::npos)
+
+
+
+
+ 184 std::string section = body.substr(0, found);
+
+
+
+ 188 body.erase(0, found + delimiter.length() + 2);
+ 189 if (!section.empty())
+
+ 191 part parsed_section(parse_section(section));
+
+
+
+ 195 parts.push_back(std::move(parsed_section));
+
+
+
+
+ 200 part parse_section(std::string& section)
+
+ 202 struct part to_return;
+
+ 204 size_t found = section.find(crlf + crlf);
+ 205 std::string head_line = section.substr(0, found + 2);
+ 206 section.erase(0, found + 4);
+
+ 208 parse_section_head(head_line, to_return);
+ 209 to_return.body = section.substr(0, section.length() - 2);
+
+
+
+ 213 void parse_section_head(std::string& lines, part& part)
+
+ 215 while (!lines.empty())
+
+
+
+ 219 const size_t found_crlf = lines.find(crlf);
+ 220 std::string line = lines.substr(0, found_crlf);
+
+ 222 lines.erase(0, found_crlf + 2);
+
+
+
+ 226 const size_t found_semicolon = line.find(
"; ");
+ 227 std::string header = line.substr(0, found_semicolon);
+ 228 if (found_semicolon != std::string::npos)
+ 229 line.erase(0, found_semicolon + 2);
+
+ 231 line = std::string();
+
+ 233 size_t header_split = header.find(
": ");
+ 234 key = header.substr(0, header_split);
+
+ 236 to_add.value = header.substr(header_split + 2);
+
+
+
+ 240 while (!line.empty())
+
+ 242 const size_t found_semicolon = line.find(
"; ");
+ 243 std::string param = line.substr(0, found_semicolon);
+ 244 if (found_semicolon != std::string::npos)
+ 245 line.erase(0, found_semicolon + 2);
+
+ 247 line = std::string();
+
+ 249 size_t param_split = param.find(
'=');
+
+ 251 std::string value = param.substr(param_split + 1);
+
+ 253 to_add.params.emplace(param.substr(0, param_split), trim(value));
+
+ 255 part.headers.emplace(key, to_add);
+
+
+
+ 259 inline std::string trim(std::string&
string,
const char& excess =
'"')
const
+
+ 261 if (
string.length() > 1 &&
string[0] == excess &&
string[
string.length() - 1] == excess)
+ 262 return string.substr(1,
string.length() - 2);
+
+
+
+ 266 inline std::string pad(std::string&
string,
const char& padding =
'"')
const
+
+ 268 return (padding +
string + padding);
+
+
+
+
std::unordered_multimap< std::string, part, ci_hash, ci_key_eq > mp_map
Multipart map (key is the name parameter).
Definition: multipart.h:71
std::unordered_multimap< std::string, header, ci_hash, ci_key_eq > mph_map
Multipart header map (key is header key).
Definition: multipart.h:31
const header & get_header_object(const T &headers, const std::string &key)
Same as get_header_value_object() but for multipart::header.
Definition: multipart.h:47
@@ -382,7 +381,7 @@
The parsed multipart request/response.
Definition: multipart.h:75
-message(const ci_map &headers, const std::string &boundary, const std::vector< part > §ions)
Default constructor using default values.
Definition: multipart.h:130
+message(const ci_map &headers_, const std::string &boundary_, const std::vector< part > §ions)
Default constructor using default values.
Definition: multipart.h:130
std::vector< part > parts
The individual parts of the message.
Definition: multipart.h:78
message(const request &req)
Create a multipart message from a request data.
Definition: multipart.h:144
std::string boundary
The text boundary that separates different parts
Definition: multipart.h:77
diff --git a/master/reference/multipart__view_8h_source.html b/master/reference/multipart__view_8h_source.html
index 9a8cfc2d1..e04ed39b9 100644
--- a/master/reference/multipart__view_8h_source.html
+++ b/master/reference/multipart__view_8h_source.html
@@ -163,9 +163,9 @@
-
+
-
+
@@ -200,12 +200,12 @@
100 friend std::ostream& operator<<(std::ostream& stream,
const part_view& part)
- 102 for (
const auto& [key, value] : part.headers)
+ 102 for (
const auto& [header_key, header_value] : part.headers)
- 104 stream << key <<
": " << value.value;
- 105 for (
const auto& [key, value] : value.params)
+ 104 stream << header_key <<
": " << header_value.value;
+ 105 for (
const auto& [param_key, param_value] : header_value.params)
- 107 stream <<
"; " << key <<
'=' << padded{value};
+ 107 stream <<
"; " << param_key <<
'=' << padded{param_value};
@@ -240,7 +240,7 @@
- 142 friend std::ostream& operator<<(std::ostream& stream,
const message_view message)
+ 142 friend std::ostream& operator<<(std::ostream& stream,
const message_view message)
144 std::string delimiter = dd + message.boundary;
@@ -271,8 +271,8 @@
-
-
+ 173 message_view(
const ci_map& headers_,
const std::string& boundary_,
const std::vector<part_view>& sections):
+
@@ -287,7 +287,7 @@
187 boundary(get_boundary(get_header_value(
"Content-Type")))
-
+ 189 parse_body(req.body);
@@ -308,7 +308,7 @@
- 210 void parse_body(std::string_view body, std::vector<part_view>& sections,
mp_view_map&
part_map)
+ 210 void parse_body(std::string_view body)
212 const std::string delimiter = dd +
boundary;
@@ -333,7 +333,7 @@
- 235 sections.push_back(std::move(parsed_section));
+ 235 parts.push_back(std::move(parsed_section));
@@ -360,17 +360,17 @@
- 262 const size_t found = lines.find(crlf);
- 263 std::string_view line = lines.substr(0, found);
+ 262 const size_t found_crlf = lines.find(crlf);
+ 263 std::string_view line = lines.substr(0, found_crlf);
264 std::string_view key;
- 265 lines = lines.substr(found + 2);
+ 265 lines = lines.substr(found_crlf + 2);
- 269 const size_t found = line.find(
"; ");
- 270 std::string_view header = line.substr(0, found);
- 271 if (found != std::string_view::npos)
- 272 line = line.substr(found + 2);
+ 269 const size_t found_semicolon = line.find(
"; ");
+ 270 std::string_view header = line.substr(0, found_semicolon);
+ 271 if (found_semicolon != std::string_view::npos)
+ 272 line = line.substr(found_semicolon + 2);
274 line = std::string_view();
@@ -383,10 +383,10 @@
283 while (!line.empty())
- 285 const size_t found = line.find(
"; ");
- 286 std::string_view param = line.substr(0, found);
- 287 if (found != std::string_view::npos)
- 288 line = line.substr(found + 2);
+ 285 const size_t found_semicolon = line.find(
"; ");
+ 286 std::string_view param = line.substr(0, found_semicolon);
+ 287 if (found_semicolon != std::string_view::npos)
+ 288 line = line.substr(found_semicolon + 2);
290 line = std::string_view();
@@ -426,13 +426,13 @@
std::vector< part_view > parts
The individual parts of the message.
Definition: multipart_view.h:125
std::string dump(int part_) const
Represent an individual part as a string.
Definition: multipart_view.h:165
mp_view_map part_map
The individual parts of the message, organized in a map with the name header parameter being the key.
Definition: multipart_view.h:126
+message_view(const ci_map &headers_, const std::string &boundary_, const std::vector< part_view > §ions)
Default constructor using default values.
Definition: multipart_view.h:173
std::string boundary
The text boundary that separates different parts
Definition: multipart_view.h:124
message_view(const request &req)
Create a multipart message from a request data.
Definition: multipart_view.h:185
std::string dump() const
Represent all parts as a string (does not include message headers)
Definition: multipart_view.h:157
-message_view(const ci_map &headers, const std::string &boundary, const std::vector< part_view > §ions)
Default constructor using default values.
Definition: multipart_view.h:173
String padded with the specified padding (double quotes by default)
Definition: multipart_view.h:60
-friend std::ostream & operator<<(std::ostream &stream, const padded value)
Outputs padded value to the stream.
Definition: multipart_view.h:65
std::string_view value
String to pad.
Definition: multipart_view.h:61
+friend std::ostream & operator<<(std::ostream &stream, const padded value_)
Outputs padded value to the stream.
Definition: multipart_view.h:65
const char padding
Padding to use.
Definition: multipart_view.h:62
One part of the multipart message.
Definition: multipart_view.h:76
mph_view_map headers
(optional) The first part before the data, Contains information regarding the type of data and encodi...
Definition: multipart_view.h:77
diff --git a/master/reference/mustache_8h_source.html b/master/reference/mustache_8h_source.html
index 25a732f2e..f8f15f5e7 100644
--- a/master/reference/mustache_8h_source.html
+++ b/master/reference/mustache_8h_source.html
@@ -152,8 +152,8 @@
-
- 55 msg(
"crow::mustache error: " + msg)
+
+ 55 msg(
"crow::mustache error: " + msg_)
57 virtual const char* what()
const throw()
override
@@ -219,8 +219,8 @@
-
- 122 start(
static_cast<int>(start)), end(
static_cast<int>(end)), pos(
static_cast<int>(pos)), t(t)
+
+ 122 start(
static_cast<int>(start_)), end(
static_cast<int>(end_)), pos(
static_cast<int>(pos_)), t(t_)
@@ -930,7 +930,7 @@
-JSON write value.
Definition: json.h:1289
+JSON write value.
Definition: json.h:1291
Represents compilation error of an template. Throwed specially at mustache compile time.
Definition: mustache.h:52
Compiled mustache template object.
Definition: mustache.h:134
std::string render_string() const
Output a returnable template from this mustache template.
Definition: mustache.h:449
diff --git a/master/reference/navtreeindex1.js b/master/reference/navtreeindex1.js
index 331cd6ce0..fd69e7fc7 100644
--- a/master/reference/navtreeindex1.js
+++ b/master/reference/navtreeindex1.js
@@ -77,7 +77,7 @@ var NAVTREEINDEX1 =
"classcrow_1_1logger.html#a59b838e541514c082a01e9111c5a11f6":[1,0,0,18,1],
"classcrow_1_1logger.html#a854e9da406195e08aa7712c7d4ca27d0":[1,0,0,18,2],
"classcrow_1_1mustache_1_1invalid__template__exception.html":[1,0,0,3,0],
-"classcrow_1_1mustache_1_1invalid__template__exception.html#a2a598ed4d91525b8642ec0c0c4b711a9":[1,0,0,3,0,0],
+"classcrow_1_1mustache_1_1invalid__template__exception.html#a52959ee8c3564cffd8d173453df9eda2":[1,0,0,3,0,0],
"classcrow_1_1mustache_1_1invalid__template__exception.html#a6ec8bc8b03e34a5d2443d2f080e9b739":[1,0,0,3,0,2],
"classcrow_1_1mustache_1_1invalid__template__exception.html#ac7fa382187fc426bca817bc56b1ffed9":[1,0,0,3,0,1],
"classcrow_1_1mustache_1_1template__t.html":[1,0,0,3,3],
diff --git a/master/reference/navtreeindex3.js b/master/reference/navtreeindex3.js
index e70144948..f655bc340 100644
--- a/master/reference/navtreeindex3.js
+++ b/master/reference/navtreeindex3.js
@@ -246,8 +246,8 @@ var NAVTREEINDEX3 =
"structcrow_1_1detail_1_1middleware__call__criteria__dynamic.html":[1,0,0,0,10],
"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html":[1,0,0,0,11],
"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html#a03d8f77d9bec07bf6cddce95adde8fc6":[1,0,0,0,11,1],
-"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html#a975e9db833b37965e9113a44787de713":[1,0,0,0,11,0],
+"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html#aebfc2f7848a728de2a901e33cda556cf":[1,0,0,0,11,0],
"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html":[1,0,0,0,12],
-"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html#a6f5d720273c0de6ae01a138e0bb84cc6":[1,0,0,0,12,0],
+"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html#a9a85b847e8f7fb3452037becd99e3411":[1,0,0,0,12,0],
"structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html#abf5e13ed2e5057951fffb0ffa4c41ad5":[1,0,0,0,12,1]
};
diff --git a/master/reference/navtreeindex4.js b/master/reference/navtreeindex4.js
index f77e1ef61..53b2e44a5 100644
--- a/master/reference/navtreeindex4.js
+++ b/master/reference/navtreeindex4.js
@@ -35,7 +35,7 @@ var NAVTREEINDEX4 =
"structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html":[1,0,0,0,0,8,3],
"structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#a0553c3d38f4902d9c3fa8655812ddbd7":[1,0,0,0,0,8,3,2],
"structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#a40965565a28cc879ec75c831c0b729ae":[1,0,0,0,0,8,3,1],
-"structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#aba29fdf5c44192709c4eef8e84a48485":[1,0,0,0,0,8,3,0],
+"structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#a994caa9765212339486fd6245e08b4ff":[1,0,0,0,0,8,3,0],
"structcrow_1_1detail_1_1routing__handler__call__helper_1_1call.html":[1,0,0,0,0,2],
"structcrow_1_1detail_1_1routing__handler__call__helper_1_1call_3_01_f_00_01_n_int_00_01_n_uint_00f79d82c7e7da7530b290964906e13ef.html":[1,0,0,0,0,4],
"structcrow_1_1detail_1_1routing__handler__call__helper_1_1call_3_01_f_00_01_n_int_00_01_n_uint_00f79d82c7e7da7530b290964906e13ef.html#abaa2c6f8c915c89eccd1c46e6526f359":[1,0,0,0,0,4,0],
@@ -119,7 +119,7 @@ var NAVTREEINDEX4 =
"structcrow_1_1multipart_1_1header__view.html#a5a998c3220179d0de4ba5e3aff6675e9":[1,0,0,2,3,2],
"structcrow_1_1multipart_1_1header__view.html#acf0fda29ac1f295c661db2249431cfcf":[1,0,0,2,3,3],
"structcrow_1_1multipart_1_1message.html":[1,0,0,2,2],
-"structcrow_1_1multipart_1_1message.html#a0007fa0cadffae1a8d16fac169d1527b":[1,0,0,2,2,0],
+"structcrow_1_1multipart_1_1message.html#a04ffb20817903d00334268d31f635621":[1,0,0,2,2,0],
"structcrow_1_1multipart_1_1message.html#a05e9cf3feb60f4534af334b2dd5eadf2":[1,0,0,2,2,9],
"structcrow_1_1multipart_1_1message.html#a32946a0f39a8d024aaf4643116a7561b":[1,0,0,2,2,1],
"structcrow_1_1multipart_1_1message.html#a4c3a0575f52bd6e91e539b6aa168d5fd":[1,0,0,2,2,5],
@@ -137,13 +137,13 @@ var NAVTREEINDEX4 =
"structcrow_1_1multipart_1_1message__view.html#aa3dc911fa839a5a401b351a789335c8a":[1,0,0,2,6,4],
"structcrow_1_1multipart_1_1message__view.html#aa7f2c3f544c69af27e243471c61bfb09":[1,0,0,2,6,6],
"structcrow_1_1multipart_1_1message__view.html#aa81bd5ceffd074caa1fe3c49131a37ce":[1,0,0,2,6,9],
+"structcrow_1_1multipart_1_1message__view.html#ab2985a84afde169fb89fc35e430106db":[1,0,0,2,6,0],
"structcrow_1_1multipart_1_1message__view.html#ab57ffe9ae32bac208feea292a33873cd":[1,0,0,2,6,7],
"structcrow_1_1multipart_1_1message__view.html#ad0a498ccdfea67c512d5cb23f62c4f1c":[1,0,0,2,6,1],
"structcrow_1_1multipart_1_1message__view.html#ad12d2270b477b231c9ff53d40bad9d60":[1,0,0,2,6,2],
-"structcrow_1_1multipart_1_1message__view.html#ae01a2e1676ca9d22d625200df14b88fe":[1,0,0,2,6,0],
"structcrow_1_1multipart_1_1padded.html":[1,0,0,2,4],
-"structcrow_1_1multipart_1_1padded.html#a27b10196d6f596db53102988da72e47e":[1,0,0,2,4,0],
"structcrow_1_1multipart_1_1padded.html#a3198bf9ee11e1c8e9e84a5880898e85b":[1,0,0,2,4,2],
+"structcrow_1_1multipart_1_1padded.html#a65a7ba8beab915313c5d078727151776":[1,0,0,2,4,0],
"structcrow_1_1multipart_1_1padded.html#a6e434697fc61b09cdd15953d5260c746":[1,0,0,2,4,1],
"structcrow_1_1multipart_1_1part.html":[1,0,0,2,1],
"structcrow_1_1multipart_1_1part.html#a06851f0fd2d36b71139e8488fb646b7e":[1,0,0,2,1,2],
@@ -161,7 +161,7 @@ var NAVTREEINDEX4 =
"structcrow_1_1mustache_1_1_action.html":[1,0,0,3,2],
"structcrow_1_1mustache_1_1_action.html#a1af3f38c04cdc0978c2a788eeda81eab":[1,0,0,3,2,2],
"structcrow_1_1mustache_1_1_action.html#a643c89b2d81bfc2d2eedfca0cb119068":[1,0,0,3,2,3],
-"structcrow_1_1mustache_1_1_action.html#abdd01c3d42e0b9943cc07cc511cb972c":[1,0,0,3,2,0],
+"structcrow_1_1mustache_1_1_action.html#ab6d29322c7a78ea25a115ae1db1ae7c1":[1,0,0,3,2,0],
"structcrow_1_1mustache_1_1_action.html#ac0daea6290bb2ca9c9c87c3fb163ce7d":[1,0,0,3,2,1],
"structcrow_1_1mustache_1_1_action.html#aed7c3e6311655c446b56c31210e27ff4":[1,0,0,3,2,4],
"structcrow_1_1mustache_1_1rendered__template.html":[1,0,0,3,1],
@@ -170,7 +170,6 @@ var NAVTREEINDEX4 =
"structcrow_1_1mustache_1_1rendered__template.html#abc95a00b4666fa9d2f563025fe4a2bc0":[1,0,0,3,1,0],
"structcrow_1_1mustache_1_1rendered__template.html#aca7c4ee2611c3926861807cd81436e8e":[1,0,0,3,1,1],
"structcrow_1_1request.html":[1,0,0,13],
-"structcrow_1_1request.html#a111b70ddb2a100a79415b539e152e145":[1,0,0,13,1],
"structcrow_1_1request.html#a33aa146a3914864ce82ef22136451601":[1,0,0,13,7],
"structcrow_1_1request.html#a3752ac015c6ba0047842a4594e4e9ad5":[1,0,0,13,13],
"structcrow_1_1request.html#a4a3e4bcd0cd626ceaee38f4c17d28c8d":[1,0,0,13,9],
@@ -187,6 +186,7 @@ var NAVTREEINDEX4 =
"structcrow_1_1request.html#aa3df34c56847d6d42887e73655276167":[1,0,0,13,21],
"structcrow_1_1request.html#aa51aa45a03c2efe581e9bf9f011e8378":[1,0,0,13,11],
"structcrow_1_1request.html#aa8a04e30e2249f04614f233d25ffaad7":[1,0,0,13,19],
+"structcrow_1_1request.html#ab90c2762f152a7d58a1ab8ea55e0afd0":[1,0,0,13,1],
"structcrow_1_1request.html#ac0603f5ffe5c7b93c0ca3a5bed4ebacc":[1,0,0,13,12],
"structcrow_1_1request.html#ac369309c6be61c011b93a5b8cf14515a":[1,0,0,13,3],
"structcrow_1_1request.html#ac3e72e3fe415c68618dee999e3984160":[1,0,0,13,4],
@@ -197,38 +197,38 @@ var NAVTREEINDEX4 =
"structcrow_1_1response.html#a068269fc8b7f1df3d5421ccd384fe1f3":[1,0,0,14,13],
"structcrow_1_1response.html#a0f4955bc5dc914d698cff5e83bca1cdb":[1,0,0,14,1],
"structcrow_1_1response.html#a10da2e17421586b68f27ef1533ec677b":[1,0,0,14,15],
+"structcrow_1_1response.html#a126da3d75afaa53b195a02c8e4b03806":[1,0,0,14,8],
"structcrow_1_1response.html#a13cd54cff7b7cea484654c3e9ace415d":[1,0,0,14,30],
"structcrow_1_1response.html#a16d1a8bcec6460ba97f90b80881693b8":[1,0,0,14,12],
-"structcrow_1_1response.html#a37aaf5b69473066fe8bcf302e9ba4580":[1,0,0,14,7],
-"structcrow_1_1response.html#a3b9bfae36855265ddc1a64c78d0caf8e":[1,0,0,14,8],
-"structcrow_1_1response.html#a52e2658b1d16dcf106ed138b6396696b":[1,0,0,14,2],
+"structcrow_1_1response.html#a178201cdeeea4bd7d2ddd97d72e0f293":[1,0,0,14,11],
+"structcrow_1_1response.html#a19aa374c89c379d50ccae959c09e8d30":[1,0,0,14,3],
"structcrow_1_1response.html#a548c4f5e059a7bb3b2560b7ac5800011":[1,0,0,14,37],
-"structcrow_1_1response.html#a58dd09e8a9b3f1d86fe9d676757c8a2c":[1,0,0,14,11],
"structcrow_1_1response.html#a693fd3f57d926251918b16a6f20be474":[1,0,0,14,5],
+"structcrow_1_1response.html#a6a1bcececde5a88e43ac5bb4d069d09f":[1,0,0,14,10],
"structcrow_1_1response.html#a70c56fc6910c94f42accb77a45d5686e":[1,0,0,14,6],
"structcrow_1_1response.html#a760bca5f5fdee03518d59d9538ce5432":[1,0,0,14,20],
+"structcrow_1_1response.html#a808aae9110e1e3a5ca7b3fa3a43881c2":[1,0,0,14,4],
"structcrow_1_1response.html#a82bba7eaacfee514c55630a13a85410e":[1,0,0,14,29],
+"structcrow_1_1response.html#a87339aace851e4fcabcd5f61cf58f0fd":[1,0,0,14,7],
"structcrow_1_1response.html#a8c35e92bc75eaa35f45e0ca6d22a8f47":[1,0,0,14,16],
"structcrow_1_1response.html#a8f5e5caa08c3e658bccd03996e1a778a":[1,0,0,14,27],
"structcrow_1_1response.html#a95f300c05782e1934dad522b6d6588cf":[1,0,0,14,36],
"structcrow_1_1response.html#a9e87a17c3cf8b434fd2a64a9b3d4b675":[1,0,0,14,25],
"structcrow_1_1response.html#a9ee58f8b775b2566418b298fe33c0dcc":[1,0,0,14,21],
"structcrow_1_1response.html#a9fb82c40e0c0844db70b7b86b4a23e9f":[1,0,0,14,18],
-"structcrow_1_1response.html#aab7485cb8f0efa3fcf062118476edfd5":[1,0,0,14,3],
+"structcrow_1_1response.html#aa2b9fa69bcdc21f244e0e8f7c0b13bbc":[1,0,0,14,2],
"structcrow_1_1response.html#aabc1f9b3264b8c5a2d05dcb409e8ff3f":[1,0,0,14,33],
"structcrow_1_1response.html#ab2b9a9b9795fa6330bd47b66a716cb0b":[1,0,0,14,26],
"structcrow_1_1response.html#abd924a9b90dfb505804fe4cf791768a3":[1,0,0,14,9],
"structcrow_1_1response.html#abef42200eca49c70dc1f5140ee3603ab":[1,0,0,14,14],
"structcrow_1_1response.html#ac04bbe2d4f54fd717cdffdb26af3e46f":[1,0,0,14,24],
"structcrow_1_1response.html#ac29da52ee1e0b55086cd8eedd6c22da1":[1,0,0,14,17],
-"structcrow_1_1response.html#ac7f3e75d48f2082a93e366d31298eb72":[1,0,0,14,10],
"structcrow_1_1response.html#ad0b5402527b2c0e985d9eaf97e0e4e2f":[1,0,0,14,22],
"structcrow_1_1response.html#ad1fd3424328f664cd049fe429e0e3dc6":[1,0,0,14,31],
"structcrow_1_1response.html#adaaa1a62451d41e6f3831463296b4c08":[1,0,0,14,28],
"structcrow_1_1response.html#ae56cfc39f24a56748c11016842427fb3":[1,0,0,14,35],
"structcrow_1_1response.html#ae789c998922616a1a895476eb89c7844":[1,0,0,14,23],
"structcrow_1_1response.html#ae9f3cc153eac05954f1f4e599527892d":[1,0,0,14,32],
-"structcrow_1_1response.html#aeee8e7dd021783524bae9bd8775bae0f":[1,0,0,14,4],
"structcrow_1_1response.html#af87163fd1c7e18650c7691e07f58c7de":[1,0,0,14,34],
"structcrow_1_1response.html#aff527a091cf5054e933a244b078648c1":[1,0,0,14,19],
"structcrow_1_1response_1_1static__file__info.html":[1,0,0,14,0],
diff --git a/master/reference/navtreeindex5.js b/master/reference/navtreeindex5.js
index 7b85a3208..cbe3acccf 100644
--- a/master/reference/navtreeindex5.js
+++ b/master/reference/navtreeindex5.js
@@ -47,11 +47,11 @@ var NAVTREEINDEX5 =
"utility_8h_source.html":[2,0,0,0,26],
"version_8h_source.html":[2,0,0,0,27],
"websocket_8h_source.html":[2,0,0,0,28],
-"":[0,0,0,2,0],
-"":[0,0,0,2],
-"":[0,0,0,1,0],
+"":[0,0,0,4,0],
"":[0,0,0,1],
-"":[0,0,0,0],
"":[0,0,0,5],
-"":[0,0,0,4,0]
+"":[0,0,0,1,0],
+"":[0,0,0,0],
+"":[0,0,0,2],
+"":[0,0,0,2,0]
};
diff --git a/master/reference/routing_8h_source.html b/master/reference/routing_8h_source.html
index d53dbaf5f..80389d90e 100644
--- a/master/reference/routing_8h_source.html
+++ b/master/reference/routing_8h_source.html
@@ -198,1774 +198,1778 @@
98 virtual void validate() = 0;
-
-
-
-
-
-
-
-
- 108 std::unique_ptr<BaseRule> upgrade()
-
- 110 if (rule_to_upgrade_)
- 111 return std::move(rule_to_upgrade_);
-
-
-
-
-
-
-
-
-
- 121 #ifdef CROW_ENABLE_SSL
-
-
-
-
-
-
-
- 129 uint32_t get_methods()
-
-
-
-
-
- 135 void foreach_method(F f)
-
- 137 for (uint32_t method = 0, method_bit = 1; method < static_cast<uint32_t>(HTTPMethod::InternalMethodCount); method++, method_bit <<= 1)
-
- 139 if (methods_ & method_bit)
-
-
-
-
- 144 std::string custom_templates_base;
+
+
+
+
+
+
+
+
+
+
+ 110 std::unique_ptr<BaseRule> upgrade()
+
+ 112 if (rule_to_upgrade_)
+ 113 return std::move(rule_to_upgrade_);
+
+
+
+
+
+
+
+
+
+ 123 #ifdef CROW_ENABLE_SSL
+
+
+
+
+
+
+
+ 131 uint32_t get_methods()
+
+
+
+
+
+ 137 void foreach_method(F f)
+
+ 139 for (uint32_t method = 0, method_bit = 1; method < static_cast<uint32_t>(HTTPMethod::InternalMethodCount); method++, method_bit <<= 1)
+
+ 141 if (methods_ & method_bit)
+
+
+
- 146 const std::string& rule() {
return rule_; }
+ 146 std::string custom_templates_base;
-
- 149 uint32_t methods_{1 <<
static_cast<int>(HTTPMethod::Get)};
-
-
-
-
-
- 155 std::unique_ptr<BaseRule> rule_to_upgrade_;
+ 148 const std::string& rule() {
return rule_; }
+
+
+ 151 uint32_t methods_{1 <<
static_cast<int>(HTTPMethod::Get)};
+
+
+
+
-
+ 157 std::unique_ptr<BaseRule> rule_to_upgrade_;
-
-
-
-
-
-
-
-
-
- 168 namespace routing_handler_call_helper
-
- 170 template<
typename T,
int Pos>
-
-
-
- 174 static const int pos = Pos;
-
-
- 177 template<
typename H1>
-
-
-
- 181 const routing_params& params;
-
-
-
-
- 186 template<
typename F,
int NInt,
int NU
int,
int NDouble,
int NString,
typename S1,
typename S2>
-
-
-
- 190 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
- 191 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<int64_t, Args1...>, black_magic::S<Args2...>>
-
- 193 void operator()(F cparams)
-
- 195 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<int64_t, NInt>>;
- 196 call<F, NInt + 1, NUint, NDouble, NString, black_magic::S<Args1...>, pushed>()(cparams);
-
-
-
- 200 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
- 201 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>>
-
- 203 void operator()(F cparams)
-
- 205 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<uint64_t, NUint>>;
- 206 call<F, NInt, NUint + 1, NDouble, NString, black_magic::S<Args1...>, pushed>()(cparams);
-
-
-
- 210 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
- 211 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<double, Args1...>, black_magic::S<Args2...>>
-
- 213 void operator()(F cparams)
-
- 215 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<double, NDouble>>;
- 216 call<F, NInt, NUint, NDouble + 1, NString, black_magic::S<Args1...>, pushed>()(cparams);
-
-
-
- 220 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
- 221 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<std::string, Args1...>, black_magic::S<Args2...>>
-
- 223 void operator()(F cparams)
-
- 225 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<std::string, NString>>;
- 226 call<F, NInt, NUint, NDouble, NString + 1, black_magic::S<Args1...>, pushed>()(cparams);
-
-
-
- 230 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1>
- 231 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<>, black_magic::S<Args1...>>
-
- 233 void operator()(F cparams)
-
-
-
-
- 238 cparams.params.template get<typename Args1::type>(Args1::pos)...);
-
-
-
- 242 template<
typename Func,
typename... ArgsWrapped>
-
-
- 245 template<
typename... Args>
- 246 void set_(Func f,
typename std::enable_if<!std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::type,
const request&>::value,
int>::type = 0)
-
-
- 249 #ifdef CROW_CAN_USE_CPP14
-
-
-
-
-
-
-
-
-
-
- 260 template<
typename Req,
typename... Args>
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 277 template<
typename... Args>
- 278 void set_(Func f,
typename std::enable_if<
- 279 std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::type,
const request&>::value &&
- 280 !std::is_same<
typename std::tuple_element<1, std::tuple<Args..., void, void>>::type,
response&>::value,
-
-
-
-
-
-
-
-
-
-
-
- 292 template<
typename... Args>
- 293 void set_(Func f,
typename std::enable_if<
- 294 std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::type,
const request&>::value &&
- 295 std::is_same<
typename std::tuple_element<1, std::tuple<Args..., void, void>>::type,
response&>::value,
-
-
- 298 handler_ = std::move(f);
-
-
- 301 template<
typename... Args>
-
-
-
- 305 using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
-
-
- 308 template<
typename... Args>
-
-
-
- 312 using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
-
-
- 315 template<
typename... Args>
-
-
-
- 319 using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+ 170 namespace routing_handler_call_helper
+
+ 172 template<
typename T,
int Pos>
+
+
+
+ 176 static const int pos = Pos;
+
+
+ 179 template<
typename H1>
+
+
+
+ 183 const routing_params& params;
+
+
+
+
+ 188 template<
typename F,
int NInt,
int NU
int,
int NDouble,
int NString,
typename S1,
typename S2>
+
+
+
+ 192 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
+ 193 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<int64_t, Args1...>, black_magic::S<Args2...>>
+
+ 195 void operator()(F cparams)
+
+ 197 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<int64_t, NInt>>;
+ 198 call<F, NInt + 1, NUint, NDouble, NString, black_magic::S<Args1...>, pushed>()(cparams);
+
+
+
+ 202 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
+ 203 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<uint64_t, Args1...>, black_magic::S<Args2...>>
+
+ 205 void operator()(F cparams)
+
+ 207 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<uint64_t, NUint>>;
+ 208 call<F, NInt, NUint + 1, NDouble, NString, black_magic::S<Args1...>, pushed>()(cparams);
+
+
+
+ 212 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
+ 213 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<double, Args1...>, black_magic::S<Args2...>>
+
+ 215 void operator()(F cparams)
+
+ 217 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<double, NDouble>>;
+ 218 call<F, NInt, NUint, NDouble + 1, NString, black_magic::S<Args1...>, pushed>()(cparams);
+
+
+
+ 222 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1,
typename... Args2>
+ 223 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<std::string, Args1...>, black_magic::S<Args2...>>
+
+ 225 void operator()(F cparams)
+
+ 227 using pushed =
typename black_magic::S<Args2...>::template push_back<call_pair<std::string, NString>>;
+ 228 call<F, NInt, NUint, NDouble, NString + 1, black_magic::S<Args1...>, pushed>()(cparams);
+
+
+
+ 232 template<
typename F,
int NInt,
int NUint,
int NDouble,
int NString,
typename... Args1>
+ 233 struct call<F, NInt, NUint, NDouble, NString, black_magic::S<>, black_magic::S<Args1...>>
+
+ 235 void operator()(F cparams)
+
+
+
+
+ 240 cparams.params.template get<typename Args1::type>(Args1::pos)...);
+
+
+
+ 244 template<
typename Func,
typename... ArgsWrapped>
+
+
+ 247 template<
typename... Args>
+ 248 void set_(Func f,
typename std::enable_if<!std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::type,
const request&>::value,
int>::type = 0)
+
+
+ 251 #ifdef CROW_CAN_USE_CPP14
+
+
+
+
+
+
+
+
+
+
+ 262 template<
typename Req,
typename... Args>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 279 template<
typename... Args>
+ 280 void set_(Func f,
typename std::enable_if<
+ 281 std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::type,
const request&>::value &&
+ 282 !std::is_same<
typename std::tuple_element<1, std::tuple<Args..., void, void>>::type,
response&>::value,
+
+
+
+
+
+
+
+
+
+
+
+ 294 template<
typename... Args>
+ 295 void set_(Func f,
typename std::enable_if<
+ 296 std::is_same<
typename std::tuple_element<0, std::tuple<Args..., void>>::type,
const request&>::value &&
+ 297 std::is_same<
typename std::tuple_element<1, std::tuple<Args..., void, void>>::type,
response&>::value,
+
+
+ 300 handler_ = std::move(f);
+
+
+ 303 template<
typename... Args>
+
+
+
+ 307 using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
+
+
+ 310 template<
typename... Args>
+
+
+
+ 314 using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
+
+
+ 317 template<
typename... Args>
+
+
+
+ 321 using args_type = black_magic::S<typename black_magic::promote_t<Args>...>;
+
- 324 void operator()(
request& req,
response& res,
const routing_params& params)
-
-
-
-
-
-
-
-
- 333 decltype(handler_)>{handler_, params, req, res});
-
-
-
-
-
-
-
-
-
-
-
-
-
- 347 template<
typename Func>
- 348 typename std::enable_if<black_magic::CallHelper<Func, black_magic::S<>>::value,
void>::type
-
-
- 351 static_assert(!std::is_same<
void, decltype(f())>::value,
- 352 "Handler function cannot have void return type; valid return types: string, int, crow::response, crow::returnable");
-
-
- 355 #ifdef CROW_CAN_USE_CPP14
-
-
-
-
-
-
-
-
-
-
- 366 template<
typename Func>
- 367 typename std::enable_if<
- 368 !black_magic::CallHelper<Func, black_magic::S<>>::value &&
- 369 black_magic::CallHelper<Func, black_magic::S<crow::request>>::value,
-
-
-
- 373 static_assert(!std::is_same<
void, decltype(f(std::declval<crow::request>()))>::value,
- 374 "Handler function cannot have void return type; valid return types: string, int, crow::response, crow::returnable");
-
-
- 377 #ifdef CROW_CAN_USE_CPP14
-
-
-
-
-
-
-
-
-
-
- 388 template<
typename Func>
- 389 typename std::enable_if<
- 390 !black_magic::CallHelper<Func, black_magic::S<>>::value &&
- 391 !black_magic::CallHelper<Func, black_magic::S<crow::request>>::value &&
- 392 black_magic::CallHelper<Func, black_magic::S<crow::response&>>::value,
-
-
-
- 396 static_assert(std::is_same<
void, decltype(f(std::declval<crow::response&>()))>::value,
- 397 "Handler function with response argument should have void return type");
-
- 399 #ifdef CROW_CAN_USE_CPP14
-
-
-
-
-
-
-
-
-
- 409 template<
typename Func>
- 410 typename std::enable_if<
- 411 !black_magic::CallHelper<Func, black_magic::S<>>::value &&
- 412 !black_magic::CallHelper<Func, black_magic::S<crow::request>>::value &&
- 413 !black_magic::CallHelper<Func, black_magic::S<crow::response&>>::value,
-
-
-
- 417 static_assert(std::is_same<
void, decltype(f(std::declval<crow::request>(), std::declval<crow::response&>()))>::value,
- 418 "Handler function with response argument should have void return type");
-
- 420 handler_ = std::move(f);
-
-
-
-
- 425 return (handler_ !=
nullptr);
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 440 template<
typename App>
-
-
-
-
-
-
-
-
- 449 max_payload_(UINT64_MAX)
-
-
- 452 void validate()
override
-
-
-
-
-
-
-
-
-
-
-
- 464 new crow::websocket::Connection<SocketAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
-
- 466 #ifdef CROW_ENABLE_SSL
-
-
- 469 new crow::websocket::Connection<SSLAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
-
-
-
-
-
-
-
- 477 max_payload_override_ =
true;
-
-
-
- 481 self_t& subprotocols(
const std::vector<std::string>& subprotocols)
-
- 483 subprotocols_ = subprotocols;
-
-
-
- 487 template<
typename Func>
- 488 self_t& onopen(Func f)
-
-
-
-
-
- 494 template<
typename Func>
- 495 self_t& onmessage(Func f)
-
- 497 message_handler_ = f;
-
-
-
- 501 template<
typename Func>
- 502 self_t& onclose(Func f)
-
-
-
-
-
- 508 template<
typename Func>
- 509 self_t& onerror(Func f)
-
-
-
-
-
- 515 template<
typename Func>
- 516 self_t& onaccept(Func f)
-
-
-
-
-
-
-
-
-
-
-
- 528 std::function<bool(
const crow::request&,
void**)> accept_handler_;
- 529 uint64_t max_payload_;
- 530 bool max_payload_override_ =
false;
- 531 std::vector<std::string> subprotocols_;
-
-
-
-
-
-
-
-
-
-
-
- 543 template<
typename App>
-
-
-
- 547 static_cast<self_t*
>(
this)->rule_to_upgrade_.reset(p);
-
-
-
- 551 self_t& name(std::string name) noexcept
-
- 553 static_cast<self_t*
>(
this)->name_ = std::move(name);
- 554 return static_cast<self_t&
>(*this);
-
-
- 557 self_t& methods(HTTPMethod method)
-
- 559 static_cast<self_t*
>(
this)->methods_ = 1 <<
static_cast<int>(method);
- 560 return static_cast<self_t&
>(*this);
-
-
- 563 template<
typename... MethodArgs>
- 564 self_t& methods(HTTPMethod method, MethodArgs... args_method)
-
- 566 methods(args_method...);
- 567 static_cast<self_t*
>(
this)->methods_ |= 1 <<
static_cast<int>(method);
- 568 return static_cast<self_t&
>(*this);
-
-
-
- 572 template<
typename App,
typename... Middlewares>
-
-
- 575 static_cast<self_t*
>(
this)->mw_indices_.template push<App, Middlewares...>();
- 576 return static_cast<self_t&
>(*this);
-
-
-
-
-
-
-
-
-
-
-
- 588 void validate()
override
-
- 590 if (!erased_handler_)
-
- 592 throw std::runtime_error(name_ + (!name_.empty() ?
": " :
"") +
"no handler for url " + rule_);
-
-
-
- 596 void handle(
request& req,
response& res,
const routing_params& params)
override
-
- 598 if (!custom_templates_base.empty())
-
- 600 else if (mustache::detail::get_template_base_directory_ref() !=
"templates")
-
- 602 erased_handler_(req, res, params);
-
-
- 605 template<
typename Func>
- 606 void operator()(Func f)
-
- 608 #ifdef CROW_MSVC_WORKAROUND
- 609 using function_t = utility::function_traits<decltype(&Func::operator())>;
-
- 611 using function_t = utility::function_traits<Func>;
-
- 613 erased_handler_ = wrap(std::move(f), black_magic::gen_seq<function_t::arity>());
-
-
-
-
-
- 619 #ifdef CROW_MSVC_WORKAROUND
- 620 template<
typename Func,
size_t... Indices>
-
- 622 template<
typename Func,
unsigned... Indices>
-
-
- 625 wrap(Func f, black_magic::seq<Indices...>)
-
- 627 #ifdef CROW_MSVC_WORKAROUND
- 628 using function_t = utility::function_traits<decltype(&Func::operator())>;
-
- 630 using function_t = utility::function_traits<Func>;
-
- 632 if (!black_magic::is_parameter_tag_compatible(
- 633 black_magic::get_parameter_tag_runtime(rule_.c_str()),
- 634 black_magic::compute_parameter_tag_from_args_list<
- 635 typename function_t::template arg<Indices>...>::value))
-
- 637 throw std::runtime_error(
"route_dynamic: Handler type is mismatched with URL parameters: " + rule_);
-
-
-
- 641 typename function_t::template arg<Indices>...>(std::move(f));
-
-
-
- 645 template<
typename Func>
- 646 void operator()(std::string name, Func&& f)
-
- 648 name_ = std::move(name);
- 649 (*this).template operator()<Func>(std::forward(f));
-
-
-
- 653 std::function<void(
request&,
response&,
const routing_params&)> erased_handler_;
-
-
-
- 657 template<
typename... Args>
-
-
-
-
-
-
-
-
-
- 667 void validate()
override
-
- 669 if (rule_.at(0) !=
'/')
- 670 throw std::runtime_error(
"Internal error: Routes must start with a '/'");
-
-
-
- 674 throw std::runtime_error(name_ + (!name_.empty() ?
": " :
"") +
"no handler for url " + rule_);
-
-
-
- 678 template<
typename Func>
- 679 void operator()(Func&& f)
-
-
- 682 #ifdef CROW_CAN_USE_CPP14
-
-
-
-
-
- 688 detail::wrapped_handler_call(req, res, f, std::forward<Args>(args)...);
-
-
-
- 692 template<
typename Func>
- 693 void operator()(std::string name, Func&& f)
-
- 695 name_ = std::move(name);
- 696 (*this).template operator()<Func>(std::forward(f));
-
-
- 699 void handle(
request& req,
response& res,
const routing_params& params)
override
-
- 701 if (!custom_templates_base.empty())
-
- 703 else if (mustache::detail::get_template_base_directory_ref() != mustache::detail::get_global_template_base_directory_ref())
-
-
-
-
-
- 709 black_magic::S<Args...>,
-
-
-
-
-
-
-
-
- 718 const int RULE_SPECIAL_REDIRECT_SLASH = 1;
+
+
+ 326 void operator()(
request& req,
response& res,
const routing_params& params)
+
+
+
+
+
+
+
+
+ 335 decltype(handler_)>{handler_, params, req, res});
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 349 template<
typename Func>
+ 350 typename std::enable_if<black_magic::CallHelper<Func, black_magic::S<>>::value,
void>::type
+
+
+ 353 static_assert(!std::is_same<
void, decltype(f())>::value,
+ 354 "Handler function cannot have void return type; valid return types: string, int, crow::response, crow::returnable");
+
+
+ 357 #ifdef CROW_CAN_USE_CPP14
+
+
+
+
+
+
+
+
+
+
+ 368 template<
typename Func>
+ 369 typename std::enable_if<
+ 370 !black_magic::CallHelper<Func, black_magic::S<>>::value &&
+ 371 black_magic::CallHelper<Func, black_magic::S<crow::request>>::value,
+
+
+
+ 375 static_assert(!std::is_same<
void, decltype(f(std::declval<crow::request>()))>::value,
+ 376 "Handler function cannot have void return type; valid return types: string, int, crow::response, crow::returnable");
+
+
+ 379 #ifdef CROW_CAN_USE_CPP14
+
+
+
+
+
+
+
+
+
+
+ 390 template<
typename Func>
+ 391 typename std::enable_if<
+ 392 !black_magic::CallHelper<Func, black_magic::S<>>::value &&
+ 393 !black_magic::CallHelper<Func, black_magic::S<crow::request>>::value &&
+ 394 black_magic::CallHelper<Func, black_magic::S<crow::response&>>::value,
+
+
+
+ 398 static_assert(std::is_same<
void, decltype(f(std::declval<crow::response&>()))>::value,
+ 399 "Handler function with response argument should have void return type");
+
+ 401 #ifdef CROW_CAN_USE_CPP14
+
+
+
+
+
+
+
+
+
+ 411 template<
typename Func>
+ 412 typename std::enable_if<
+ 413 !black_magic::CallHelper<Func, black_magic::S<>>::value &&
+ 414 !black_magic::CallHelper<Func, black_magic::S<crow::request>>::value &&
+ 415 !black_magic::CallHelper<Func, black_magic::S<crow::response&>>::value,
+
+
+
+ 419 static_assert(std::is_same<
void, decltype(f(std::declval<crow::request>(), std::declval<crow::response&>()))>::value,
+ 420 "Handler function with response argument should have void return type");
+
+ 422 handler_ = std::move(f);
+
+
+
+
+ 427 return (handler_ !=
nullptr);
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 442 template<
typename App>
+
+
+
+
+
+
+
+
+ 451 max_payload_(UINT64_MAX)
+
+
+ 454 void validate()
override
+
+
+
+
+
+
+
+
+
+
+
+ 466 new crow::websocket::Connection<SocketAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
+
+ 468 #ifdef CROW_ENABLE_SSL
+
+
+ 471 new crow::websocket::Connection<SSLAdaptor, App>(req, std::move(adaptor), app_, max_payload_, subprotocols_, open_handler_, message_handler_, close_handler_, error_handler_, accept_handler_);
+
+
+
+
+
+
+
+ 479 max_payload_override_ =
true;
+
+
+
+ 483 self_t& subprotocols(
const std::vector<std::string>& subprotocols)
+
+ 485 subprotocols_ = subprotocols;
+
+
+
+ 489 template<
typename Func>
+ 490 self_t& onopen(Func f)
+
+
+
+
+
+ 496 template<
typename Func>
+ 497 self_t& onmessage(Func f)
+
+ 499 message_handler_ = f;
+
+
+
+ 503 template<
typename Func>
+ 504 self_t& onclose(Func f)
+
+
+
+
+
+ 510 template<
typename Func>
+ 511 self_t& onerror(Func f)
+
+
+
+
+
+ 517 template<
typename Func>
+ 518 self_t& onaccept(Func f)
+
+
+
+
+
+
+
+
+
+
+
+ 530 std::function<bool(
const crow::request&,
void**)> accept_handler_;
+ 531 uint64_t max_payload_;
+ 532 bool max_payload_override_ =
false;
+ 533 std::vector<std::string> subprotocols_;
+
+
+
+
+
+
+
+
+
+
+
+ 545 template<
typename App>
+
+
+
+ 549 static_cast<self_t*
>(
this)->rule_to_upgrade_.reset(p);
+
+
+
+ 553 self_t& name(std::string name) noexcept
+
+ 555 static_cast<self_t*
>(
this)->name_ = std::move(name);
+ 556 return static_cast<self_t&
>(*this);
+
+
+ 559 self_t& methods(HTTPMethod method)
+
+ 561 static_cast<self_t*
>(
this)->methods_ = 1 <<
static_cast<int>(method);
+ 562 return static_cast<self_t&
>(*this);
+
+
+ 565 template<
typename... MethodArgs>
+ 566 self_t& methods(HTTPMethod method, MethodArgs... args_method)
+
+ 568 methods(args_method...);
+ 569 static_cast<self_t*
>(
this)->methods_ |= 1 <<
static_cast<int>(method);
+ 570 return static_cast<self_t&
>(*this);
+
+
+
+ 574 template<
typename App,
typename... Middlewares>
+
+
+ 577 static_cast<self_t*
>(
this)->mw_indices_.template push<App, Middlewares...>();
+ 578 return static_cast<self_t&
>(*this);
+
+
+
+
+
+
+
+
+
+
+
+ 590 void validate()
override
+
+ 592 if (!erased_handler_)
+
+ 594 throw std::runtime_error(name_ + (!name_.empty() ?
": " :
"") +
"no handler for url " + rule_);
+
+
+
+ 598 void handle(
request& req,
response& res,
const routing_params& params)
override
+
+ 600 if (!custom_templates_base.empty())
+
+ 602 else if (mustache::detail::get_template_base_directory_ref() !=
"templates")
+
+ 604 erased_handler_(req, res, params);
+
+
+ 607 template<
typename Func>
+ 608 void operator()(Func f)
+
+ 610 #ifdef CROW_MSVC_WORKAROUND
+ 611 using function_t = utility::function_traits<decltype(&Func::operator())>;
+
+ 613 using function_t = utility::function_traits<Func>;
+
+ 615 erased_handler_ = wrap(std::move(f), black_magic::gen_seq<function_t::arity>());
+
+
+
+
+
+ 621 #ifdef CROW_MSVC_WORKAROUND
+ 622 template<
typename Func,
size_t... Indices>
+
+ 624 template<
typename Func,
unsigned... Indices>
+
+
+ 627 wrap(Func f, black_magic::seq<Indices...>)
+
+ 629 #ifdef CROW_MSVC_WORKAROUND
+ 630 using function_t = utility::function_traits<decltype(&Func::operator())>;
+
+ 632 using function_t = utility::function_traits<Func>;
+
+ 634 if (!black_magic::is_parameter_tag_compatible(
+ 635 black_magic::get_parameter_tag_runtime(rule_.c_str()),
+ 636 black_magic::compute_parameter_tag_from_args_list<
+ 637 typename function_t::template arg<Indices>...>::value))
+
+ 639 throw std::runtime_error(
"route_dynamic: Handler type is mismatched with URL parameters: " + rule_);
+
+
+
+ 643 typename function_t::template arg<Indices>...>(std::move(f));
+
+
+
+ 647 template<
typename Func>
+ 648 void operator()(std::string name, Func&& f)
+
+ 650 name_ = std::move(name);
+ 651 (*this).template operator()<Func>(std::forward(f));
+
+
+
+ 655 std::function<void(
request&,
response&,
const routing_params&)> erased_handler_;
+
+
+
+ 659 template<
typename... Args>
+
+
+
+
+
+
+
+
+
+ 669 void validate()
override
+
+ 671 if (rule_.at(0) !=
'/')
+ 672 throw std::runtime_error(
"Internal error: Routes must start with a '/'");
+
+
+
+ 676 throw std::runtime_error(name_ + (!name_.empty() ?
": " :
"") +
"no handler for url " + rule_);
+
+
+
+ 680 template<
typename Func>
+ 681 void operator()(Func&& f)
+
+
+ 684 #ifdef CROW_CAN_USE_CPP14
+
+
+
+
+
+ 690 detail::wrapped_handler_call(req, res, f, std::forward<Args>(args)...);
+
+
+
+ 694 template<
typename Func>
+ 695 void operator()(std::string name, Func&& f)
+
+ 697 name_ = std::move(name);
+ 698 (*this).template operator()<Func>(std::forward(f));
+
+
+ 701 void handle(
request& req,
response& res,
const routing_params& params)
override
+
+ 703 if (!custom_templates_base.empty())
+
+ 705 else if (mustache::detail::get_template_base_directory_ref() != mustache::detail::get_global_template_base_directory_ref())
+
+
+
+
+
+ 711 black_magic::S<Args...>,
+
+
+
+
+
+
+
-
-
-
-
-
-
-
- 727 uint16_t rule_index{};
-
- 729 uint16_t blueprint_index{INVALID_BP_ID};
-
- 731 ParamType param = ParamType::MAX;
- 732 std::vector<Node> children;
-
- 734 bool IsSimpleNode()
const
-
- 736 return !rule_index &&
- 737 blueprint_index == INVALID_BP_ID &&
- 738 children.size() < 2 &&
- 739 param == ParamType::MAX &&
- 740 std::all_of(std::begin(children), std::end(children), [](
const Node& x) {
- 741 return x.param == ParamType::MAX;
-
-
-
- 745 Node& add_child_node()
-
- 747 children.emplace_back();
- 748 return children.back();
-
-
-
-
-
-
-
-
-
-
- 759 return head_.children.empty();
-
-
-
-
- 764 for (
auto& child : head_.children)
-
-
-
-
-
-
-
- 772 void optimizeNode(Node& node)
-
- 774 if (node.children.empty())
-
- 776 if (node.IsSimpleNode())
-
- 778 auto children_temp = std::move(node.children);
- 779 auto& child_temp = children_temp[0];
- 780 node.key += child_temp.key;
- 781 node.rule_index = child_temp.rule_index;
- 782 node.blueprint_index = child_temp.blueprint_index;
- 783 node.children = std::move(child_temp.children);
-
-
-
-
- 788 for (
auto& child : node.children)
-
-
-
-
-
-
- 795 void debug_node_print(
const Node& node,
int level)
-
- 797 if (node.param != ParamType::MAX)
-
-
-
-
- 802 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
-
-
- 805 case ParamType::UINT:
- 806 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
-
-
- 809 case ParamType::DOUBLE:
- 810 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
-
-
- 813 case ParamType::STRING:
- 814 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
-
-
- 817 case ParamType::PATH:
- 818 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
-
-
-
- 822 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
-
-
-
-
-
- 828 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ " << node.key;
-
- 830 for (
const auto& child : node.children)
-
- 832 debug_node_print(child, level + 1);
-
-
-
-
-
-
- 839 CROW_LOG_DEBUG <<
"└➙ ROOT";
- 840 for (
const auto& child : head_.children)
- 841 debug_node_print(child, 1);
-
-
-
-
- 846 if (!head_.IsSimpleNode())
- 847 throw std::runtime_error(
"Internal error: Trie header should be simple!");
-
-
-
-
- 852 routing_handle_result find(
const std::string& req_url,
const Node& node,
unsigned pos = 0, routing_params* params =
nullptr, std::vector<uint16_t>* blueprints =
nullptr)
const
-
-
- 855 routing_params empty;
- 856 if (params ==
nullptr)
-
-
- 859 std::vector<uint16_t> MT;
- 860 if (blueprints ==
nullptr)
-
-
-
- 864 std::vector<uint16_t> found_BP;
- 865 routing_params match_params;
-
- 867 auto update_found = [&found, &found_BP, &match_params](routing_handle_result& ret) {
- 868 found_BP = std::move(ret.blueprint_indices);
- 869 if (ret.rule_index && (!found || found > ret.rule_index))
-
- 871 found = ret.rule_index;
- 872 match_params = std::move(ret.r_params);
-
-
-
-
- 877 if (pos == req_url.size())
-
- 879 found_BP = std::move(*blueprints);
- 880 return routing_handle_result{node.rule_index, *blueprints, *params};
-
-
- 883 bool found_fragment =
false;
+ 720 const int RULE_SPECIAL_REDIRECT_SLASH = 1;
+
+
+
+
+
+
+
+
+ 729 uint16_t rule_index{};
+
+ 731 uint16_t blueprint_index{INVALID_BP_ID};
+
+ 733 ParamType param = ParamType::MAX;
+ 734 std::vector<Node> children;
+
+ 736 bool IsSimpleNode()
const
+
+ 738 return !rule_index &&
+ 739 blueprint_index == INVALID_BP_ID &&
+ 740 children.size() < 2 &&
+ 741 param == ParamType::MAX &&
+ 742 std::all_of(std::begin(children), std::end(children), [](
const Node& x) {
+ 743 return x.param == ParamType::MAX;
+
+
+
+ 747 Node& add_child_node()
+
+ 749 children.emplace_back();
+ 750 return children.back();
+
+
+
+
+
+
+
+
+
+
+ 761 return head_.children.empty();
+
+
+
+
+ 766 for (
auto& child : head_.children)
+
+
+
+
+
+
+
+ 774 void optimizeNode(Node& node)
+
+ 776 if (node.children.empty())
+
+ 778 if (node.IsSimpleNode())
+
+ 780 auto children_temp = std::move(node.children);
+ 781 auto& child_temp = children_temp[0];
+ 782 node.key += child_temp.key;
+ 783 node.rule_index = child_temp.rule_index;
+ 784 node.blueprint_index = child_temp.blueprint_index;
+ 785 node.children = std::move(child_temp.children);
+
+
+
+
+ 790 for (
auto& child : node.children)
+
+
+
+
+
+
+ 797 void debug_node_print(
const Node& node,
int level)
+
+ 799 if (node.param != ParamType::MAX)
+
+
+
+
+ 804 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
+
+
+ 807 case ParamType::UINT:
+ 808 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
+
+
+ 811 case ParamType::DOUBLE:
+ 812 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
+
+
+ 815 case ParamType::STRING:
+ 816 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
+
+
+ 819 case ParamType::PATH:
+ 820 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
+
+
+
+ 824 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ "
+
+
+
+
+
+ 830 CROW_LOG_DEBUG << std::string(3 * level,
' ') <<
"└➝ " << node.key;
+
+ 832 for (
const auto& child : node.children)
+
+ 834 debug_node_print(child, level + 1);
+
+
+
+
+
+
+ 841 CROW_LOG_DEBUG <<
"└➙ ROOT";
+ 842 for (
const auto& child : head_.children)
+ 843 debug_node_print(child, 1);
+
+
+
+
+ 848 if (!head_.IsSimpleNode())
+ 849 throw std::runtime_error(
"Internal error: Trie header should be simple!");
+
+
+
+
+ 854 routing_handle_result find(
const std::string& req_url,
const Node& node,
unsigned pos = 0, routing_params* params =
nullptr, std::vector<uint16_t>* blueprints =
nullptr)
const
+
+
+ 857 routing_params empty;
+ 858 if (params ==
nullptr)
+
+
+ 861 std::vector<uint16_t> MT;
+ 862 if (blueprints ==
nullptr)
+
+
+
+ 866 std::vector<uint16_t> found_BP;
+ 867 routing_params match_params;
+
+ 869 auto update_found = [&found, &found_BP, &match_params](routing_handle_result& ret) {
+ 870 found_BP = std::move(ret.blueprint_indices);
+ 871 if (ret.rule_index && (!found || found > ret.rule_index))
+
+ 873 found = ret.rule_index;
+ 874 match_params = std::move(ret.r_params);
+
+
+
+
+ 879 if (pos == req_url.size())
+
+ 881 found_BP = std::move(*blueprints);
+ 882 return routing_handle_result{node.rule_index, *blueprints, *params};
+
- 885 for (
const auto& child : node.children)
-
- 887 if (child.param != ParamType::MAX)
-
- 889 if (child.param == ParamType::INT)
-
- 891 char c = req_url[pos];
- 892 if ((c >=
'0' && c <=
'9') || c ==
'+' || c ==
'-')
-
-
-
- 896 long long int value = strtoll(req_url.data() + pos, &eptr, 10);
- 897 if (errno != ERANGE && eptr != req_url.data() + pos)
-
- 899 found_fragment =
true;
- 900 params->int_params.push_back(value);
- 901 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
- 902 auto ret = find(req_url, child, eptr - req_url.data(), params, blueprints);
-
- 904 params->int_params.pop_back();
- 905 if (!blueprints->empty()) blueprints->pop_back();
-
-
-
-
- 910 else if (child.param == ParamType::UINT)
-
- 912 char c = req_url[pos];
- 913 if ((c >=
'0' && c <=
'9') || c ==
'+')
-
-
-
- 917 unsigned long long int value = strtoull(req_url.data() + pos, &eptr, 10);
- 918 if (errno != ERANGE && eptr != req_url.data() + pos)
-
- 920 found_fragment =
true;
- 921 params->uint_params.push_back(value);
- 922 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
- 923 auto ret = find(req_url, child, eptr - req_url.data(), params, blueprints);
-
- 925 params->uint_params.pop_back();
- 926 if (!blueprints->empty()) blueprints->pop_back();
-
-
-
-
- 931 else if (child.param == ParamType::DOUBLE)
-
- 933 char c = req_url[pos];
- 934 if ((c >=
'0' && c <=
'9') || c ==
'+' || c ==
'-' || c ==
'.')
-
-
-
- 938 double value = strtod(req_url.data() + pos, &eptr);
- 939 if (errno != ERANGE && eptr != req_url.data() + pos)
-
- 941 found_fragment =
true;
- 942 params->double_params.push_back(value);
- 943 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
- 944 auto ret = find(req_url, child, eptr - req_url.data(), params, blueprints);
-
- 946 params->double_params.pop_back();
- 947 if (!blueprints->empty()) blueprints->pop_back();
-
-
-
-
- 952 else if (child.param == ParamType::STRING)
-
-
- 955 for (; epos < req_url.size(); epos++)
-
- 957 if (req_url[epos] ==
'/')
-
-
-
-
-
- 963 found_fragment =
true;
- 964 params->string_params.push_back(req_url.substr(pos, epos - pos));
- 965 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
- 966 auto ret = find(req_url, child, epos, params, blueprints);
-
- 968 params->string_params.pop_back();
- 969 if (!blueprints->empty()) blueprints->pop_back();
-
-
-
- 973 else if (child.param == ParamType::PATH)
-
- 975 size_t epos = req_url.size();
-
-
-
- 979 found_fragment =
true;
- 980 params->string_params.push_back(req_url.substr(pos, epos - pos));
- 981 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
- 982 auto ret = find(req_url, child, epos, params, blueprints);
-
- 984 params->string_params.pop_back();
- 985 if (!blueprints->empty()) blueprints->pop_back();
-
-
-
-
-
-
- 992 const std::string& fragment = child.key;
- 993 if (req_url.compare(pos, fragment.size(), fragment) == 0)
-
- 995 found_fragment =
true;
- 996 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
- 997 auto ret = find(req_url, child, pos + fragment.size(), params, blueprints);
-
- 999 if (!blueprints->empty()) blueprints->pop_back();
-
-
-
-
- 1004 if (!found_fragment)
- 1005 found_BP = std::move(*blueprints);
-
- 1007 return routing_handle_result{found, found_BP, match_params};
-
-
- 1010 routing_handle_result find(
const std::string& req_url)
const
-
- 1012 return find(req_url, head_);
-
-
-
- 1016 void add(
const std::string& url, uint16_t rule_index,
unsigned bp_prefix_length = 0, uint16_t blueprint_index = INVALID_BP_ID)
-
-
-
- 1020 bool has_blueprint = bp_prefix_length != 0 && blueprint_index != INVALID_BP_ID;
+ 885 bool found_fragment =
false;
+
+ 887 for (
const auto& child : node.children)
+
+ 889 if (child.param != ParamType::MAX)
+
+ 891 if (child.param == ParamType::INT)
+
+ 893 char c = req_url[pos];
+ 894 if ((c >=
'0' && c <=
'9') || c ==
'+' || c ==
'-')
+
+
+
+ 898 long long int value = strtoll(req_url.data() + pos, &eptr, 10);
+ 899 if (errno != ERANGE && eptr != req_url.data() + pos)
+
+ 901 found_fragment =
true;
+ 902 params->int_params.push_back(value);
+ 903 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
+ 904 auto ret = find(req_url, child, eptr - req_url.data(), params, blueprints);
+
+ 906 params->int_params.pop_back();
+ 907 if (!blueprints->empty()) blueprints->pop_back();
+
+
+
+
+ 912 else if (child.param == ParamType::UINT)
+
+ 914 char c = req_url[pos];
+ 915 if ((c >=
'0' && c <=
'9') || c ==
'+')
+
+
+
+ 919 unsigned long long int value = strtoull(req_url.data() + pos, &eptr, 10);
+ 920 if (errno != ERANGE && eptr != req_url.data() + pos)
+
+ 922 found_fragment =
true;
+ 923 params->uint_params.push_back(value);
+ 924 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
+ 925 auto ret = find(req_url, child, eptr - req_url.data(), params, blueprints);
+
+ 927 params->uint_params.pop_back();
+ 928 if (!blueprints->empty()) blueprints->pop_back();
+
+
+
+
+ 933 else if (child.param == ParamType::DOUBLE)
+
+ 935 char c = req_url[pos];
+ 936 if ((c >=
'0' && c <=
'9') || c ==
'+' || c ==
'-' || c ==
'.')
+
+
+
+ 940 double value = strtod(req_url.data() + pos, &eptr);
+ 941 if (errno != ERANGE && eptr != req_url.data() + pos)
+
+ 943 found_fragment =
true;
+ 944 params->double_params.push_back(value);
+ 945 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
+ 946 auto ret = find(req_url, child, eptr - req_url.data(), params, blueprints);
+
+ 948 params->double_params.pop_back();
+ 949 if (!blueprints->empty()) blueprints->pop_back();
+
+
+
+
+ 954 else if (child.param == ParamType::STRING)
+
+
+ 957 for (; epos < req_url.size(); epos++)
+
+ 959 if (req_url[epos] ==
'/')
+
+
+
+
+
+ 965 found_fragment =
true;
+ 966 params->string_params.push_back(req_url.substr(pos, epos - pos));
+ 967 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
+ 968 auto ret = find(req_url, child, epos, params, blueprints);
+
+ 970 params->string_params.pop_back();
+ 971 if (!blueprints->empty()) blueprints->pop_back();
+
+
+
+ 975 else if (child.param == ParamType::PATH)
+
+ 977 size_t epos = req_url.size();
+
+
+
+ 981 found_fragment =
true;
+ 982 params->string_params.push_back(req_url.substr(pos, epos - pos));
+ 983 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
+ 984 auto ret = find(req_url, child, epos, params, blueprints);
+
+ 986 params->string_params.pop_back();
+ 987 if (!blueprints->empty()) blueprints->pop_back();
+
+
+
+
+
+
+ 994 const std::string& fragment = child.key;
+ 995 if (req_url.compare(pos, fragment.size(), fragment) == 0)
+
+ 997 found_fragment =
true;
+ 998 if (child.blueprint_index != INVALID_BP_ID) blueprints->push_back(child.blueprint_index);
+ 999 auto ret = find(req_url, child, pos + fragment.size(), params, blueprints);
+
+ 1001 if (!blueprints->empty()) blueprints->pop_back();
+
+
+
+
+ 1006 if (!found_fragment)
+ 1007 found_BP = std::move(*blueprints);
+
+ 1009 return routing_handle_result{found, found_BP, match_params};
+
+
+ 1012 routing_handle_result find(
const std::string& req_url)
const
+
+ 1014 return find(req_url, head_);
+
+
+
+ 1018 void add(
const std::string& url, uint16_t rule_index,
unsigned bp_prefix_length = 0, uint16_t blueprint_index = INVALID_BP_ID)
+
+
- 1022 for (
unsigned i = 0; i < url.size(); i++)
-
-
-
-
- 1027 static struct ParamTraits
-
-
-
-
-
- 1033 {ParamType::INT,
"<int>"},
- 1034 {ParamType::UINT,
"<uint>"},
- 1035 {ParamType::DOUBLE,
"<float>"},
- 1036 {ParamType::DOUBLE,
"<double>"},
- 1037 {ParamType::STRING,
"<str>"},
- 1038 {ParamType::STRING,
"<string>"},
- 1039 {ParamType::PATH,
"<path>"},
-
-
- 1042 for (
const auto& x : paramTraits)
-
- 1044 if (url.compare(i, x.name.size(), x.name) == 0)
-
-
- 1047 for (
auto& child : idx->children)
-
- 1049 if (child.param == x.type)
-
-
-
-
-
-
-
-
-
-
- 1060 auto new_node_idx = &idx->add_child_node();
- 1061 new_node_idx->param = x.type;
-
-
-
-
-
-
-
-
-
-
-
- 1073 bool piece_found =
false;
- 1074 for (
auto& child : idx->children)
-
- 1076 if (child.key[0] == c)
-
-
-
-
-
-
-
-
- 1085 auto new_node_idx = &idx->add_child_node();
- 1086 new_node_idx->key = c;
-
- 1088 if (has_blueprint && i == bp_prefix_length)
- 1089 new_node_idx->blueprint_index = blueprint_index;
-
-
-
-
-
-
- 1096 if (idx->rule_index)
- 1097 throw std::runtime_error(
"handler already exists for " + url);
- 1098 idx->rule_index = rule_index;
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1115 static_dir_(prefix),
- 1116 templates_dir_(prefix)
-
-
- 1119 Blueprint(
const std::string& prefix,
const std::string& static_dir):
- 1120 prefix_(prefix), static_dir_(static_dir){};
-
- 1122 Blueprint(
const std::string& prefix,
const std::string& static_dir,
const std::string& templates_dir):
- 1123 prefix_(prefix), static_dir_(static_dir), templates_dir_(templates_dir){};
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1140 *
this = std::move(value);
-
-
-
-
-
-
- 1147 prefix_ = std::move(value.prefix_);
- 1148 static_dir_ = std::move(value.static_dir_);
- 1149 templates_dir_ = std::move(value.templates_dir_);
- 1150 all_rules_ = std::move(value.all_rules_);
- 1151 catchall_rule_ = std::move(value.catchall_rule_);
- 1152 blueprints_ = std::move(value.blueprints_);
- 1153 mw_indices_ = std::move(value.mw_indices_);
-
-
-
-
-
- 1159 return value.prefix() == prefix_;
-
-
-
-
- 1164 return value.prefix() != prefix_;
-
-
- 1167 std::string prefix()
const
-
-
-
-
- 1172 std::string static_dir()
const
-
-
-
-
-
-
-
-
-
-
-
-
- 1185 DynamicRule& new_rule_dynamic(
const std::string& rule)
-
- 1187 std::string new_rule =
'/' + prefix_ + rule;
- 1188 auto ruleObject =
new DynamicRule(std::move(new_rule));
- 1189 ruleObject->custom_templates_base = templates_dir_;
- 1190 all_rules_.emplace_back(ruleObject);
-
-
-
+ 1022 bool has_blueprint = bp_prefix_length != 0 && blueprint_index != INVALID_BP_ID;
+
+ 1024 for (
unsigned i = 0; i < url.size(); i++)
+
+
+
+
+ 1029 static struct ParamTraits
+
+
+
+
+
+ 1035 {ParamType::INT,
"<int>"},
+ 1036 {ParamType::UINT,
"<uint>"},
+ 1037 {ParamType::DOUBLE,
"<float>"},
+ 1038 {ParamType::DOUBLE,
"<double>"},
+ 1039 {ParamType::STRING,
"<str>"},
+ 1040 {ParamType::STRING,
"<string>"},
+ 1041 {ParamType::PATH,
"<path>"},
+
+
+ 1044 for (
const auto& x : paramTraits)
+
+ 1046 if (url.compare(i, x.name.size(), x.name) == 0)
+
+
+ 1049 for (
auto& child : idx->children)
+
+ 1051 if (child.param == x.type)
+
+
+
+
+
+
+
+
+
+
+ 1062 auto new_node_idx = &idx->add_child_node();
+ 1063 new_node_idx->param = x.type;
+
+
+
+
+
+
+
+
+
+
+
+ 1075 bool piece_found =
false;
+ 1076 for (
auto& child : idx->children)
+
+ 1078 if (child.key[0] == c)
+
+
+
+
+
+
+
+
+ 1087 auto new_node_idx = &idx->add_child_node();
+ 1088 new_node_idx->key = c;
+
+ 1090 if (has_blueprint && i == bp_prefix_length)
+ 1091 new_node_idx->blueprint_index = blueprint_index;
+
+
+
+
+
+
+ 1098 if (idx->rule_index)
+ 1099 throw std::runtime_error(
"handler already exists for " + url);
+ 1100 idx->rule_index = rule_index;
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1117 static_dir_(prefix),
+ 1118 templates_dir_(prefix){};
+
+ 1120 Blueprint(
const std::string& prefix,
const std::string& static_dir):
+ 1121 prefix_(prefix), static_dir_(static_dir){};
+
+ 1123 Blueprint(
const std::string& prefix,
const std::string& static_dir,
const std::string& templates_dir):
+ 1124 prefix_(prefix), static_dir_(static_dir), templates_dir_(templates_dir){};
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1141 *
this = std::move(value);
+
+
+
+
+
+
+ 1148 prefix_ = std::move(value.prefix_);
+ 1149 static_dir_ = std::move(value.static_dir_);
+ 1150 templates_dir_ = std::move(value.templates_dir_);
+ 1151 all_rules_ = std::move(value.all_rules_);
+ 1152 catchall_rule_ = std::move(value.catchall_rule_);
+ 1153 blueprints_ = std::move(value.blueprints_);
+ 1154 mw_indices_ = std::move(value.mw_indices_);
+
+
+
+
+
+ 1160 return value.prefix() == prefix_;
+
+
+
+
+ 1165 return value.prefix() != prefix_;
+
+
+ 1168 std::string prefix()
const
+
+
+
+
+ 1173 std::string static_dir()
const
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1188 DynamicRule& new_rule_dynamic(
const std::string& rule)
+
+ 1190 std::string new_rule =
'/' + prefix_ + rule;
+ 1191 auto ruleObject =
new DynamicRule(std::move(new_rule));
+ 1192 ruleObject->custom_templates_base = templates_dir_;
+ 1193 all_rules_.emplace_back(ruleObject);
- 1195 template<u
int64_t N>
- 1196 typename black_magic::arguments<N>::type::template rebind<TaggedRule>& new_rule_tagged(
const std::string& rule)
-
- 1198 std::string new_rule =
'/' + prefix_ + rule;
- 1199 using RuleT =
typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
-
- 1201 auto ruleObject =
new RuleT(std::move(new_rule));
- 1202 ruleObject->custom_templates_base = templates_dir_;
- 1203 all_rules_.emplace_back(ruleObject);
-
-
-
+
+
+
+ 1198 template<u
int64_t N>
+ 1199 typename black_magic::arguments<N>::type::template rebind<TaggedRule>& new_rule_tagged(
const std::string& rule)
+
+ 1201 std::string new_rule =
'/' + prefix_ + rule;
+ 1202 using RuleT =
typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
+
+ 1204 auto ruleObject =
new RuleT(std::move(new_rule));
+ 1205 ruleObject->custom_templates_base = templates_dir_;
+ 1206 all_rules_.emplace_back(ruleObject);
- 1208 void register_blueprint(
Blueprint& blueprint)
-
- 1210 if (blueprints_.empty() || std::find(blueprints_.begin(), blueprints_.end(), &blueprint) == blueprints_.end())
-
- 1212 apply_blueprint(blueprint);
- 1213 blueprints_.emplace_back(&blueprint);
-
-
- 1216 throw std::runtime_error(
"blueprint \"" + blueprint.prefix_ +
"\" already exists in blueprint \"" + prefix_ +
'\"');
-
-
-
-
-
- 1222 return catchall_rule_;
-
-
- 1225 template<
typename App,
typename... Middlewares>
-
-
- 1228 mw_indices_.push<
App, Middlewares...>();
-
-
-
- 1232 void apply_blueprint(
Blueprint& blueprint)
-
-
- 1235 blueprint.prefix_ = prefix_ +
'/' + blueprint.prefix_;
- 1236 blueprint.static_dir_ = static_dir_ +
'/' + blueprint.static_dir_;
- 1237 blueprint.templates_dir_ = templates_dir_ +
'/' + blueprint.templates_dir_;
- 1238 for (
auto& rule : blueprint.all_rules_)
-
- 1240 std::string new_rule =
'/' + prefix_ + rule->rule_;
- 1241 rule->rule_ = new_rule;
-
- 1243 for (
Blueprint* bp_child : blueprint.blueprints_)
-
-
- 1246 apply_blueprint(bp_ref);
-
-
-
- 1250 std::string prefix_;
- 1251 std::string static_dir_;
- 1252 std::string templates_dir_;
- 1253 std::vector<std::unique_ptr<BaseRule>> all_rules_;
-
- 1255 std::vector<Blueprint*> blueprints_;
-
-
-
-
-
-
-
-
-
-
-
-
-
- 1269 DynamicRule& new_rule_dynamic(
const std::string& rule)
-
-
- 1272 all_rules_.emplace_back(ruleObject);
-
-
-
+
+
+
+ 1211 void register_blueprint(
Blueprint& blueprint)
+
+ 1213 if (blueprints_.empty() || std::find(blueprints_.begin(), blueprints_.end(), &blueprint) == blueprints_.end())
+
+ 1215 apply_blueprint(blueprint);
+ 1216 blueprints_.emplace_back(&blueprint);
+
+
+ 1219 throw std::runtime_error(
"blueprint \"" + blueprint.prefix_ +
"\" already exists in blueprint \"" + prefix_ +
'\"');
+
+
+
+
+
+ 1225 return catchall_rule_;
+
+
+ 1228 template<
typename App,
typename... Middlewares>
+
+
+ 1231 mw_indices_.push<
App, Middlewares...>();
+
+
+
+ 1235 void apply_blueprint(
Blueprint& blueprint)
+
+
+ 1238 blueprint.prefix_ = prefix_ +
'/' + blueprint.prefix_;
+ 1239 blueprint.static_dir_ = static_dir_ +
'/' + blueprint.static_dir_;
+ 1240 blueprint.templates_dir_ = templates_dir_ +
'/' + blueprint.templates_dir_;
+ 1241 for (
auto& rule : blueprint.all_rules_)
+
+ 1243 std::string new_rule =
'/' + prefix_ + rule->rule_;
+ 1244 rule->rule_ = new_rule;
+
+ 1246 for (
Blueprint* bp_child : blueprint.blueprints_)
+
+
+ 1249 apply_blueprint(bp_ref);
+
+
+
+ 1253 std::string prefix_;
+ 1254 std::string static_dir_;
+ 1255 std::string templates_dir_;
+ 1256 std::vector<std::unique_ptr<BaseRule>> all_rules_;
+
+ 1258 std::vector<Blueprint*> blueprints_;
+
+
+
+
+
+
+
+
+
+
+
+
+
+ 1272 DynamicRule& new_rule_dynamic(
const std::string& rule)
+
+
+ 1275 all_rules_.emplace_back(ruleObject);
- 1277 template<u
int64_t N>
- 1278 typename black_magic::arguments<N>::type::template rebind<TaggedRule>& new_rule_tagged(
const std::string& rule)
-
- 1280 using RuleT =
typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
-
- 1282 auto ruleObject =
new RuleT(rule);
- 1283 all_rules_.emplace_back(ruleObject);
+
+
+
+ 1280 template<u
int64_t N>
+ 1281 typename black_magic::arguments<N>::type::template rebind<TaggedRule>& new_rule_tagged(
const std::string& rule)
+
+ 1283 using RuleT =
typename black_magic::arguments<N>::type::template rebind<TaggedRule>;
-
-
+ 1285 auto ruleObject =
new RuleT(rule);
+ 1286 all_rules_.emplace_back(ruleObject);
-
-
- 1290 return catchall_rule_;
-
-
- 1293 void internal_add_rule_object(
const std::string& rule,
BaseRule* ruleObject)
-
- 1295 internal_add_rule_object(rule, ruleObject, INVALID_BP_ID, blueprints_);
-
-
- 1298 void internal_add_rule_object(
const std::string& rule,
BaseRule* ruleObject,
const uint16_t& BP_index, std::vector<Blueprint*>& blueprints)
-
- 1300 bool has_trailing_slash =
false;
- 1301 std::string rule_without_trailing_slash;
- 1302 if (rule.size() > 1 && rule.back() ==
'/')
-
- 1304 has_trailing_slash =
true;
- 1305 rule_without_trailing_slash = rule;
- 1306 rule_without_trailing_slash.pop_back();
-
-
- 1309 ruleObject->mw_indices_.pack();
-
- 1311 ruleObject->foreach_method([&](
int method) {
- 1312 per_methods_[method].rules.emplace_back(ruleObject);
- 1313 per_methods_[method].trie.add(rule, per_methods_[method].rules.size() - 1, BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length() : 0, BP_index);
-
-
-
- 1317 if (has_trailing_slash)
-
- 1319 per_methods_[method].trie.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH, BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length() : 0, BP_index);
-
-
-
- 1323 ruleObject->set_added();
-
+
+
+
+
+
+ 1293 return catchall_rule_;
+
+
+ 1296 void internal_add_rule_object(
const std::string& rule,
BaseRule* ruleObject)
+
+ 1298 internal_add_rule_object(rule, ruleObject, INVALID_BP_ID, blueprints_);
+
+
+ 1301 void internal_add_rule_object(
const std::string& rule,
BaseRule* ruleObject,
const uint16_t& BP_index, std::vector<Blueprint*>& blueprints)
+
+ 1303 bool has_trailing_slash =
false;
+ 1304 std::string rule_without_trailing_slash;
+ 1305 if (rule.size() > 1 && rule.back() ==
'/')
+
+ 1307 has_trailing_slash =
true;
+ 1308 rule_without_trailing_slash = rule;
+ 1309 rule_without_trailing_slash.pop_back();
+
+
+ 1312 ruleObject->mw_indices_.pack();
+
+ 1314 ruleObject->foreach_method([&](
int method) {
+ 1315 per_methods_[method].rules.emplace_back(ruleObject);
+ 1316 per_methods_[method].trie.add(rule, per_methods_[method].rules.size() - 1, BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length() : 0, BP_index);
+
+
+
+ 1320 if (has_trailing_slash)
+
+ 1322 per_methods_[method].trie.add(rule_without_trailing_slash, RULE_SPECIAL_REDIRECT_SLASH, BP_index != INVALID_BP_ID ? blueprints[BP_index]->prefix().length() : 0, BP_index);
+
+
- 1326 void register_blueprint(
Blueprint& blueprint)
-
- 1328 if (std::find(blueprints_.begin(), blueprints_.end(), &blueprint) == blueprints_.end())
-
- 1330 blueprints_.emplace_back(&blueprint);
-
-
- 1333 throw std::runtime_error(
"blueprint \"" + blueprint.prefix_ +
"\" already exists in router");
-
-
- 1336 void get_recursive_child_methods(
Blueprint* blueprint, std::vector<HTTPMethod>& methods)
-
-
- 1339 if (blueprint->static_dir_.empty() && blueprint->all_rules_.empty())
-
- 1341 for (
Blueprint* bp : blueprint->blueprints_)
-
- 1343 get_recursive_child_methods(bp, methods);
-
-
- 1346 else if (!blueprint->static_dir_.empty())
- 1347 methods.emplace_back(HTTPMethod::Get);
- 1348 for (
auto& rule : blueprint->all_rules_)
-
- 1350 rule->foreach_method([&methods](
unsigned method) {
- 1351 HTTPMethod method_final =
static_cast<HTTPMethod
>(method);
- 1352 if (std::find(methods.begin(), methods.end(), method_final) == methods.end())
- 1353 methods.emplace_back(method_final);
-
-
-
-
- 1358 void validate_bp() {
-
-
- 1361 validate_bp(blueprints_, blueprint_mw);
-
-
-
-
- 1366 for (
unsigned i = 0; i < blueprints.size(); i++)
-
-
-
- 1370 if (blueprint->is_added())
continue;
-
- 1372 if (blueprint->static_dir_ ==
"" && blueprint->all_rules_.empty())
-
- 1374 std::vector<HTTPMethod> methods;
- 1375 get_recursive_child_methods(blueprint, methods);
- 1376 for (HTTPMethod x : methods)
-
- 1378 int i =
static_cast<int>(x);
- 1379 per_methods_[i].trie.add(blueprint->prefix(), 0, blueprint->prefix().length(), i);
-
-
-
- 1383 current_mw.merge_back(blueprint->mw_indices_);
- 1384 for (
auto& rule : blueprint->all_rules_)
-
- 1386 if (rule && !rule->is_added())
-
- 1388 auto upgraded = rule->upgrade();
-
- 1390 rule = std::move(upgraded);
-
- 1392 rule->mw_indices_.merge_front(current_mw);
- 1393 internal_add_rule_object(rule->rule(), rule.get(), i, blueprints);
-
-
- 1396 validate_bp(blueprint->blueprints_, current_mw);
- 1397 current_mw.pop_back(blueprint->mw_indices_);
- 1398 blueprint->set_added();
-
-
-
-
-
- 1404 for (
auto& rule : all_rules_)
-
- 1406 if (rule && !rule->is_added())
-
- 1408 auto upgraded = rule->upgrade();
-
- 1410 rule = std::move(upgraded);
-
- 1412 internal_add_rule_object(rule->rule(), rule.get());
-
-
- 1415 for (
auto& per_method : per_methods_)
-
- 1417 per_method.trie.validate();
+ 1326 ruleObject->set_added();
+
+
+ 1329 void register_blueprint(
Blueprint& blueprint)
+
+ 1331 if (std::find(blueprints_.begin(), blueprints_.end(), &blueprint) == blueprints_.end())
+
+ 1333 blueprints_.emplace_back(&blueprint);
+
+
+ 1336 throw std::runtime_error(
"blueprint \"" + blueprint.prefix_ +
"\" already exists in router");
+
+
+ 1339 void get_recursive_child_methods(
Blueprint* blueprint, std::vector<HTTPMethod>& methods)
+
+
+ 1342 if (blueprint->static_dir_.empty() && blueprint->all_rules_.empty())
+
+ 1344 for (
Blueprint* bp : blueprint->blueprints_)
+
+ 1346 get_recursive_child_methods(bp, methods);
+
+
+ 1349 else if (!blueprint->static_dir_.empty())
+ 1350 methods.emplace_back(HTTPMethod::Get);
+ 1351 for (
auto& rule : blueprint->all_rules_)
+
+ 1353 rule->foreach_method([&methods](
unsigned method) {
+ 1354 HTTPMethod method_final =
static_cast<HTTPMethod
>(method);
+ 1355 if (std::find(methods.begin(), methods.end(), method_final) == methods.end())
+ 1356 methods.emplace_back(method_final);
+
+
+
+
+
+
+
+
+ 1365 validate_bp(blueprints_, blueprint_mw);
+
+
+
+
+ 1370 for (
unsigned i = 0; i < blueprints.size(); i++)
+
+
+
+ 1374 if (blueprint->is_added())
continue;
+
+ 1376 if (blueprint->static_dir_ ==
"" && blueprint->all_rules_.empty())
+
+ 1378 std::vector<HTTPMethod> methods;
+ 1379 get_recursive_child_methods(blueprint, methods);
+ 1380 for (HTTPMethod x : methods)
+
+ 1382 int method_index =
static_cast<int>(x);
+ 1383 per_methods_[method_index].trie.add(blueprint->prefix(), 0, blueprint->prefix().length(), method_index);
+
+
+
+ 1387 current_mw.merge_back(blueprint->mw_indices_);
+ 1388 for (
auto& rule : blueprint->all_rules_)
+
+ 1390 if (rule && !rule->is_added())
+
+ 1392 auto upgraded = rule->upgrade();
+
+ 1394 rule = std::move(upgraded);
+
+ 1396 rule->mw_indices_.merge_front(current_mw);
+ 1397 internal_add_rule_object(rule->rule(), rule.get(), i, blueprints);
+
+
+ 1400 validate_bp(blueprint->blueprints_, current_mw);
+ 1401 current_mw.pop_back(blueprint->mw_indices_);
+ 1402 blueprint->set_added();
+
+
+
+
+
+ 1408 for (
auto& rule : all_rules_)
+
+ 1410 if (rule && !rule->is_added())
+
+ 1412 auto upgraded = rule->upgrade();
+
+ 1414 rule = std::move(upgraded);
+
+ 1416 internal_add_rule_object(rule->rule(), rule.get());
+
-
-
-
- 1422 template<
typename Adaptor>
- 1423 void handle_upgrade(
const request& req,
response& res, Adaptor&& adaptor)
-
- 1425 if (req.method >= HTTPMethod::InternalMethodCount)
-
-
- 1428 auto& per_method = per_methods_[
static_cast<int>(req.method)];
- 1429 auto& rules = per_method.rules;
- 1430 unsigned rule_index = per_method.trie.find(req.
url).rule_index;
+ 1419 for (
auto& per_method : per_methods_)
+
+ 1421 per_method.trie.validate();
+
+
+
+
+ 1426 template<
typename Adaptor>
+ 1427 void handle_upgrade(
const request& req,
response& res, Adaptor&& adaptor)
+
+ 1429 if (req.method >= HTTPMethod::InternalMethodCount)
+
-
-
- 1434 for (
auto& per_method : per_methods_)
-
- 1436 if (per_method.trie.find(req.
url).rule_index)
-
- 1438 CROW_LOG_DEBUG <<
"Cannot match method " << req.
url <<
" " << method_name(req.method);
-
-
-
-
-
-
- 1445 CROW_LOG_INFO <<
"Cannot match rules " << req.
url;
-
-
-
-
-
- 1451 if (rule_index >= rules.size())
- 1452 throw std::runtime_error(
"Trie internal structure corrupted!");
-
- 1454 if (rule_index == RULE_SPECIAL_REDIRECT_SLASH)
-
- 1456 CROW_LOG_INFO <<
"Redirecting to a url with trailing slash: " << req.
url;
-
-
-
- 1460 if (req.get_header_value(
"Host").empty())
-
-
-
-
+ 1432 auto& per_method = per_methods_[
static_cast<int>(req.method)];
+ 1433 auto& rules = per_method.rules;
+ 1434 unsigned rule_index = per_method.trie.find(req.
url).rule_index;
+
+
+
+ 1438 for (
auto& method : per_methods_)
+
+ 1440 if (method.trie.find(req.
url).rule_index)
+
+ 1442 CROW_LOG_DEBUG <<
"Cannot match method " << req.
url <<
" " << method_name(req.method);
+
+
+
+
+
+
+ 1449 CROW_LOG_INFO <<
"Cannot match rules " << req.
url;
+
+
+
+
+
+ 1455 if (rule_index >= rules.size())
+ 1456 throw std::runtime_error(
"Trie internal structure corrupted!");
+
+ 1458 if (rule_index == RULE_SPECIAL_REDIRECT_SLASH)
+
+ 1460 CROW_LOG_INFO <<
"Redirecting to a url with trailing slash: " << req.
url;
+
+
+
+ 1464 if (req.get_header_value(
"Host").empty())
- 1466 res.
add_header(
"Location",
"http://" + req.get_header_value(
"Host") + req.
url +
"/");
+
-
-
-
-
- 1472 CROW_LOG_DEBUG <<
"Matched rule (upgrade) '" << rules[rule_index]->rule_ <<
"' " <<
static_cast<uint32_t
>(req.method) <<
" / " << rules[rule_index]->get_methods();
-
-
-
- 1476 rules[rule_index]->handle_upgrade(req, res, std::move(adaptor));
-
-
+
+
+ 1470 res.
add_header(
"Location",
"http://" + req.get_header_value(
"Host") + req.
url +
"/");
+
+
+
+
+
+ 1476 CROW_LOG_DEBUG <<
"Matched rule (upgrade) '" << rules[rule_index]->rule_ <<
"' " <<
static_cast<uint32_t
>(req.method) <<
" / " << rules[rule_index]->get_methods();
+
+
- 1480 exception_handler_(res);
-
-
-
-
-
- 1486 void get_found_bp(std::vector<uint16_t>& bp_i, std::vector<Blueprint*>& blueprints, std::vector<Blueprint*>& found_bps, uint16_t index = 0)
-
-
-
-
-
-
-
-
-
- 1496 auto verify_prefix = [&bp_i, &index, &blueprints, &found_bps]() {
-
- 1498 bp_i[index] < blueprints.size() &&
- 1499 blueprints[bp_i[index]]->prefix().substr(0, found_bps[index - 1]->prefix().length() + 1).compare(std::string(found_bps[index - 1]->prefix() +
'/')) == 0;
-
- 1501 if (index < bp_i.size())
-
-
- 1504 if (verify_prefix())
-
- 1506 found_bps.push_back(blueprints[bp_i[index]]);
- 1507 get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
-
-
-
- 1511 if (found_bps.size() < 2)
-
-
- 1514 found_bps.push_back(blueprints_[bp_i[index]]);
-
-
-
- 1518 found_bps.pop_back();
- 1519 Blueprint* last_element = found_bps.back();
- 1520 found_bps.push_back(last_element->blueprints_[bp_i[index]]);
-
- 1522 get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
-
-
-
-
-
-
-
-
- 1531 std::vector<Blueprint*> bps_found;
- 1532 get_found_bp(found.blueprint_indices, blueprints_, bps_found);
- 1533 for (
int i = bps_found.size() - 1; i > 0; i--)
-
- 1535 std::vector<uint16_t> bpi = found.blueprint_indices;
- 1536 if (bps_found[i]->catchall_rule().has_handler())
-
-
-
- 1540 bps_found[i]->catchall_rule().handler_(req, res);
-
-
+ 1480 rules[rule_index]->handle_upgrade(req, res, std::move(adaptor));
+
+
+
+ 1484 exception_handler_(res);
+
+
+
+
+
+ 1490 void get_found_bp(std::vector<uint16_t>& bp_i, std::vector<Blueprint*>& blueprints, std::vector<Blueprint*>& found_bps, uint16_t index = 0)
+
+
+
+
+
+
+
+
+
+ 1500 auto verify_prefix = [&bp_i, &index, &blueprints, &found_bps]() {
+
+ 1502 bp_i[index] < blueprints.size() &&
+ 1503 blueprints[bp_i[index]]->prefix().substr(0, found_bps[index - 1]->prefix().length() + 1).compare(std::string(found_bps[index - 1]->prefix() +
'/')) == 0;
+
+ 1505 if (index < bp_i.size())
+
+
+ 1508 if (verify_prefix())
+
+ 1510 found_bps.push_back(blueprints[bp_i[index]]);
+ 1511 get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
+
+
+
+ 1515 if (found_bps.size() < 2)
+
+
+ 1518 found_bps.push_back(blueprints_[bp_i[index]]);
+
+
+
+ 1522 found_bps.pop_back();
+ 1523 Blueprint* last_element = found_bps.back();
+ 1524 found_bps.push_back(last_element->blueprints_[bp_i[index]]);
+
+ 1526 get_found_bp(bp_i, found_bps.back()->blueprints_, found_bps, ++index);
+
+
+
+
+
+
+
+
+ 1535 std::vector<Blueprint*> bps_found;
+ 1536 get_found_bp(found.blueprint_indices, blueprints_, bps_found);
+ 1537 for (
int i = bps_found.size() - 1; i > 0; i--)
+
+ 1539 std::vector<uint16_t> bpi = found.blueprint_indices;
+ 1540 if (bps_found[i]->catchall_rule().has_handler())
+
+
- 1544 exception_handler_(res);
+ 1544 bps_found[i]->catchall_rule().handler_(req, res);
- 1546 #ifdef CROW_ENABLE_DEBUG
- 1547 return std::string(
"Redirected to Blueprint \"" + bps_found[i]->prefix() +
"\" Catchall rule");
-
- 1549 return std::string();
-
-
-
- 1553 if (catchall_rule_.has_handler())
-
-
-
- 1557 catchall_rule_.handler_(req, res);
-
-
+
+
+ 1548 exception_handler_(res);
+
+ 1550 #ifdef CROW_ENABLE_DEBUG
+ 1551 return std::string(
"Redirected to Blueprint \"" + bps_found[i]->prefix() +
"\" Catchall rule");
+
+ 1553 return std::string();
+
+
+
+ 1557 if (catchall_rule_.has_handler())
+
+
- 1561 exception_handler_(res);
+ 1561 catchall_rule_.handler_(req, res);
- 1563 #ifdef CROW_ENABLE_DEBUG
- 1564 return std::string(
"Redirected to global Catchall rule");
-
- 1566 return std::string();
-
-
- 1569 return std::string();
-
-
- 1572 std::unique_ptr<routing_handle_result> handle_initial(
request& req,
response& res)
-
- 1574 HTTPMethod method_actual = req.method;
+
+
+ 1565 exception_handler_(res);
+
+ 1567 #ifdef CROW_ENABLE_DEBUG
+ 1568 return std::string(
"Redirected to global Catchall rule");
+
+ 1570 return std::string();
+
+
+ 1573 return std::string();
+
- 1576 std::unique_ptr<routing_handle_result> found{
-
-
- 1579 std::vector<uint16_t>(),
-
- 1581 HTTPMethod::InternalMethodCount)};
-
-
- 1584 if (CROW_UNLIKELY(req.method >= HTTPMethod::InternalMethodCount))
-
- 1586 else if (req.method == HTTPMethod::Head)
-
- 1588 *found = per_methods_[
static_cast<int>(method_actual)].trie.find(req.
url);
-
- 1590 if (!found->rule_index)
-
- 1592 method_actual = HTTPMethod::Get;
- 1593 *found = per_methods_[
static_cast<int>(method_actual)].trie.find(req.
url);
- 1594 if (!found->rule_index)
-
- 1596 CROW_LOG_DEBUG <<
"Cannot match rules " << req.
url;
- 1597 res = response(404);
-
-
-
-
-
-
- 1604 found->method = method_actual;
-
-
- 1607 else if (req.method == HTTPMethod::Options)
-
- 1609 std::string allow =
"OPTIONS, HEAD, ";
-
- 1611 if (req.
url ==
"/*")
-
- 1613 for (
int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
-
- 1615 if (
static_cast<int>(HTTPMethod::Head) == i)
-
-
- 1618 if (!per_methods_[i].trie.is_empty())
-
- 1620 allow += method_name(
static_cast<HTTPMethod
>(i)) +
", ";
-
-
- 1623 allow = allow.substr(0, allow.size() - 2);
- 1624 res = response(204);
-
-
- 1627 found->method = method_actual;
-
-
-
-
- 1632 bool rules_matched =
false;
- 1633 for (
int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
-
- 1635 if (per_methods_[i].trie.find(req.
url).rule_index)
-
- 1637 rules_matched =
true;
-
- 1639 if (
static_cast<int>(HTTPMethod::Head) == i)
-
-
- 1642 allow += method_name(
static_cast<HTTPMethod
>(i)) +
", ";
-
-
-
-
- 1647 allow = allow.substr(0, allow.size() - 2);
- 1648 res = response(204);
-
-
- 1651 found->method = method_actual;
-
-
-
-
- 1656 CROW_LOG_DEBUG <<
"Cannot match rules " << req.
url;
- 1657 res = response(404);
-
-
-
-
-
-
-
- 1665 *found = per_methods_[
static_cast<int>(method_actual)].trie.find(req.
url);
-
- 1667 if (!found->rule_index)
-
- 1669 for (
auto& per_method : per_methods_)
-
- 1671 if (per_method.trie.find(req.
url).rule_index)
-
- 1673 const std::string error_message(
get_error(405, *found, req, res));
- 1674 CROW_LOG_DEBUG <<
"Cannot match method " << req.
url <<
" " << method_name(method_actual) <<
". " << error_message;
-
-
-
-
-
-
- 1681 const std::string error_message(
get_error(404, *found, req, res));
- 1682 CROW_LOG_DEBUG <<
"Cannot match rules " << req.
url <<
". " << error_message;
-
-
-
-
- 1687 found->method = method_actual;
-
-
-
-
- 1692 template<
typename App>
- 1693 void handle(request& req, response& res, routing_handle_result found)
-
- 1695 HTTPMethod method_actual = found.method;
- 1696 auto& rules = per_methods_[
static_cast<int>(method_actual)].rules;
- 1697 unsigned rule_index = found.rule_index;
-
- 1699 if (rule_index >= rules.size())
- 1700 throw std::runtime_error(
"Trie internal structure corrupted!");
-
- 1702 if (rule_index == RULE_SPECIAL_REDIRECT_SLASH)
-
- 1704 CROW_LOG_INFO <<
"Redirecting to a url with trailing slash: " << req.url;
- 1705 res = response(301);
-
-
- 1708 if (req.get_header_value(
"Host").empty())
-
- 1710 res.add_header(
"Location", req.url +
"/");
-
-
+ 1576 std::unique_ptr<routing_handle_result> handle_initial(
request& req,
response& res)
+
+ 1578 HTTPMethod method_actual = req.method;
+
+ 1580 std::unique_ptr<routing_handle_result> found{
+
+
+ 1583 std::vector<uint16_t>(),
+
+ 1585 HTTPMethod::InternalMethodCount)};
+
+
+ 1588 if (CROW_UNLIKELY(req.method >= HTTPMethod::InternalMethodCount))
+
+ 1590 else if (req.method == HTTPMethod::Head)
+
+ 1592 *found = per_methods_[
static_cast<int>(method_actual)].trie.find(req.
url);
+
+ 1594 if (!found->rule_index)
+
+ 1596 method_actual = HTTPMethod::Get;
+ 1597 *found = per_methods_[
static_cast<int>(method_actual)].trie.find(req.
url);
+ 1598 if (!found->rule_index)
+
+ 1600 CROW_LOG_DEBUG <<
"Cannot match rules " << req.
url;
+ 1601 res = response(404);
+
+
+
+
+
+
+ 1608 found->method = method_actual;
+
+
+ 1611 else if (req.method == HTTPMethod::Options)
+
+ 1613 std::string allow =
"OPTIONS, HEAD, ";
+
+ 1615 if (req.
url ==
"/*")
+
+ 1617 for (
int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
+
+ 1619 if (
static_cast<int>(HTTPMethod::Head) == i)
+
+
+ 1622 if (!per_methods_[i].trie.is_empty())
+
+ 1624 allow += method_name(
static_cast<HTTPMethod
>(i)) +
", ";
+
+
+ 1627 allow = allow.substr(0, allow.size() - 2);
+ 1628 res = response(204);
+
+
+ 1631 found->method = method_actual;
+
+
+
+
+ 1636 bool rules_matched =
false;
+ 1637 for (
int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
+
+ 1639 if (per_methods_[i].trie.find(req.
url).rule_index)
+
+ 1641 rules_matched =
true;
+
+ 1643 if (
static_cast<int>(HTTPMethod::Head) == i)
+
+
+ 1646 allow += method_name(
static_cast<HTTPMethod
>(i)) +
", ";
+
+
+
+
+ 1651 allow = allow.substr(0, allow.size() - 2);
+ 1652 res = response(204);
+
+
+ 1655 found->method = method_actual;
+
+
+
+
+ 1660 CROW_LOG_DEBUG <<
"Cannot match rules " << req.
url;
+ 1661 res = response(404);
+
+
+
+
+
+
+
+ 1669 *found = per_methods_[
static_cast<int>(method_actual)].trie.find(req.
url);
+
+ 1671 if (!found->rule_index)
+
+ 1673 for (
auto& per_method : per_methods_)
+
+ 1675 if (per_method.trie.find(req.
url).rule_index)
+
+ 1677 const std::string error_message(
get_error(405, *found, req, res));
+ 1678 CROW_LOG_DEBUG <<
"Cannot match method " << req.
url <<
" " << method_name(method_actual) <<
". " << error_message;
+
+
+
+
+
+
+ 1685 const std::string error_message(
get_error(404, *found, req, res));
+ 1686 CROW_LOG_DEBUG <<
"Cannot match rules " << req.
url <<
". " << error_message;
+
+
+
+
+ 1691 found->method = method_actual;
+
+
+
+
+ 1696 template<
typename App>
+ 1697 void handle(request& req, response& res, routing_handle_result found)
+
+ 1699 HTTPMethod method_actual = found.method;
+ 1700 auto& rules = per_methods_[
static_cast<int>(method_actual)].rules;
+ 1701 unsigned rule_index = found.rule_index;
+
+ 1703 if (rule_index >= rules.size())
+ 1704 throw std::runtime_error(
"Trie internal structure corrupted!");
+
+ 1706 if (rule_index == RULE_SPECIAL_REDIRECT_SLASH)
+
+ 1708 CROW_LOG_INFO <<
"Redirecting to a url with trailing slash: " << req.url;
+ 1709 res = response(301);
+
+
+ 1712 if (req.get_header_value(
"Host").empty())
- 1714 res.add_header(
"Location",
"http://" + req.get_header_value(
"Host") + req.url +
"/");
+ 1714 res.add_header(
"Location", req.url +
"/");
-
-
-
-
- 1720 CROW_LOG_DEBUG <<
"Matched rule '" << rules[rule_index]->rule_ <<
"' " <<
static_cast<uint32_t
>(req.method) <<
" / " << rules[rule_index]->get_methods();
-
-
-
- 1724 auto& rule = rules[rule_index];
- 1725 handle_rule<App>(rule, req, res, found.r_params);
-
-
-
- 1729 exception_handler_(res);
-
-
-
-
-
- 1735 template<
typename App>
- 1736 typename std::enable_if<std::tuple_size<typename App::mw_container_t>::value != 0,
void>::type
-
-
- 1739 if (!rule->mw_indices_.empty())
-
- 1741 auto& ctx = *
reinterpret_cast<typename App::context_t*
>(req.middleware_context);
- 1742 auto& container = *
reinterpret_cast<typename App::mw_container_t*
>(req.middleware_container);
- 1743 detail::middleware_call_criteria_dynamic<false> crit_fwd(rule->mw_indices_.indices());
-
- 1745 auto glob_completion_handler = std::move(res.complete_request_handler_);
- 1746 res.complete_request_handler_ = [] {};
-
- 1748 detail::middleware_call_helper<decltype(crit_fwd),
- 1749 0,
typename App::context_t,
typename App::mw_container_t>(crit_fwd, container, req, res, ctx);
-
-
-
- 1753 glob_completion_handler();
-
-
-
- 1757 res.complete_request_handler_ = [&rule, &ctx, &container, &req, &res, glob_completion_handler] {
- 1758 detail::middleware_call_criteria_dynamic<true> crit_bwd(rule->mw_indices_.indices());
-
- 1760 detail::after_handlers_call_helper<
-
- 1762 std::tuple_size<typename App::mw_container_t>::value - 1,
- 1763 typename App::context_t,
- 1764 typename App::mw_container_t>(crit_bwd, container, ctx, req, res);
- 1765 glob_completion_handler();
-
-
- 1768 rule->handle(req, res, rp);
-
-
- 1771 template<
typename App>
- 1772 typename std::enable_if<std::tuple_size<typename App::mw_container_t>::value == 0,
void>::type
-
-
- 1775 rule->handle(req, res, rp);
-
-
-
-
- 1780 for (
int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
-
- 1782 Trie& trie_ = per_methods_[i].trie;
- 1783 if (!trie_.is_empty())
-
- 1785 CROW_LOG_DEBUG << method_name(static_cast<HTTPMethod>(i));
- 1786 trie_.debug_print();
-
-
-
-
- 1791 std::vector<Blueprint*>& blueprints()
-
-
-
-
-
-
- 1798 return exception_handler_;
-
-
- 1801 static void default_exception_handler(response& res)
-
-
- 1804 res = response(500);
-
-
-
-
-
- 1810 catch (
const std::exception& e)
+
+
+ 1718 res.add_header(
"Location",
"http://" + req.get_header_value(
"Host") + req.url +
"/");
+
+
+
+
+
+ 1724 CROW_LOG_DEBUG <<
"Matched rule '" << rules[rule_index]->rule_ <<
"' " <<
static_cast<uint32_t
>(req.method) <<
" / " << rules[rule_index]->get_methods();
+
+
+
+ 1728 auto& rule = rules[rule_index];
+ 1729 handle_rule<App>(rule, req, res, found.r_params);
+
+
+
+ 1733 exception_handler_(res);
+
+
+
+
+
+ 1739 template<
typename App>
+ 1740 typename std::enable_if<std::tuple_size<typename App::mw_container_t>::value != 0,
void>::type
+
+
+ 1743 if (!rule->mw_indices_.empty())
+
+ 1745 auto& ctx = *
reinterpret_cast<typename App::context_t*
>(req.middleware_context);
+ 1746 auto& container = *
reinterpret_cast<typename App::mw_container_t*
>(req.middleware_container);
+ 1747 detail::middleware_call_criteria_dynamic<false> crit_fwd(rule->mw_indices_.indices());
+
+ 1749 auto glob_completion_handler = std::move(res.complete_request_handler_);
+ 1750 res.complete_request_handler_ = [] {};
+
+ 1752 detail::middleware_call_helper<decltype(crit_fwd),
+ 1753 0,
typename App::context_t,
typename App::mw_container_t>(crit_fwd, container, req, res, ctx);
+
+
+
+ 1757 glob_completion_handler();
+
+
+
+ 1761 res.complete_request_handler_ = [&rule, &ctx, &container, &req, &res, glob_completion_handler] {
+ 1762 detail::middleware_call_criteria_dynamic<true> crit_bwd(rule->mw_indices_.indices());
+
+ 1764 detail::after_handlers_call_helper<
+
+ 1766 std::tuple_size<typename App::mw_container_t>::value - 1,
+ 1767 typename App::context_t,
+ 1768 typename App::mw_container_t>(crit_bwd, container, ctx, req, res);
+ 1769 glob_completion_handler();
+
+
+ 1772 rule->handle(req, res, rp);
+
+
+ 1775 template<
typename App>
+ 1776 typename std::enable_if<std::tuple_size<typename App::mw_container_t>::value == 0,
void>::type
+
+
+ 1779 rule->handle(req, res, rp);
+
+
+
+
+ 1784 for (
int i = 0; i < static_cast<int>(HTTPMethod::InternalMethodCount); i++)
+
+ 1786 Trie& trie_ = per_methods_[i].trie;
+ 1787 if (!trie_.is_empty())
+
+ 1789 CROW_LOG_DEBUG << method_name(static_cast<HTTPMethod>(i));
+ 1790 trie_.debug_print();
+
+
+
+
+ 1795 std::vector<Blueprint*>& blueprints()
+
+
+
+
+
+
+ 1802 return exception_handler_;
+
+
+ 1805 static void default_exception_handler(response& res)
+
+
+ 1808 res = response(500);
+
+
- 1812 CROW_LOG_ERROR <<
"An uncaught exception occurred: " << e.what();
+
-
+ 1814 catch (
const std::exception& e)
- 1816 CROW_LOG_ERROR <<
"An uncaught exception occurred. The type was unknown so no information was available.";
+ 1816 CROW_LOG_ERROR <<
"An uncaught exception occurred: " << e.what();
-
-
-
- 1821 CatchallRule catchall_rule_;
-
-
-
- 1825 std::vector<BaseRule*> rules;
-
-
-
-
-
-
- 1832 std::array<PerMethod, static_cast<int>(HTTPMethod::InternalMethodCount)> per_methods_;
- 1833 std::vector<std::unique_ptr<BaseRule>> all_rules_;
- 1834 std::vector<Blueprint*> blueprints_;
- 1835 std::function<void(
crow::response&)> exception_handler_ = &default_exception_handler;
-
-
+
+
+ 1820 CROW_LOG_ERROR <<
"An uncaught exception occurred. The type was unknown so no information was available.";
+
+
+
+
+ 1825 CatchallRule catchall_rule_;
+
+
+
+ 1829 std::vector<BaseRule*> rules;
+
+
+
+
+
+
+ 1836 std::array<PerMethod, static_cast<int>(HTTPMethod::InternalMethodCount)> per_methods_;
+ 1837 std::vector<std::unique_ptr<BaseRule>> all_rules_;
+ 1838 std::vector<Blueprint*> blueprints_;
+ 1839 std::function<void(
crow::response&)> exception_handler_ = &default_exception_handler;
+
+
A base class for all rules.
Definition: routing.h:89
-A blueprint can be considered a smaller section of a Crow app, specifically where the router is conce...
Definition: routing.h:1111
-Definition: routing.h:342
+A blueprint can be considered a smaller section of a Crow app, specifically where the router is conce...
Definition: routing.h:1113
+Definition: routing.h:344
The main server application class.
Definition: app.h:199
self_t & websocket_max_payload(uint64_t max_payload)
Set the default max payload size for websockets.
Definition: app.h:278
-A rule that can change its parameters during runtime.
Definition: routing.h:582
-Handles matching requests to existing rules and upgrade requests.
Definition: routing.h:1264
-std::string get_error(unsigned short code, routing_handle_result &found, const request &req, response &res)
Is used to handle errors, you insert the error code, found route, request, and response....
Definition: routing.h:1528
-Default rule created when CROW_ROUTE is called.
Definition: routing.h:659
-A search tree.
Definition: routing.h:723
-bool is_empty()
Check whether or not the trie is empty.
Definition: routing.h:757
-A rule dealing with websockets.
Definition: routing.h:442
-self_t & max_payload(uint64_t max_payload)
Override the global payload limit for this single WebSocket rule.
Definition: routing.h:474
+A rule that can change its parameters during runtime.
Definition: routing.h:584
+Handles matching requests to existing rules and upgrade requests.
Definition: routing.h:1267
+std::string get_error(unsigned short code, routing_handle_result &found, const request &req, response &res)
Is used to handle errors, you insert the error code, found route, request, and response....
Definition: routing.h:1532
+Default rule created when CROW_ROUTE is called.
Definition: routing.h:661
+A search tree.
Definition: routing.h:725
+bool is_empty()
Check whether or not the trie is empty.
Definition: routing.h:759
+A rule dealing with websockets.
Definition: routing.h:444
+self_t & max_payload(uint64_t max_payload)
Override the global payload limit for this single WebSocket rule.
Definition: routing.h:476
A websocket connection.
Definition: websocket.h:106
This file includes the definition of the crow::mustache namespace and its members.
void set_base(const std::string &path)
Defines the templates directory path at route level. By default is templates/.
Definition: mustache.h:738
The main namespace of the library. In this namespace is defined the most important classes and functi...
Crow< Middlewares... > App
Alias of Crow<Middlewares...>. Useful if you want a instance of an Crow application that require Midd...
Definition: app.h:786
-Allows the user to assign parameters using functions.
Definition: routing.h:540
-self_t & middlewares()
Enable local middleware for this handler.
Definition: routing.h:573
+Allows the user to assign parameters using functions.
Definition: routing.h:542
+self_t & middlewares()
Enable local middleware for this handler.
Definition: routing.h:575
Definition: socket_adaptors.h:107
A wrapper for the asio::ip::tcp::socket and asio::ssl::stream.
Definition: socket_adaptors.h:39
-Definition: routing.h:726
+Definition: routing.h:728
Typesafe wrapper for storing lists of middleware as their indices in the App.
Definition: routing.h:30
-Definition: routing.h:303
-Definition: routing.h:262
-Definition: routing.h:244
-Definition: routing.h:172
-Definition: routing.h:179
-Definition: routing.h:188
+Definition: routing.h:305
+Definition: routing.h:264
+Definition: routing.h:246
+Definition: routing.h:174
+Definition: routing.h:181
+Definition: routing.h:190
An HTTP request.
Definition: http_request.h:36
std::string url
The endpoint without any parameters.
Definition: http_request.h:39
HTTP response.
Definition: http_response.h:34
diff --git a/master/reference/search/all_10.js b/master/reference/search/all_10.js
index e75441705..3d2187c83 100644
--- a/master/reference/search/all_10.js
+++ b/master/reference/search/all_10.js
@@ -11,7 +11,7 @@ var searchData=
['rendered_5ftemplate_191',['rendered_template',['../structcrow_1_1mustache_1_1rendered__template.html',1,'crow::mustache']]],
['req_192',['req',['../structcrow_1_1_h_t_t_p_parser.html#a56ce939040d6c582a62cea766e489d53',1,'crow::HTTPParser']]],
['req_5fhandler_5fwrapper_193',['req_handler_wrapper',['../structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html',1,'crow::detail::routing_handler_call_helper::Wrapped']]],
- ['request_194',['request',['../structcrow_1_1request.html',1,'crow::request'],['../structcrow_1_1request.html#a838c9a8c9a5eb2283d57e66f3630b5a6',1,'crow::request::request()'],['../structcrow_1_1request.html#a111b70ddb2a100a79415b539e152e145',1,'crow::request::request(HTTPMethod method, std::string raw_url, std::string url, query_string url_params, ci_map headers, std::string body, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade)']]],
+ ['request_194',['request',['../structcrow_1_1request.html',1,'crow::request'],['../structcrow_1_1request.html#a838c9a8c9a5eb2283d57e66f3630b5a6',1,'crow::request::request()'],['../structcrow_1_1request.html#ab90c2762f152a7d58a1ab8ea55e0afd0',1,'crow::request::request(HTTPMethod method_, std::string raw_url_, std::string url_, query_string url_params_, ci_map headers_, std::string body_, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade)']]],
['response_195',['response',['../structcrow_1_1response.html',1,'crow']]],
['returnable_196',['returnable',['../structcrow_1_1returnable.html',1,'crow']]],
['route_197',['route',['../classcrow_1_1_crow.html#a5e1e54d49ff3015fd08f545b574ab44f',1,'crow::Crow']]],
diff --git a/master/reference/search/all_b.js b/master/reference/search/all_b.js
index 52b9fdf5b..273f73fed 100644
--- a/master/reference/search/all_b.js
+++ b/master/reference/search/all_b.js
@@ -3,8 +3,8 @@ var searchData=
['manual_5flength_5fheader_136',['manual_length_header',['../structcrow_1_1response.html#a95f300c05782e1934dad522b6d6588cf',1,'crow::response']]],
['max_5fage_137',['max_age',['../structcrow_1_1_c_o_r_s_rules.html#aa3721c183750d7317d165c1b89013717',1,'crow::CORSRules']]],
['max_5fpayload_138',['max_payload',['../classcrow_1_1_web_socket_rule.html#ad4d8b25025e767fbe9af7f7c4263c2cb',1,'crow::WebSocketRule']]],
- ['message_139',['message',['../structcrow_1_1multipart_1_1message.html',1,'crow::multipart::message'],['../structcrow_1_1multipart_1_1message.html#a32946a0f39a8d024aaf4643116a7561b',1,'crow::multipart::message::message(const request &req)'],['../structcrow_1_1multipart_1_1message.html#a0007fa0cadffae1a8d16fac169d1527b',1,'crow::multipart::message::message(const ci_map &headers, const std::string &boundary, const std::vector< part > §ions)']]],
- ['message_5fview_140',['message_view',['../structcrow_1_1multipart_1_1message__view.html',1,'crow::multipart::message_view'],['../structcrow_1_1multipart_1_1message__view.html#ae01a2e1676ca9d22d625200df14b88fe',1,'crow::multipart::message_view::message_view(const ci_map &headers, const std::string &boundary, const std::vector< part_view > §ions)'],['../structcrow_1_1multipart_1_1message__view.html#ad0a498ccdfea67c512d5cb23f62c4f1c',1,'crow::multipart::message_view::message_view(const request &req)']]],
+ ['message_139',['message',['../structcrow_1_1multipart_1_1message.html',1,'crow::multipart::message'],['../structcrow_1_1multipart_1_1message.html#a32946a0f39a8d024aaf4643116a7561b',1,'crow::multipart::message::message(const request &req)'],['../structcrow_1_1multipart_1_1message.html#a04ffb20817903d00334268d31f635621',1,'crow::multipart::message::message(const ci_map &headers_, const std::string &boundary_, const std::vector< part > §ions)']]],
+ ['message_5fview_140',['message_view',['../structcrow_1_1multipart_1_1message__view.html',1,'crow::multipart::message_view'],['../structcrow_1_1multipart_1_1message__view.html#ab2985a84afde169fb89fc35e430106db',1,'crow::multipart::message_view::message_view(const ci_map &headers_, const std::string &boundary_, const std::vector< part_view > §ions)'],['../structcrow_1_1multipart_1_1message__view.html#ad0a498ccdfea67c512d5cb23f62c4f1c',1,'crow::multipart::message_view::message_view(const request &req)']]],
['methods_141',['methods',['../structcrow_1_1_c_o_r_s_rules.html#a345cef92c2f28444e505646d429717cb',1,'crow::CORSRules::methods(crow::HTTPMethod method)'],['../structcrow_1_1_c_o_r_s_rules.html#a7ffe0b716c19efe9f576091c92cf83b4',1,'crow::CORSRules::methods(crow::HTTPMethod method, Methods... method_list)']]],
['middleware_5fcall_5fcriteria_5fdynamic_142',['middleware_call_criteria_dynamic',['../structcrow_1_1detail_1_1middleware__call__criteria__dynamic.html',1,'crow::detail']]],
['middleware_5fcall_5fcriteria_5fdynamic_3c_20false_20_3e_143',['middleware_call_criteria_dynamic< false >',['../structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html',1,'crow::detail']]],
diff --git a/master/reference/search/all_d.js b/master/reference/search/all_d.js
index a472fe1f0..f244f8f25 100644
--- a/master/reference/search/all_d.js
+++ b/master/reference/search/all_d.js
@@ -3,7 +3,7 @@ var searchData=
['opcode_159',['opcode',['../classcrow_1_1websocket_1_1_connection.html#a6d74305323202dc7ebd07cbd3ee19f98',1,'crow::websocket::Connection']]],
['operator_20double_160',['operator double',['../structcrow_1_1multipart_1_1header.html#a0b87278e0ebe8d323f46c9ed64fc385a',1,'crow::multipart::header::operator double()'],['../structcrow_1_1multipart_1_1part.html#ac9c4ebeeabe158725bc67cf14c9f957e',1,'crow::multipart::part::operator double()'],['../structcrow_1_1multipart_1_1header__view.html#a06c7abf8526ec9826b3962969b67cc6d',1,'crow::multipart::header_view::operator double()'],['../structcrow_1_1multipart_1_1part__view.html#a55cbb62dd09e491594475b10b761a99c',1,'crow::multipart::part_view::operator double()']]],
['operator_20int_161',['operator int',['../structcrow_1_1multipart_1_1header.html#adff380493f414108eb67420d06d426ee',1,'crow::multipart::header::operator int()'],['../structcrow_1_1multipart_1_1part.html#a06851f0fd2d36b71139e8488fb646b7e',1,'crow::multipart::part::operator int()'],['../structcrow_1_1multipart_1_1header__view.html#a3031c16055b06d94567802ec202c6622',1,'crow::multipart::header_view::operator int()'],['../structcrow_1_1multipart_1_1part__view.html#a2307998bbce5709e7d1d7cee49b7edc0',1,'crow::multipart::part_view::operator int()']]],
- ['operator_3c_3c_162',['operator<<',['../structcrow_1_1multipart_1_1padded.html#a27b10196d6f596db53102988da72e47e',1,'crow::multipart::padded']]],
+ ['operator_3c_3c_162',['operator<<',['../structcrow_1_1multipart_1_1padded.html#a65a7ba8beab915313c5d078727151776',1,'crow::multipart::padded']]],
['origin_163',['origin',['../structcrow_1_1_c_o_r_s_rules.html#a1d7a6517c7c256046065b2a02a25f6fa',1,'crow::CORSRules']]],
['string_164',['string',['../classcrow_1_1json_1_1rvalue.html#a2d5dd8607112a132fe070dee432987ae',1,'crow::json::rvalue']]]
];
diff --git a/master/reference/search/functions_a.js b/master/reference/search/functions_a.js
index 5d3400294..4faa60ad5 100644
--- a/master/reference/search/functions_a.js
+++ b/master/reference/search/functions_a.js
@@ -2,8 +2,8 @@ var searchData=
[
['max_5fage_435',['max_age',['../structcrow_1_1_c_o_r_s_rules.html#aa3721c183750d7317d165c1b89013717',1,'crow::CORSRules']]],
['max_5fpayload_436',['max_payload',['../classcrow_1_1_web_socket_rule.html#ad4d8b25025e767fbe9af7f7c4263c2cb',1,'crow::WebSocketRule']]],
- ['message_437',['message',['../structcrow_1_1multipart_1_1message.html#a0007fa0cadffae1a8d16fac169d1527b',1,'crow::multipart::message::message(const ci_map &headers, const std::string &boundary, const std::vector< part > §ions)'],['../structcrow_1_1multipart_1_1message.html#a32946a0f39a8d024aaf4643116a7561b',1,'crow::multipart::message::message(const request &req)']]],
- ['message_5fview_438',['message_view',['../structcrow_1_1multipart_1_1message__view.html#ae01a2e1676ca9d22d625200df14b88fe',1,'crow::multipart::message_view::message_view(const ci_map &headers, const std::string &boundary, const std::vector< part_view > §ions)'],['../structcrow_1_1multipart_1_1message__view.html#ad0a498ccdfea67c512d5cb23f62c4f1c',1,'crow::multipart::message_view::message_view(const request &req)']]],
+ ['message_437',['message',['../structcrow_1_1multipart_1_1message.html#a04ffb20817903d00334268d31f635621',1,'crow::multipart::message::message(const ci_map &headers_, const std::string &boundary_, const std::vector< part > §ions)'],['../structcrow_1_1multipart_1_1message.html#a32946a0f39a8d024aaf4643116a7561b',1,'crow::multipart::message::message(const request &req)']]],
+ ['message_5fview_438',['message_view',['../structcrow_1_1multipart_1_1message__view.html#ab2985a84afde169fb89fc35e430106db',1,'crow::multipart::message_view::message_view(const ci_map &headers_, const std::string &boundary_, const std::vector< part_view > §ions)'],['../structcrow_1_1multipart_1_1message__view.html#ad0a498ccdfea67c512d5cb23f62c4f1c',1,'crow::multipart::message_view::message_view(const request &req)']]],
['methods_439',['methods',['../structcrow_1_1_c_o_r_s_rules.html#a345cef92c2f28444e505646d429717cb',1,'crow::CORSRules::methods(crow::HTTPMethod method)'],['../structcrow_1_1_c_o_r_s_rules.html#a7ffe0b716c19efe9f576091c92cf83b4',1,'crow::CORSRules::methods(crow::HTTPMethod method, Methods... method_list)']]],
['middlewares_440',['middlewares',['../structcrow_1_1_rule_parameter_traits.html#a137eb67383f095ce7ae5ef4da19656ab',1,'crow::RuleParameterTraits']]],
['moved_441',['moved',['../structcrow_1_1response.html#a760bca5f5fdee03518d59d9538ce5432',1,'crow::response']]],
diff --git a/master/reference/search/functions_e.js b/master/reference/search/functions_e.js
index 153a9570d..c81b70236 100644
--- a/master/reference/search/functions_e.js
+++ b/master/reference/search/functions_e.js
@@ -5,7 +5,7 @@ var searchData=
['redirect_5fperm_459',['redirect_perm',['../structcrow_1_1response.html#a9e87a17c3cf8b434fd2a64a9b3d4b675',1,'crow::response']]],
['render_460',['render',['../classcrow_1_1mustache_1_1template__t.html#a67caf7e23349a829b913c897ab882a8e',1,'crow::mustache::template_t::render() const'],['../classcrow_1_1mustache_1_1template__t.html#a77c579b71240695bd9fb634f48facd03',1,'crow::mustache::template_t::render(const context &ctx) const'],['../classcrow_1_1mustache_1_1template__t.html#ae8f2561efe590c0b5704df76b0c82aa5',1,'crow::mustache::template_t::render(const context &&ctx) const']]],
['render_5fstring_461',['render_string',['../classcrow_1_1mustache_1_1template__t.html#a21199e08a066d7c66b5728354c2c40fd',1,'crow::mustache::template_t::render_string() const'],['../classcrow_1_1mustache_1_1template__t.html#af2258136c497b02eadfacbf50704de08',1,'crow::mustache::template_t::render_string(const context &ctx) const']]],
- ['request_462',['request',['../structcrow_1_1request.html#a838c9a8c9a5eb2283d57e66f3630b5a6',1,'crow::request::request()'],['../structcrow_1_1request.html#a111b70ddb2a100a79415b539e152e145',1,'crow::request::request(HTTPMethod method, std::string raw_url, std::string url, query_string url_params, ci_map headers, std::string body, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade)']]],
+ ['request_462',['request',['../structcrow_1_1request.html#a838c9a8c9a5eb2283d57e66f3630b5a6',1,'crow::request::request()'],['../structcrow_1_1request.html#ab90c2762f152a7d58a1ab8ea55e0afd0',1,'crow::request::request(HTTPMethod method_, std::string raw_url_, std::string url_, query_string url_params_, ci_map headers_, std::string body_, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade)']]],
['route_463',['route',['../classcrow_1_1_crow.html#a5e1e54d49ff3015fd08f545b574ab44f',1,'crow::Crow']]],
['route_5fdynamic_464',['route_dynamic',['../classcrow_1_1_crow.html#a0822a573ed653c3218f06c819a773ec2',1,'crow::Crow']]],
['run_465',['run',['../classcrow_1_1_crow.html#a193d8b03f717234a841cd92f72c6b4b5',1,'crow::Crow']]],
diff --git a/master/reference/search/related_0.js b/master/reference/search/related_0.js
index 27010cd56..ce2d152fe 100644
--- a/master/reference/search/related_0.js
+++ b/master/reference/search/related_0.js
@@ -1,4 +1,4 @@
var searchData=
[
- ['operator_3c_3c_533',['operator<<',['../structcrow_1_1multipart_1_1padded.html#a27b10196d6f596db53102988da72e47e',1,'crow::multipart::padded']]]
+ ['operator_3c_3c_533',['operator<<',['../structcrow_1_1multipart_1_1padded.html#a65a7ba8beab915313c5d078727151776',1,'crow::multipart::padded']]]
];
diff --git a/master/reference/session_8h_source.html b/master/reference/session_8h_source.html
index c76e0c11b..1d3583465 100644
--- a/master/reference/session_8h_source.html
+++ b/master/reference/session_8h_source.html
@@ -703,8 +703,8 @@
-JSON read value.
Definition: json.h:276
-JSON write value.
Definition: json.h:1289
+JSON read value.
Definition: json.h:278
+JSON write value.
Definition: json.h:1291
template_t load(const std::string &filename)
Open, read and renders a file using a mustache compiler. It also sanitize the input before compilatio...
Definition: mustache.h:812
The main namespace of the library. In this namespace is defined the most important classes and functi...
Definition: cookie_parser.h:37
@@ -713,7 +713,7 @@
InMemoryStore stores all entries in memory.
Definition: session.h:481
Definition: session.h:238
Definition: session.h:228
-
+
CachedSessions are shared across requests.
Definition: session.h:208
Expiration tracker keeps track of soonest-to-expire keys.
Definition: session.h:156
uint64_t peek_first() const
Get expiration time of soonest-to-expire entry.
Definition: session.h:180
diff --git a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4-members.html b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4-members.html
index ebe99d7c1..b46a4fa57 100644
--- a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4-members.html
+++ b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4-members.html
@@ -103,7 +103,7 @@
This is the complete list of members for crow::detail::middleware_call_criteria_dynamic< false >, including all inherited members.
diff --git a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html
index 040cfdb1f..5a8014d4d 100644
--- a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html
+++ b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html
@@ -105,9 +105,9 @@
|
-
- | middleware_call_criteria_dynamic (const std::vector< int > &indices) |
- |
+
+ | middleware_call_criteria_dynamic (const std::vector< int > &indices_) |
+ |
template<typename > |
bool | enabled (int mw_index) const |
diff --git a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.js b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.js
index 9b1518b62..6dfafee43 100644
--- a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.js
+++ b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.js
@@ -1,5 +1,5 @@
var structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4 =
[
- [ "middleware_call_criteria_dynamic", "structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html#a975e9db833b37965e9113a44787de713", null ],
+ [ "middleware_call_criteria_dynamic", "structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html#aebfc2f7848a728de2a901e33cda556cf", null ],
[ "enabled", "structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01false_01_4.html#a03d8f77d9bec07bf6cddce95adde8fc6", null ]
];
\ No newline at end of file
diff --git a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4-members.html b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4-members.html
index 1e447cfd9..c241bd666 100644
--- a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4-members.html
+++ b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4-members.html
@@ -103,7 +103,7 @@
This is the complete list of members for crow::detail::middleware_call_criteria_dynamic< true >, including all inherited members.
diff --git a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html
index 05d85fe53..2310ae566 100644
--- a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html
+++ b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html
@@ -105,9 +105,9 @@
|
-
- | middleware_call_criteria_dynamic (const std::vector< int > &indices) |
- |
+
+ | middleware_call_criteria_dynamic (const std::vector< int > &indices_) |
+ |
template<typename > |
bool | enabled (int mw_index) const |
diff --git a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.js b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.js
index 3dae86386..36a2b9fde 100644
--- a/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.js
+++ b/master/reference/structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.js
@@ -1,5 +1,5 @@
var structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4 =
[
- [ "middleware_call_criteria_dynamic", "structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html#a6f5d720273c0de6ae01a138e0bb84cc6", null ],
+ [ "middleware_call_criteria_dynamic", "structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html#a9a85b847e8f7fb3452037becd99e3411", null ],
[ "enabled", "structcrow_1_1detail_1_1middleware__call__criteria__dynamic_3_01true_01_4.html#abf5e13ed2e5057951fffb0ffa4c41ad5", null ]
];
\ No newline at end of file
diff --git a/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper-members.html b/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper-members.html
index 068fd33a5..c10825fcc 100644
--- a/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper-members.html
+++ b/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper-members.html
@@ -104,7 +104,7 @@
f (defined in crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args >) | crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args > | |
operator()(const request &req, response &res, Args... args) (defined in crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args >) | crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args > | inline |
- req_handler_wrapper(Func f) (defined in crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args >) | crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args > | inline |
+ req_handler_wrapper(Func fun) (defined in crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args >) | crow::detail::routing_handler_call_helper::Wrapped< Func, ArgsWrapped >::req_handler_wrapper< Req, Args > | inline |
diff --git a/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html b/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html
index 90c00d31b..cabe3c946 100644
--- a/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html
+++ b/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html
@@ -106,9 +106,9 @@
|
-
- | req_handler_wrapper (Func f) |
- |
+
+ | req_handler_wrapper (Func fun) |
+ |
void | operator() (const request &req, response &res, Args... args) |
|
diff --git a/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.js b/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.js
index ea86183eb..4063a4a98 100644
--- a/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.js
+++ b/master/reference/structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.js
@@ -1,6 +1,6 @@
var structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper =
[
- [ "req_handler_wrapper", "structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#aba29fdf5c44192709c4eef8e84a48485", null ],
+ [ "req_handler_wrapper", "structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#a994caa9765212339486fd6245e08b4ff", null ],
[ "operator()", "structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#a40965565a28cc879ec75c831c0b729ae", null ],
[ "f", "structcrow_1_1detail_1_1routing__handler__call__helper_1_1_wrapped_1_1req__handler__wrapper.html#a0553c3d38f4902d9c3fa8655812ddbd7", null ]
];
\ No newline at end of file
diff --git a/master/reference/structcrow_1_1multipart_1_1message-members.html b/master/reference/structcrow_1_1multipart_1_1message-members.html
index 0011cf2e6..af5c7864f 100644
--- a/master/reference/structcrow_1_1multipart_1_1message-members.html
+++ b/master/reference/structcrow_1_1multipart_1_1message-members.html
@@ -109,7 +109,7 @@
get_header_value(const std::string &key) const (defined in crow::multipart::message) | crow::multipart::message | inline |
get_part_by_name(const std::string &name) (defined in crow::multipart::message) | crow::multipart::message | inline |
headers | crow::multipart::message | |
- message(const ci_map &headers, const std::string &boundary, const std::vector< part > §ions) | crow::multipart::message | inline |
+ message(const ci_map &headers_, const std::string &boundary_, const std::vector< part > §ions) | crow::multipart::message | inline |
message(const request &req) | crow::multipart::message | inlineexplicit |
part_map | crow::multipart::message | |
parts | crow::multipart::message | |
diff --git a/master/reference/structcrow_1_1multipart_1_1message.html b/master/reference/structcrow_1_1multipart_1_1message.html
index 33c2ac687..43c10a978 100644
--- a/master/reference/structcrow_1_1multipart_1_1message.html
+++ b/master/reference/structcrow_1_1multipart_1_1message.html
@@ -134,10 +134,10 @@
std::string dump (int part_) const |
| Represent an individual part as a string.
|
|
-
- | message (const ci_map &headers, const std::string &boundary, const std::vector< part > §ions) |
- | Default constructor using default values.
|
- |
+
+ | message (const ci_map &headers_, const std::string &boundary_, const std::vector< part > §ions) |
+ | Default constructor using default values.
|
+ |
| message (const request &req) |
| Create a multipart message from a request data.
|
diff --git a/master/reference/structcrow_1_1multipart_1_1message.js b/master/reference/structcrow_1_1multipart_1_1message.js
index 538ea81d3..83f88bedc 100644
--- a/master/reference/structcrow_1_1multipart_1_1message.js
+++ b/master/reference/structcrow_1_1multipart_1_1message.js
@@ -1,6 +1,6 @@
var structcrow_1_1multipart_1_1message =
[
- [ "message", "structcrow_1_1multipart_1_1message.html#a0007fa0cadffae1a8d16fac169d1527b", null ],
+ [ "message", "structcrow_1_1multipart_1_1message.html#a04ffb20817903d00334268d31f635621", null ],
[ "message", "structcrow_1_1multipart_1_1message.html#a32946a0f39a8d024aaf4643116a7561b", null ],
[ "dump", "structcrow_1_1multipart_1_1message.html#adac4c7af1a5d0eb66c2accbaf80e0196", null ],
[ "dump", "structcrow_1_1multipart_1_1message.html#abeeebf36687f9cbdf06a6521eac1ce33", null ],
diff --git a/master/reference/structcrow_1_1multipart_1_1message__view-members.html b/master/reference/structcrow_1_1multipart_1_1message__view-members.html
index 71e35ed20..9df7a17fd 100644
--- a/master/reference/structcrow_1_1multipart_1_1message__view-members.html
+++ b/master/reference/structcrow_1_1multipart_1_1message__view-members.html
@@ -108,7 +108,7 @@
get_header_value(const std::string &key) const (defined in crow::multipart::message_view) | crow::multipart::message_view | inline |
get_part_by_name(const std::string_view name) (defined in crow::multipart::message_view) | crow::multipart::message_view | inline |
headers | crow::multipart::message_view | |
- message_view(const ci_map &headers, const std::string &boundary, const std::vector< part_view > §ions) | crow::multipart::message_view | inline |
+ message_view(const ci_map &headers_, const std::string &boundary_, const std::vector< part_view > §ions) | crow::multipart::message_view | inline |
message_view(const request &req) | crow::multipart::message_view | inlineexplicit |
operator<< (defined in crow::multipart::message_view) | crow::multipart::message_view | friend |
part_map | crow::multipart::message_view | |
diff --git a/master/reference/structcrow_1_1multipart_1_1message__view.html b/master/reference/structcrow_1_1multipart_1_1message__view.html
index 12baf32e3..7948a5ca9 100644
--- a/master/reference/structcrow_1_1multipart_1_1message__view.html
+++ b/master/reference/structcrow_1_1multipart_1_1message__view.html
@@ -126,10 +126,10 @@
std::string dump (int part_) const |
| Represent an individual part as a string.
|
|
-
- | message_view (const ci_map &headers, const std::string &boundary, const std::vector< part_view > §ions) |
- | Default constructor using default values.
|
- |
+
+ | message_view (const ci_map &headers_, const std::string &boundary_, const std::vector< part_view > §ions) |
+ | Default constructor using default values.
|
+ |
| message_view (const request &req) |
| Create a multipart message from a request data.
|
diff --git a/master/reference/structcrow_1_1multipart_1_1message__view.js b/master/reference/structcrow_1_1multipart_1_1message__view.js
index 3f5cbeec4..8bd0a4b92 100644
--- a/master/reference/structcrow_1_1multipart_1_1message__view.js
+++ b/master/reference/structcrow_1_1multipart_1_1message__view.js
@@ -1,6 +1,6 @@
var structcrow_1_1multipart_1_1message__view =
[
- [ "message_view", "structcrow_1_1multipart_1_1message__view.html#ae01a2e1676ca9d22d625200df14b88fe", null ],
+ [ "message_view", "structcrow_1_1multipart_1_1message__view.html#ab2985a84afde169fb89fc35e430106db", null ],
[ "message_view", "structcrow_1_1multipart_1_1message__view.html#ad0a498ccdfea67c512d5cb23f62c4f1c", null ],
[ "dump", "structcrow_1_1multipart_1_1message__view.html#ad12d2270b477b231c9ff53d40bad9d60", null ],
[ "dump", "structcrow_1_1multipart_1_1message__view.html#a93b1d69b8688d153ed0949ad6dc527fc", null ],
diff --git a/master/reference/structcrow_1_1multipart_1_1padded-members.html b/master/reference/structcrow_1_1multipart_1_1padded-members.html
index 2d94d8247..ef50260b5 100644
--- a/master/reference/structcrow_1_1multipart_1_1padded-members.html
+++ b/master/reference/structcrow_1_1multipart_1_1padded-members.html
@@ -102,7 +102,7 @@
This is the complete list of members for crow::multipart::padded, including all inherited members.
diff --git a/master/reference/structcrow_1_1multipart_1_1padded.html b/master/reference/structcrow_1_1multipart_1_1padded.html
index a97edc122..59614bf81 100644
--- a/master/reference/structcrow_1_1multipart_1_1padded.html
+++ b/master/reference/structcrow_1_1multipart_1_1padded.html
@@ -122,10 +122,10 @@
|
-
-std::ostream & | operator<< (std::ostream &stream, const padded value) |
- | Outputs padded value to the stream.
|
- |
+
+std::ostream & | operator<< (std::ostream &stream, const padded value_) |
+ | Outputs padded value to the stream.
|
+ |
String padded with the specified padding (double quotes by default)
diff --git a/master/reference/structcrow_1_1multipart_1_1padded.js b/master/reference/structcrow_1_1multipart_1_1padded.js
index 57d88c309..2ac256935 100644
--- a/master/reference/structcrow_1_1multipart_1_1padded.js
+++ b/master/reference/structcrow_1_1multipart_1_1padded.js
@@ -1,6 +1,6 @@
var structcrow_1_1multipart_1_1padded =
[
- [ "operator<<", "structcrow_1_1multipart_1_1padded.html#a27b10196d6f596db53102988da72e47e", null ],
+ [ "operator<<", "structcrow_1_1multipart_1_1padded.html#a65a7ba8beab915313c5d078727151776", null ],
[ "padding", "structcrow_1_1multipart_1_1padded.html#a6e434697fc61b09cdd15953d5260c746", null ],
[ "value", "structcrow_1_1multipart_1_1padded.html#a3198bf9ee11e1c8e9e84a5880898e85b", null ]
];
\ No newline at end of file
diff --git a/master/reference/structcrow_1_1mustache_1_1_action-members.html b/master/reference/structcrow_1_1mustache_1_1_action-members.html
index 91566c165..76c9381fa 100644
--- a/master/reference/structcrow_1_1mustache_1_1_action-members.html
+++ b/master/reference/structcrow_1_1mustache_1_1_action-members.html
@@ -102,7 +102,7 @@
This is the complete list of members for crow::mustache::Action, including all inherited members.
- Action(ActionType t, size_t start, size_t end, size_t pos=0) (defined in crow::mustache::Action) | crow::mustache::Action | inline |
+ Action(ActionType t_, size_t start_, size_t end_, size_t pos_=0) (defined in crow::mustache::Action) | crow::mustache::Action | inline |
end (defined in crow::mustache::Action) | crow::mustache::Action | |
pos (defined in crow::mustache::Action) | crow::mustache::Action | |
start (defined in crow::mustache::Action) | crow::mustache::Action | |
diff --git a/master/reference/structcrow_1_1mustache_1_1_action.html b/master/reference/structcrow_1_1mustache_1_1_action.html
index e748a77bc..36116b6bb 100644
--- a/master/reference/structcrow_1_1mustache_1_1_action.html
+++ b/master/reference/structcrow_1_1mustache_1_1_action.html
@@ -111,9 +111,9 @@
|
-
- | Action (ActionType t, size_t start, size_t end, size_t pos=0) |
- |
+
+ | Action (ActionType t_, size_t start_, size_t end_, size_t pos_=0) |
+ |
|
diff --git a/master/reference/structcrow_1_1mustache_1_1_action.js b/master/reference/structcrow_1_1mustache_1_1_action.js
index 8d9a210f4..02c28fa71 100644
--- a/master/reference/structcrow_1_1mustache_1_1_action.js
+++ b/master/reference/structcrow_1_1mustache_1_1_action.js
@@ -1,6 +1,6 @@
var structcrow_1_1mustache_1_1_action =
[
- [ "Action", "structcrow_1_1mustache_1_1_action.html#abdd01c3d42e0b9943cc07cc511cb972c", null ],
+ [ "Action", "structcrow_1_1mustache_1_1_action.html#ab6d29322c7a78ea25a115ae1db1ae7c1", null ],
[ "end", "structcrow_1_1mustache_1_1_action.html#ac0daea6290bb2ca9c9c87c3fb163ce7d", null ],
[ "pos", "structcrow_1_1mustache_1_1_action.html#a1af3f38c04cdc0978c2a788eeda81eab", null ],
[ "start", "structcrow_1_1mustache_1_1_action.html#a643c89b2d81bfc2d2eedfca0cb119068", null ],
diff --git a/master/reference/structcrow_1_1request-members.html b/master/reference/structcrow_1_1request-members.html
index cf11506ba..aff3f9b27 100644
--- a/master/reference/structcrow_1_1request-members.html
+++ b/master/reference/structcrow_1_1request-members.html
@@ -121,7 +121,7 @@
raw_url | crow::request | |
remote_ip_address | crow::request | |
request() | crow::request | inline |
- request(HTTPMethod method, std::string raw_url, std::string url, query_string url_params, ci_map headers, std::string body, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade) | crow::request | inline |
+ request(HTTPMethod method_, std::string raw_url_, std::string url_, query_string url_params_, ci_map headers_, std::string body_, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade) | crow::request | inline |
upgrade | crow::request | |
url | crow::request | |
url_params | crow::request | |
diff --git a/master/reference/structcrow_1_1request.html b/master/reference/structcrow_1_1request.html
index 63b20f39b..d83b8e4f6 100644
--- a/master/reference/structcrow_1_1request.html
+++ b/master/reference/structcrow_1_1request.html
@@ -115,10 +115,10 @@
request () |
| Construct an empty request. (sets the method to GET )
|
|
-
- | request (HTTPMethod method, std::string raw_url, std::string url, query_string url_params, ci_map headers, std::string body, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade) |
- | 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_, unsigned char http_major, unsigned char http_minor, bool has_keep_alive, bool has_close_connection, bool is_upgrade) |
+ | Construct a request with all values assigned.
|
+ |
void | add_header (std::string key, std::string value) |
|
diff --git a/master/reference/structcrow_1_1request.js b/master/reference/structcrow_1_1request.js
index 243ae8363..35769a6a7 100644
--- a/master/reference/structcrow_1_1request.js
+++ b/master/reference/structcrow_1_1request.js
@@ -1,7 +1,7 @@
var structcrow_1_1request =
[
[ "request", "structcrow_1_1request.html#a838c9a8c9a5eb2283d57e66f3630b5a6", null ],
- [ "request", "structcrow_1_1request.html#a111b70ddb2a100a79415b539e152e145", null ],
+ [ "request", "structcrow_1_1request.html#ab90c2762f152a7d58a1ab8ea55e0afd0", null ],
[ "add_header", "structcrow_1_1request.html#a98b85749921fc63e57d6ea891fe17391", null ],
[ "check_version", "structcrow_1_1request.html#ac369309c6be61c011b93a5b8cf14515a", null ],
[ "dispatch", "structcrow_1_1request.html#ac3e72e3fe415c68618dee999e3984160", null ],
diff --git a/master/reference/structcrow_1_1response-members.html b/master/reference/structcrow_1_1response-members.html
index 5c1819e2e..f61adfe87 100644
--- a/master/reference/structcrow_1_1response-members.html
+++ b/master/reference/structcrow_1_1response-members.html
@@ -124,16 +124,16 @@
redirect(const std::string &location) | crow::response | inline |
redirect_perm(const std::string &location) | crow::response | inline |
response() (defined in crow::response) | crow::response | inline |
- response(int code) (defined in crow::response) | crow::response | inlineexplicit |
- response(std::string body) (defined in crow::response) | crow::response | inline |
- response(int code, std::string body) (defined in crow::response) | crow::response | inline |
+ response(int code_) (defined in crow::response) | crow::response | inlineexplicit |
+ response(std::string body_) (defined in crow::response) | crow::response | inline |
+ response(int code_, std::string body_) (defined in crow::response) | crow::response | inline |
response(returnable &&value) (defined in crow::response) | crow::response | inline |
response(returnable &value) (defined in crow::response) | crow::response | inline |
- response(int code, returnable &value) (defined in crow::response) | crow::response | inline |
- response(int code, returnable &&value) (defined in crow::response) | crow::response | inline |
+ response(int code_, returnable &value) (defined in crow::response) | crow::response | inline |
+ response(int code_, returnable &&value) (defined in crow::response) | crow::response | inline |
response(response &&r) (defined in crow::response) | crow::response | inline |
- response(std::string contentType, std::string body) (defined in crow::response) | crow::response | inline |
- response(int code, std::string contentType, std::string body) (defined in crow::response) | crow::response | inline |
+ response(std::string contentType, std::string body_) (defined in crow::response) | crow::response | inline |
+ response(int code_, std::string contentType, std::string body_) (defined in crow::response) | crow::response | inline |
Router (defined in crow::response) | crow::response | friend |
set_header(std::string key, std::string value) | crow::response | inline |
set_static_file_info(std::string path) | crow::response | inline |
diff --git a/master/reference/structcrow_1_1response.html b/master/reference/structcrow_1_1response.html
index 1bda49371..5fe34d9c0 100644
--- a/master/reference/structcrow_1_1response.html
+++ b/master/reference/structcrow_1_1response.html
@@ -131,36 +131,36 @@
const std::string & | get_header_value (const std::string &key) |
|
-
- | response (int code) |
- |
-
- | response (std::string body) |
- |
-
- | response (int code, std::string body) |
- |
+
+ | response (int code_) |
+ |
+
+ | response (std::string body_) |
+ |
+
+ | response (int code_, std::string body_) |
+ |
| response (returnable &&value) |
|
| response (returnable &value) |
|
-
- | response (int code, returnable &value) |
- |
-
- | response (int code, returnable &&value) |
- |
+
+ | response (int code_, returnable &value) |
+ |
+
+ | response (int code_, returnable &&value) |
+ |
| response (response &&r) |
|
-
- | response (std::string contentType, std::string body) |
- |
-
- | response (int code, std::string contentType, std::string body) |
- |
+
+ | response (std::string contentType, std::string body_) |
+ |
+
+ | response (int code_, std::string contentType, std::string body_) |
+ |
response & | operator= (const response &r)=delete |
|
diff --git a/master/reference/structcrow_1_1response.js b/master/reference/structcrow_1_1response.js
index cf79e7300..d54e70752 100644
--- a/master/reference/structcrow_1_1response.js
+++ b/master/reference/structcrow_1_1response.js
@@ -2,16 +2,16 @@ var structcrow_1_1response =
[
[ "static_file_info", "structcrow_1_1response_1_1static__file__info.html", "structcrow_1_1response_1_1static__file__info" ],
[ "response", "structcrow_1_1response.html#a0f4955bc5dc914d698cff5e83bca1cdb", null ],
- [ "response", "structcrow_1_1response.html#a52e2658b1d16dcf106ed138b6396696b", null ],
- [ "response", "structcrow_1_1response.html#aab7485cb8f0efa3fcf062118476edfd5", null ],
- [ "response", "structcrow_1_1response.html#aeee8e7dd021783524bae9bd8775bae0f", null ],
+ [ "response", "structcrow_1_1response.html#aa2b9fa69bcdc21f244e0e8f7c0b13bbc", null ],
+ [ "response", "structcrow_1_1response.html#a19aa374c89c379d50ccae959c09e8d30", null ],
+ [ "response", "structcrow_1_1response.html#a808aae9110e1e3a5ca7b3fa3a43881c2", null ],
[ "response", "structcrow_1_1response.html#a693fd3f57d926251918b16a6f20be474", null ],
[ "response", "structcrow_1_1response.html#a70c56fc6910c94f42accb77a45d5686e", null ],
- [ "response", "structcrow_1_1response.html#a37aaf5b69473066fe8bcf302e9ba4580", null ],
- [ "response", "structcrow_1_1response.html#a3b9bfae36855265ddc1a64c78d0caf8e", null ],
+ [ "response", "structcrow_1_1response.html#a87339aace851e4fcabcd5f61cf58f0fd", null ],
+ [ "response", "structcrow_1_1response.html#a126da3d75afaa53b195a02c8e4b03806", null ],
[ "response", "structcrow_1_1response.html#abd924a9b90dfb505804fe4cf791768a3", null ],
- [ "response", "structcrow_1_1response.html#ac7f3e75d48f2082a93e366d31298eb72", null ],
- [ "response", "structcrow_1_1response.html#a58dd09e8a9b3f1d86fe9d676757c8a2c", null ],
+ [ "response", "structcrow_1_1response.html#a6a1bcececde5a88e43ac5bb4d069d09f", null ],
+ [ "response", "structcrow_1_1response.html#a178201cdeeea4bd7d2ddd97d72e0f293", null ],
[ "add_header", "structcrow_1_1response.html#a16d1a8bcec6460ba97f90b80881693b8", null ],
[ "clear", "structcrow_1_1response.html#a068269fc8b7f1df3d5421ccd384fe1f3", null ],
[ "end", "structcrow_1_1response.html#abef42200eca49c70dc1f5140ee3603ab", null ],
diff --git a/master/reference/utility_8h_source.html b/master/reference/utility_8h_source.html
index 0d8c2fb26..8bf29d604 100644
--- a/master/reference/utility_8h_source.html
+++ b/master/reference/utility_8h_source.html
@@ -743,9 +743,9 @@
644 else if (size >= 2 && data[size - 2] ==
'=')
- 645 size = (size / 4 * 3) - 2;
+ 645 size = (size / 4 * 3) - 2;
646 else if (size >= 1 && data[size - 1] ==
'=')
- 647 size = (size / 4 * 3) - 1;
+ 647 size = (size / 4 * 3) - 1;
@@ -825,7 +825,7 @@
- 727 auto sanitizeSpecialFile = [](std::string& source,
unsigned ofs,
const char* pattern,
bool includeNumber,
char replacement) {
+ 727 auto sanitizeSpecialFile = [](std::string& source,
unsigned ofs,
const char* pattern,
bool includeNumber,
char replacement_) {
729 size_t len = source.length();
730 const char* p = pattern;
@@ -844,7 +844,7 @@
743 if ((i >= len) || (source[i] ==
'.') || (source[i] ==
':') || (source[i] ==
'/') || (source[i] ==
'\\'))
745 source.erase(ofs + 1, (i - ofs) - 1);
- 746 source[ofs] = replacement;
+ 746 source[ofs] = replacement_;
749 bool checkForSpecialEntries =
true;
@@ -1035,7 +1035,7 @@
- 937 template <
typename Iter1,
typename Iter2>
+ 937 template<
typename Iter1,
typename Iter2>
938 inline static Iter1 find_first_of(Iter1 first1, Iter1 last1, Iter2 first2, Iter2 last2)
940 for (; first1 != last1; ++first1)