diff --git a/include/ircd/http.h b/include/ircd/http.h index 60126dc80..f548de86a 100644 --- a/include/ircd/http.h +++ b/include/ircd/http.h @@ -262,6 +262,7 @@ struct ircd::http::request::head struct ircd::http::response { struct head; + struct chunk; // compose a response into buffer response(window_buffer &, @@ -291,6 +292,15 @@ struct ircd::http::response::head head() = default; }; +struct ircd::http::response::chunk +:line +{ + size_t size {0}; + + chunk(parse::capstan &pc); + chunk() = default; +}; + template T ircd::http::query::string::get(const string_view &key, diff --git a/ircd/http.cc b/ircd/http.cc index 44d678a37..749bf7409 100644 --- a/ircd/http.cc +++ b/ircd/http.cc @@ -19,7 +19,7 @@ namespace ircd::http extern const std::unordered_map reason; - [[noreturn]] void throw_error(const qi::expectation_failure &); + [[noreturn]] void throw_error(const qi::expectation_failure &, const bool &internal = false); } BOOST_FUSION_ADAPT_STRUCT @@ -675,19 +675,41 @@ ircd::http::writeline(window_buffer &write) }); } +/// Called to translate a grammar exception into an http::error within our +/// system. This will then usually propagate back to our client. +/// +/// If we are a client to another server, set internal=true. Even though this +/// still generates an HTTP error, the code is 500 so if it propagates back to +/// a client it does not indicate to *that* client that *they* made a bad +/// request from a 400 back to them. void -ircd::http::throw_error(const qi::expectation_failure &e) +ircd::http::throw_error(const qi::expectation_failure &e, + const bool &internal) { - const auto rule + const auto &code_ + { + internal? + code::INTERNAL_SERVER_ERROR: + code::BAD_REQUEST + }; + + const char *const &fmtstr + { + internal? + "I expected a valid HTTP %s. Server sent %zu invalid characters starting with `%s'.": + "I require a valid HTTP %s. You sent %zu invalid characters starting with `%s'." + }; + + const auto &rule { ircd::string(e.what_) }; throw error { - code::BAD_REQUEST, fmt::snstringf + code_, fmt::snstringf { - 512, "I require a valid HTTP %s. You sent %zu invalid characters starting with `%s'.", + 512, fmtstr, between(rule, "<", ">"), size_t(e.last - e.first), string_view{e.first, e.last}