// -*- mode: c++; c-basic-offset: 2; -*- #ifndef HTTP_HH #define HTTP_HH #include #include #include // 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() {} virtual bool valid() const = 0; virtual std::string name() const = 0; virtual bool name_equal(std::string const& name) const = 0; virtual std::string value() const = 0; virtual void next() = 0; protected: HeaderIterator() {} HeaderIterator(HeaderIterator const&) = delete; }; class HeaderTokenIterator { public: virtual ~HeaderTokenIterator() {} virtual bool valid() const = 0; virtual std::string token() const = 0; virtual bool token_equal(std::string const& name) const = 0; virtual void next() = 0; protected: HeaderTokenIterator() {} HeaderTokenIterator(HeaderTokenIterator const&) = delete; }; class Http { public: virtual ~Http() {} virtual bool good() const = 0; virtual std::string proto() const = 0; virtual bool proto_equal(std::string const& proto) const = 0; virtual Version proto_version() const = 0; virtual std::unique_ptr header() const = 0; virtual std::unique_ptr header( std::string const& name) const = 0; std::string first_header(std::string const& name) const; virtual std::unique_ptr header_tokens( std::string const& name) const = 0; virtual char const* data() const = 0; virtual size_t size() const = 0; protected: Http() {} Http(Http const&) = delete; }; class HttpResponse : public virtual Http { public: virtual ~HttpResponse() {} static HttpResponse* parse(std::string const& data); static HttpResponse* parse(char const* data, size_t len, bool copy = true); static HttpResponse* parse(std::shared_ptr data, size_t offset, size_t len); virtual uint16_t status_code() const = 0; virtual std::string status_message() const = 0; protected: HttpResponse() {} HttpResponse(HttpResponse const&) = delete; }; class HttpRequest : public virtual Http { public: virtual ~HttpRequest() {} static HttpRequest* parse(std::string const& data); static HttpRequest* parse(char const* data, size_t len, bool copy = true); static HttpRequest* parse(std::shared_ptr data, size_t offset, size_t len); virtual std::string method() const = 0; virtual bool method_equal(std::string const& method) const = 0; virtual std::string url() const = 0; virtual bool url_equal(std::string const& url) const = 0; protected: HttpRequest() {} HttpRequest(HttpRequest const&) = delete; }; class HttpResponseBuilder { public: virtual ~HttpResponseBuilder() {} static HttpResponseBuilder* create( std::string const& proto, Version version, uint16_t status_code, std::string const& status_message); virtual void add_header(std::string const& name, std::string const& value) = 0; // This will add a content-length header unless there already is one virtual void set_content(std::string const& content) = 0; virtual std::string build() const = 0; protected: HttpResponseBuilder() {} HttpResponseBuilder(HttpResponseBuilder const&) = delete; }; class HttpRequestBuilder { public: virtual ~HttpRequestBuilder() {} static HttpRequestBuilder* create( std::string const& method, std::string const& url, std::string const& proto, Version version); virtual void add_header(std::string const& name, std::string const& value) = 0; // This will add a content-length header unless there already is one virtual void set_content(std::string const& content) = 0; virtual std::string build() const = 0; protected: HttpRequestBuilder() {} HttpRequestBuilder(HttpRequestBuilder const&) = delete; }; #endif // HTTP_HH