#ifndef WEBCC_MESSAGE_H_ #define WEBCC_MESSAGE_H_ #include #include #include // for move() #include #include "webcc/common.h" #include "webcc/globals.h" namespace webcc { class Message; std::ostream& operator<<(std::ostream& os, const Message& message); // Base class for HTTP request and response messages. class Message { public: Message() : content_length_(kInvalidLength) { } virtual ~Message() = default; const std::string& start_line() const { return start_line_; } void set_start_line(const std::string& start_line) { start_line_ = start_line; } std::size_t content_length() const { return content_length_; } void set_content_length(std::size_t content_length) { content_length_ = content_length; } const std::string& content() const { return content_; } bool IsConnectionKeepAlive() const; void SetHeader(Header&& header) { headers_.Set(std::move(header.first), std::move(header.second)); } void SetHeader(const std::string& key, const std::string& value) { headers_.Set(key, value); } const std::string& GetHeader(const std::string& key, bool* existed = nullptr) const { return headers_.Get(key, existed); } bool HasHeader(const std::string& key) const { return headers_.Has(key); } ContentEncoding GetContentEncoding() const; // Return true if header Accept-Encoding contains "gzip". bool AcceptEncodingGzip() const; const ContentType& content_type() const { return content_type_; } // TODO: Set header? void SetContentType(const ContentType& content_type) { content_type_ = content_type; } void SetContentType(const std::string& content_type) { SetHeader(headers::kContentType, content_type); } // Example: SetContentType("application/json", "utf-8") void SetContentType(const std::string& media_type, const std::string& charset); void SetContent(std::string&& content, bool set_length); // Prepare payload. virtual void Prepare(); const Payload& payload() const { return payload_; } // Copy the exact payload to the given output stream. void CopyPayload(std::ostream& os) const; // Copy the exact payload to the given string. void CopyPayload(std::string* str) const; // Dump to output stream. void Dump(std::ostream& os, std::size_t indent = 0, const std::string& prefix = "") const; // Dump to string, only used by logger. std::string Dump(std::size_t indent = 0, const std::string& prefix = "") const; protected: void SetContentLength(std::size_t content_length) { content_length_ = content_length; SetHeader(headers::kContentLength, std::to_string(content_length)); } // Get the timestamp for HTTP Date header field. // E.g., Wed, 21 Oct 2015 07:28:00 GMT // See: https://tools.ietf.org/html/rfc7231#section-7.1.1.2 std::string GetTimestamp(); protected: std::string start_line_; std::string content_; ContentType content_type_; std::size_t content_length_; Headers headers_; // NOTE: The payload itself doesn't hold the memory! Payload payload_; }; } // namespace webcc #endif // WEBCC_MESSAGE_H_