/////////////////////////////////////////////////////////////////////////////// // // Copyright (C) 2008-2012 Artyom Beilis (Tonkikh) // // See accompanying file COPYING.TXT file for licensing details. // /////////////////////////////////////////////////////////////////////////////// #ifndef CPPCMS_HTTP_RESPONSE_H #define CPPCMS_HTTP_RESPONSE_H #include #include #include #include #include #include namespace booster{ namespace system { class error_code; } } namespace cppcms { class cache_interface; namespace impl { namespace cgi { class connection; }} namespace http { class context; class cookie; /// /// \brief this class represents all HTTP/CGI response related API, generation of output content and /// HTTP headers. /// class CPPCMS_API response : public booster::noncopyable { public: /// /// This type represent the enum of HTTP Status type as of RFC 2616 sec. 6.1.1 /// typedef enum { continue_transfer = 100, switching_protocol = 101, ok = 200, created = 201, accepted = 202, non_authoritative_information = 203, no_content = 204, reset_content = 205, partial_content = 206, multiple_choices = 300, moved_permanently = 301, found = 302, see_other = 303, not_modified = 304, use_proxy = 305, temporary_redirect = 307, bad_request = 400, unauthorized = 401, payment_required = 402, forbidden = 403, not_found = 404, method_not_allowed = 405, not_acceptable = 406, proxy_authentication_required = 407, request_time_out = 408, conflict = 409, gone = 410, precondition_failed = 412, request_entity_too_large = 413, request_uri_too_large = 414, unsupported_media_type = 415, requested_range_not_satisfiable = 416, expectation_failed = 417, internal_server_error = 500, not_implemented = 501, bad_gateway = 502, service_unavailable = 503, gateway_timeout = 504, http_version_not_supported = 505 } status_type; /// /// This enum represents different types of IO modes giving fine grained control over HTTP output. /// /// These modes are set via io_mode member function /// typedef enum { normal, ///< Synchronous IO. Write the request, it is buffered and possible compressed using gzip. nogzip, ///< Same as normal but disable gzip compression raw, ///< User has full control over the output, it is also fully responsible for generation ///< of HTTP headers, no-session management given. asynchronous, ///< In this mode the data is buffered and never transferred unless it is requested by async_flush_output, ///< or async_complete_response member functions of http::context explicitly. asynchronous_raw ///< Same as asynchronous but the user is responsible for generation of its own HTTP headers. } io_mode_type; // Standard HTTP Response Headers RFC 2616 /// /// Set HTTP Header Accept-Ranges /// void accept_ranges(std::string const &); /// /// Set HTTP Header Age /// void age(unsigned seconds); /// /// Set HTTP Header Allow /// void allow(std::string const &); /// /// Set HTTP Header Cache-Control /// void cache_control(std::string const &); /// /// Set HTTP Header Content-Encoding. /// /// Note: if you set this header manually, gzip compression will be automatically disabled. /// void content_encoding(std::string const &); /// /// Set HTTP Header Content-Language /// void content_language(std::string const &); /// /// Set HTTP Header Content-Length /// void content_length(unsigned long long len); /// /// Set HTTP Header Content-Location /// void content_location(std::string const &); /// /// Set HTTP Header Content-Md5 /// void content_md5(std::string const &); /// /// Set HTTP Header Content-Range /// void content_range(std::string const &); /// /// Set HTTP Header Content-Type /// void content_type(std::string const &); /// /// Set HTTP Header Date /// void date(time_t); /// /// Set HTTP Header Etag /// void etag(std::string const &); /// /// Set HTTP Header Expires, it is formatted as HTTP Date-Time from the POSIX time \a t /// void expires(time_t t); /// /// Set HTTP Header Last-Modified, it is formatted as HTTP Date-Time from the POSIX time \a t /// void last_modified(time_t t); /// /// Set HTTP Header Location /// void location(std::string const &); /// /// Set HTTP Header Pragma /// void pragma(std::string const &); /// /// Set HTTP Header Proxy-Authenticate /// void proxy_authenticate(std::string const &); /// /// Set HTTP Header Retry-After /// void retry_after(std::string const &); /// /// Set HTTP Header Retry-After /// void retry_after(unsigned); /// /// Set GCI Status Header, the message is created according to the code automatically /// void status(int code); /// /// Set HTTP Header Status with the status code \a code and a custom \a message /// void status(int code,std::string const &message); /// /// Set HTTP Header Trailer /// void trailer(std::string const &); /// /// Set HTTP Header Transfer-Encoding, note /// void transfer_encoding(std::string const &); /// /// Set HTTP Header Vary /// void vary(std::string const &); /// /// Set HTTP Header Via /// void via(std::string const &); /// /// Set HTTP Header Warning /// void warning(std::string const &); /// /// Set HTTP Header WWW-Authenticate /// void www_authenticate(std::string const &); /// /// Set Generic HTTP header "name: value" /// void set_header(std::string const &name,std::string const &value); /// /// Get output header value, returns empty string if it is not set /// std::string get_header(std::string const &name); /// /// Erase specific header \a h /// void erase_header(std::string const &h); /// /// add header - independently of set_header/get_header/erase_header - allows /// to specify multiple headers of same type like Set-Cookie or WWW-Authenticate /// /// \ver{v1_2} void add_header(std::string const &name,std::string const &value); /// /// This function set HTTP Content-Type header, but unlike contet_type function it also adds /// current locale charset encoding (unless localization.disable_charset_in_content_type set to true in configuration) /// void set_content_header(std::string const &content_type); /// /// Shortcut to set_content_header("text/html") - this is the default content-type header /// void set_html_header(); /// /// Shortcut to set_content_header("text/xhtml") /// void set_xhtml_header(); /// /// Shortcut to set_content_header("text/plain") /// void set_plain_text_header(); /// /// Redirect to other \a location by setting HTTP Location header and a Status header with a status \a status /// void set_redirect_header(std::string const &location,int status = found); /// /// Set HTTP Cookie /// void set_cookie(cookie const &); /// /// This creates a default HTTP response (including HTML body) with a status \a stat a message \a msg. /// /// Note: if \a msg is empty default message for HTTP Status code \a stat is used. /// void make_error_response(int stat,std::string const &msg = std::string()); /// /// Get current io_mode, see a description for io_mode_type. /// io_mode_type io_mode(); /// /// Set current io_mode, see a description for io_mode_type. /// /// Note: you can't change it after requesting for output stream, i.e. calling out() member function. /// void io_mode(io_mode_type); /// /// Request an output stream to write the body of HTTP response after writing headers. /// /// Note: /// /// - it triggers saving changes in the session, so further changes will have no effect. /// - it triggers writing all headers to output stream, such that changing any header or adding cookies will have no effect. /// - it is impossible to change an io_mode after calling this function. /// std::ostream &out(); /// /// Create an HTTP time string from POSIX time as of RFC 2616 /// static std::string make_http_time(time_t); /// /// Return a string that represents a message for HTTP status code \a status /// static char const *status_to_string(int status); /// /// Check if out() member function was called, (so it is impossible to do some tasks like changing HTTP headers. /// See out description for more details /// bool some_output_was_written(); /// /// Finalize an output request. Generally this function is called automatically for synchronous application, however /// when working with asynchronous requests you should call this function before calling async_complete_response. /// void finalize(); /// /// Defines the size of the output buffer for the output data. /// /// Setting the to 0 makes the output non-buffered and prevents unnecessary copy of large objects in memory /// /// The default is defined in configuration by service.output_buffer_size and service.async_output_buffer_size for synchronous and asynchronous /// applications accordingly, can be called before and after out() was called /// /// Calling with negative value would reset it to the default /// /// Note: when gzip compression active, buffering is still present at intermediate levels /// /// \ver{v1_2} void setbuf(int buffer_size); /// /// Sets full buffering mode for asynchronous applications /// /// When set to true the output data is transferred only when async_flush_output or async_complete_response are called this /// is the default behavior. /// /// When set to false, the data is sent upon flushing of the std::ostream provided by out(). If I/O operation blocks, /// the actual output is buffered, it is possible to test if blocking occurred by calling pending_blocked_output() /// /// When the full buffering is disable, if an error occurs, the out() is set to fail state. /// /// \ver{v1_2} void full_asynchronous_buffering(bool enable); /// /// Get current state of asynchronous buffering /// /// \ver{v1_2} bool full_asynchronous_buffering(); /// /// Returns true of some of the output wasn't sent due to blocking upon flushing of std::stream &out() which is used together with full_asynchronous_buffering(false) mode. /// /// Note: it does not look on to internal buffers thus it is user's responsibility to call /// /// Once the condition occurs you can flush the output asynchronously using async_complete_response or async_flush_output /// /// \ver{v1_2} bool pending_blocked_output(); /// \cond INTERNAL response(context &); ~response(); /// \endcond private: friend class impl::cgi::connection; friend class ::cppcms::cache_interface; void copy_to_cache(); std::string copied_data(); bool need_gzip(); std::pair output(); void write_http_headers(std::ostream &); int flush_async_chunk(booster::system::error_code &e); struct _data; booster::hold_ptr<_data> d; context &context_; std::ostream *stream_; io_mode_type io_mode_; uint32_t disable_compression_ : 1; uint32_t ostream_requested_ : 1; uint32_t copy_to_cache_ : 1; uint32_t finalized_ : 1; uint32_t reserved_ : 28; }; } /* http */ } /* cppcms */ #endif