// file : web/apache/request -*- C++ -*- // copyright : Copyright (c) 2014-2016 Code Synthesis Ltd // license : MIT; see accompanying LICENSE file #ifndef WEB_APACHE_REQUEST #define WEB_APACHE_REQUEST #include // request_rec, HTTP_*, OK, M_POST #include #include // unique_ptr #include #include #include #include #include #include namespace web { namespace apache { // The state of the request processing, reflecting an interaction with // Apache API (like reading/writing content function calls), with no // buffering taken into account. Any state different from the initial // suppose that some irrevocable interaction with Apache API have // happened, so request processing should be either completed, or // reported as failed. State values are ordered in a sense that the // higher value reflects the more advanced stage of processing, so the // request current state value may not decrease. // enum class request_state { // Denotes the initial stage of the request handling. At this stage // the request line and headers are already parsed by Apache. // initial, // Reading the request content. // reading, // Adding the response headers (cookies in particular). // headers, // Writing the response content. // writing }; class request: public web::request, public web::response, public stream_state { friend class service; request (request_rec* rec) noexcept : rec_ (rec) { rec_->status = HTTP_OK; } request_state state () const noexcept {return state_;} // Flush the buffered response content if present. The returned value // should be passed to Apache API on request handler exit. // int flush (); // Prepare for the request re-processing if possible (no unbuffered // read/write operations have been done). Throw sequence_error // otherwise. In particular, the preparation can include the response // content buffer cleanup, the request content buffer rewind. // void rewind (); // Get request path. // virtual const path_type& path (); // Get request body data stream. // virtual std::istream& content (bool buffer = false); // Get request parameters. // virtual const name_values& parameters (); // Get request cookies. // virtual const name_values& cookies (); // Get response status code. // status_code status () const noexcept {return rec_->status;} // Set response status code. // virtual void status (status_code status); // Set response status code, content type and get body stream. // virtual std::ostream& content (status_code status, const std::string& type, bool buffer = true); // Add response cookie. // virtual void cookie (const char* name, const char* value, const std::chrono::seconds* max_age = nullptr, const char* path = nullptr, const char* domain = nullptr, bool secure = false, bool buffer = true); private: // Get application/x-www-form-urlencoded form data. // const std::string& form_data (); void parse_parameters (const char* args); // Advance the request processing state. Noop if new state is equal to // the current one. Throw sequence_error if the new state is less then // the current one. Can throw invalid_request if HTTP request is // malformed. // void state (request_state); // stream_state members implementation. // virtual void set_read_state () {state (request_state::reading);} virtual void set_write_state () {state (request_state::writing);} private: request_rec* rec_; request_state state_ = request_state::initial; path_type path_; std::unique_ptr parameters_; std::unique_ptr cookies_; std::unique_ptr form_data_; std::unique_ptr in_buf_; std::unique_ptr in_; std::unique_ptr out_buf_; std::unique_ptr out_; }; } } #include #endif // WEB_APACHE_REQUEST