#ifndef HTTP_PROTOCOL_HH #define HTTP_PROTOCOL_HH #include #include #include #include #include "buffer.hh" // glibc defines these even tho it shouldn't if you ask posix #ifdef major # undef major #endif #ifdef minor # undef minor #endif struct Version { uint16_t major; uint16_t minor; Version() : major(0), minor(0) { } Version(uint16_t major, uint16_t minor) : major(major), minor(minor) { } }; class HeaderIterator { public: virtual ~HeaderIterator() = default; virtual bool valid() const = 0; virtual std::string_view name() const = 0; virtual std::string value() const = 0; virtual void next() = 0; protected: HeaderIterator() = default; HeaderIterator(HeaderIterator const&) = delete; HeaderIterator& operator=(HeaderIterator const&) = delete; }; class HeaderTokenIterator { public: virtual ~HeaderTokenIterator() = default; virtual bool valid() const = 0; virtual std::string token() const = 0; virtual void next() = 0; protected: HeaderTokenIterator() = default; HeaderTokenIterator(HeaderTokenIterator const&) = delete; HeaderTokenIterator& operator=(HeaderTokenIterator const&) = delete; }; class HttpPackage { public: virtual ~HttpPackage() = default; virtual bool good() const = 0; virtual std::string_view proto() const = 0; virtual Version proto_version() const = 0; virtual std::unique_ptr header() const = 0; virtual std::unique_ptr header( std::string_view name) const = 0; std::string first_header(std::string_view name) const; virtual std::unique_ptr header_tokens( std::string_view name) const = 0; virtual size_t size() const = 0; protected: HttpPackage() = default; HttpPackage(HttpPackage const&) = delete; HttpPackage& operator=(HttpPackage const&) = delete; }; class HttpResponse : public virtual HttpPackage { public: virtual ~HttpResponse() = default; static std::unique_ptr parse(RoBuffer* buffer); virtual uint16_t status_code() const = 0; virtual std::string_view status_message() const = 0; protected: HttpResponse() = default; HttpResponse(HttpResponse const&) = delete; HttpResponse& operator=(HttpResponse const&) = delete; }; class HttpRequest : public virtual HttpPackage { public: virtual ~HttpRequest() = default; static std::unique_ptr parse(RoBuffer* buffer); virtual std::string_view method() const = 0; virtual std::string_view url() const = 0; protected: HttpRequest() = default; HttpRequest(HttpRequest const&) = delete; HttpRequest& operator=(HttpRequest const&) = delete; }; class HttpResponseBuilder { public: virtual ~HttpResponseBuilder() = default; static std::unique_ptr create( std::string proto, Version version, uint16_t status_code, std::string status_message); virtual void add_header(std::string name, std::string value) = 0; virtual bool build(Buffer* dst) const = 0; virtual size_t size() const = 0; protected: HttpResponseBuilder() = default; HttpResponseBuilder(HttpResponseBuilder const&) = delete; HttpResponseBuilder& operator=(HttpResponseBuilder const&) = delete; }; class HttpRequestBuilder { public: virtual ~HttpRequestBuilder() = default; static std::unique_ptr create( std::string method, std::string url, std::string proto, Version version); virtual void add_header(std::string name, std::string value) = 0; virtual bool build(Buffer* dst) const = 0; virtual size_t size() const = 0; protected: HttpRequestBuilder() = default; HttpRequestBuilder(HttpRequestBuilder const&) = delete; HttpRequestBuilder& operator=(HttpRequestBuilder const&) = delete; }; class CgiResponseBuilder { public: virtual ~CgiResponseBuilder() = default; static std::unique_ptr create(uint16_t status_code); virtual void add_header(std::string name, std::string value) = 0; virtual bool build(Buffer* dst) const = 0; virtual size_t size() const = 0; protected: CgiResponseBuilder() = default; CgiResponseBuilder(CgiResponseBuilder const&) = delete; CgiResponseBuilder& operator=(CgiResponseBuilder const&) = delete; }; std::string_view http_standard_message(uint16_t code); std::string http_date(time_t in); #endif // HTTP_PROTOCOL_HH