From 0b6b57f9acaa2ec648bf582ff67851331f8e6eef Mon Sep 17 00:00:00 2001 From: Karen Arutyunov Date: Mon, 14 Mar 2016 14:38:45 +0300 Subject: Use serializable transaction isolation level --- web/apache/request | 121 +++++++++++++++++++++++++++++++++-------------------- 1 file changed, 76 insertions(+), 45 deletions(-) (limited to 'web/apache/request') diff --git a/web/apache/request b/web/apache/request index ab69dff..9540561 100644 --- a/web/apache/request +++ b/web/apache/request @@ -5,23 +5,14 @@ #ifndef WEB_APACHE_REQUEST #define WEB_APACHE_REQUEST -#include +#include // request_rec, HTTP_*, OK, M_POST -#include -#include -#include - -#include #include #include // unique_ptr #include -#include #include #include -#include // move() #include -#include -#include #include #include @@ -30,23 +21,63 @@ 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 write_state + public stream_state { friend class service; - request (request_rec* rec) noexcept: rec_ (rec) {rec_->status = HTTP_OK;} + request (request_rec* rec) noexcept + : rec_ (rec) + { + rec_->status = HTTP_OK; + } + + request_state + state () const noexcept {return state_;} - // Flush of buffered content. + // Flush the buffered response content if present. The returned value + // should be passed to Apache API on request handler exit. // int flush (); - // Return true if content have been sent to the client, false otherwise. + // 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. // - bool - get_write_state () const noexcept {return write_state_;} + void + rewind (); // Get request path. // @@ -56,7 +87,7 @@ namespace web // Get request body data stream. // virtual std::istream& - content (); + content (bool buffer = false); // Get request parameters. // @@ -70,7 +101,8 @@ namespace web // Get response status code. // - status_code status () const noexcept {return rec_->status;} + status_code + status () const noexcept {return rec_->status;} // Set response status code. // @@ -89,10 +121,11 @@ namespace web virtual void cookie (const char* name, const char* value, - const std::chrono::seconds* max_age = 0, - const char* path = 0, - const char* domain = 0, - bool secure = false); + 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. @@ -103,37 +136,35 @@ namespace web 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_write_state () - { - if (!write_state_) - { - // Preparing to write a response read and discard request - // body if any. - // - int r (ap_discard_request_body (rec_)); - - if (r != OK) - { - throw invalid_request (r); - } - - write_state_ = true; - } - } + set_read_state () {state (request_state::reading);} + + virtual void + set_write_state () {state (request_state::writing);} private: request_rec* rec_; - bool buffer_ {true}; - bool write_state_ {false}; - std::unique_ptr out_buf_; - std::unique_ptr out_; - std::unique_ptr in_buf_; - std::unique_ptr in_; + 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_; }; } } -- cgit v1.1