Line data Source code
1 : #pragma once 2 : 3 : #include <memory> 4 : 5 : #include "source/common/http/http1/parser.h" 6 : 7 : #include "absl/base/attributes.h" 8 : #include "quiche/balsa/balsa_enums.h" 9 : #include "quiche/balsa/balsa_frame.h" 10 : #include "quiche/balsa/balsa_headers.h" 11 : #include "quiche/balsa/balsa_visitor_interface.h" 12 : 13 : namespace Envoy { 14 : namespace Http { 15 : namespace Http1 { 16 : 17 : // This class wraps BalsaFrame and BalsaHeaders into a Parser implementation 18 : // to be used by ConnectionImpl. 19 : class BalsaParser : public Parser, public quiche::BalsaVisitorInterface { 20 : public: 21 : BalsaParser(MessageType type, ParserCallbacks* connection, size_t max_header_length, 22 : bool enable_trailers, bool allow_custom_methods); 23 1571 : ~BalsaParser() override = default; 24 : 25 : // Http1::Parser implementation 26 : size_t execute(const char* slice, int len) override; 27 : void resume() override; 28 : CallbackResult pause() override; 29 : ParserStatus getStatus() const override; 30 : Http::Code statusCode() const override; 31 : bool isHttp11() const override; 32 : absl::optional<uint64_t> contentLength() const override; 33 : bool isChunked() const override; 34 : absl::string_view methodName() const override; 35 : absl::string_view errorMessage() const override; 36 : int hasTransferEncoding() const override; 37 : 38 : private: 39 : // quiche::BalsaVisitorInterface implementation 40 : // TODO(bnc): Encapsulate in a private object. 41 : void OnRawBodyInput(absl::string_view input) override; 42 : void OnBodyChunkInput(absl::string_view input) override; 43 : void OnHeaderInput(absl::string_view input) override; 44 : void OnTrailerInput(absl::string_view input) override; 45 : void OnTrailers(std::unique_ptr<quiche::BalsaHeaders> trailers) override; 46 : void ProcessHeaders(const quiche::BalsaHeaders& headers) override; 47 : void OnRequestFirstLineInput(absl::string_view line_input, absl::string_view method_input, 48 : absl::string_view request_uri, 49 : absl::string_view version_input) override; 50 : void OnResponseFirstLineInput(absl::string_view line_input, absl::string_view version_input, 51 : absl::string_view status_input, 52 : absl::string_view reason_input) override; 53 : void OnChunkLength(size_t chunk_length) override; 54 : void OnChunkExtensionInput(absl::string_view input) override; 55 : void OnInterimHeaders(std::unique_ptr<quiche::BalsaHeaders> headers) override; 56 : void HeaderDone() override; 57 : void ContinueHeaderDone() override; 58 : void MessageDone() override; 59 : void HandleError(quiche::BalsaFrameEnums::ErrorCode error_code) override; 60 : void HandleWarning(quiche::BalsaFrameEnums::ErrorCode error_code) override; 61 : 62 : // Shared implementation for ProcessHeaders() and OnTrailers(). 63 : void validateAndProcessHeadersOrTrailersImpl(const quiche::BalsaHeaders& headers, bool trailers); 64 : 65 : // Return ParserStatus::Error if `result` is CallbackResult::Error. 66 : // Return current value of `status_` otherwise. 67 : // Typical use would be `status_ = convertResult(result);` 68 : ABSL_MUST_USE_RESULT ParserStatus convertResult(CallbackResult result) const; 69 : 70 : quiche::BalsaFrame framer_; 71 : quiche::BalsaHeaders headers_; 72 : 73 : const MessageType message_type_ = MessageType::Request; 74 : ParserCallbacks* connection_ = nullptr; 75 : const bool enable_trailers_ = false; 76 : const bool allow_custom_methods_ = false; 77 : bool first_byte_processed_ = false; 78 : bool headers_done_ = false; 79 : ParserStatus status_ = ParserStatus::Ok; 80 : // An error message, often seemingly arbitrary to match http-parser behavior. 81 : absl::string_view error_message_; 82 : }; 83 : 84 : } // namespace Http1 85 : } // namespace Http 86 : } // namespace Envoy