diff options
Diffstat (limited to 'web/apache')
-rw-r--r-- | web/apache/log | 30 | ||||
-rw-r--r-- | web/apache/request | 70 | ||||
-rw-r--r-- | web/apache/request.cxx | 224 | ||||
-rw-r--r-- | web/apache/request.ixx | 147 | ||||
-rw-r--r-- | web/apache/service | 192 | ||||
-rw-r--r-- | web/apache/service.cxx | 109 | ||||
-rw-r--r-- | web/apache/service.txx | 85 | ||||
-rw-r--r-- | web/apache/stream | 23 |
8 files changed, 460 insertions, 420 deletions
diff --git a/web/apache/log b/web/apache/log index 50e2f7c..acc7c92 100644 --- a/web/apache/log +++ b/web/apache/log @@ -48,25 +48,25 @@ namespace web if (func) ap_log_error (file, - line, - APLOG_NO_MODULE, - level, - 0, - server_, - "[%s]: %s", - func, - msg); + line, + APLOG_NO_MODULE, + level, + 0, + server_, + "[%s]: %s", + func, + msg); else // skip function name placeholder from log line // ap_log_error (file, - line, - APLOG_NO_MODULE, - level, - 0, - server_, - ": %s", - msg); + line, + APLOG_NO_MODULE, + level, + 0, + server_, + ": %s", + msg); } private: diff --git a/web/apache/request b/web/apache/request index 4071bd1..1fb9cbe 100644 --- a/web/apache/request +++ b/web/apache/request @@ -46,48 +46,12 @@ namespace web // Get request body data stream. // virtual std::istream& - content () - { - if (!in_) - { - std::unique_ptr<std::streambuf> in_buf ( - new istreambuf (rec_, *this)); - - in_.reset (new std::istream (in_buf.get ())); - in_buf_ = std::move (in_buf); - in_->exceptions (std::ios::failbit | std::ios::badbit); - - // Save form data now otherwise will not be available to do later - // when data read from stream. - // - form_data (); - } - - return *in_; - } + content (); // Get request parameters. // virtual const name_values& - parameters () - { - if (!parameters_) - { - parameters_.reset (new name_values ()); - - try - { - parse_parameters (rec_->args); - parse_parameters (form_data ()->c_str ()); - } - catch (const std::invalid_argument& ) - { - throw invalid_request (); - } - } - - return *parameters_; - } + parameters (); // Get request cookies. // @@ -101,26 +65,7 @@ namespace web // Set response status code. // virtual void - status (status_code status) - { - if (status != rec_->status) - { - // Setting status code in exception handler is a common usecase - // where no sense to throw but still need to signal apache a - // proper status code. - // - if (get_write_state () && !std::current_exception ()) - { - throw sequence_error ("::web::apache::request::status"); - } - - rec_->status = status; - buffer_ = true; - out_.reset (); - out_buf_.reset (); - ap_set_content_type (rec_, nullptr); - } - } + status (status_code status); // Set response status code, content type and get body stream. // @@ -140,11 +85,9 @@ namespace web bool secure = false); private: - using string_ptr = std::unique_ptr<std::string>; - // Get application/x-www-form-urlencoded form data. // - const string_ptr& + const std::string& form_data (); void @@ -167,7 +110,7 @@ namespace web // Preparing to write a response read and discard request // body if any. // - int r = ap_discard_request_body (rec_); + int r (ap_discard_request_body (rec_)); if (r != OK) { @@ -179,7 +122,6 @@ namespace web } private: - request_rec* rec_; bool buffer_ {true}; bool write_state_ {false}; @@ -189,7 +131,7 @@ namespace web std::unique_ptr<std::istream> in_; std::unique_ptr<name_values> parameters_; std::unique_ptr<name_values> cookies_; - string_ptr form_data_; + std::unique_ptr<std::string> form_data_; }; } } diff --git a/web/apache/request.cxx b/web/apache/request.cxx index 3711437..caf0d60 100644 --- a/web/apache/request.cxx +++ b/web/apache/request.cxx @@ -25,6 +25,48 @@ namespace web { namespace apache { + + istream& request:: + content () + { + if (!in_) + { + unique_ptr<streambuf> in_buf (new istreambuf (rec_, *this)); + + in_.reset (new istream (in_buf.get ())); + in_buf_ = move (in_buf); + in_->exceptions (ios::failbit | ios::badbit); + + // Save form data now otherwise will not be available to do later + // when data already read from stream. + // + form_data (); + } + + return *in_; + } + + const name_values& request:: + parameters () + { + if (!parameters_) + { + parameters_.reset (new name_values ()); + + try + { + parse_parameters (rec_->args); + parse_parameters (form_data ().c_str ()); + } + catch (const invalid_argument& ) + { + throw invalid_request (); + } + } + + return *parameters_; + } + const name_values& request:: cookies () { @@ -32,8 +74,8 @@ namespace web { cookies_.reset (new name_values ()); - const apr_array_header_t* ha = apr_table_elts (rec_->headers_in); - size_t n = ha->nelts; + const apr_array_header_t* ha (apr_table_elts (rec_->headers_in)); + size_t n (ha->nelts); for (auto h (reinterpret_cast<const apr_table_entry_t *> (ha->elts)); n--; ++h) @@ -42,8 +84,8 @@ namespace web { for (const char* n (h->val); n != 0; ) { - const char* v = strchr (n, '='); - const char* e = strchr (n, ';'); + const char* v (strchr (n, '=')); + const char* e (strchr (n, ';')); if (e && e < v) v = 0; @@ -97,12 +139,12 @@ namespace web // form_data (); - unique_ptr<std::streambuf> out_buf ( + unique_ptr<streambuf> out_buf ( buffer - ? static_cast<std::streambuf*> (new std::stringbuf ()) - : static_cast<std::streambuf*> (new ostreambuf (rec_, *this))); + ? static_cast<streambuf*> (new stringbuf ()) + : static_cast<streambuf*> (new ostreambuf (rec_, *this))); - out_.reset (new std::ostream (out_buf.get ())); + out_.reset (new ostream (out_buf.get ())); out_buf_ = move (out_buf); out_->exceptions (ios::eofbit | ios::failbit | ios::badbit); @@ -117,6 +159,28 @@ namespace web } void request:: + status (status_code status) + { + if (status != rec_->status) + { + // Setting status code in exception handler is a common usecase + // where no sense to throw but still need to signal apache a + // proper status code. + // + if (get_write_state () && !current_exception ()) + { + throw sequence_error ("::web::apache::request::status"); + } + + rec_->status = status; + buffer_ = true; + out_.reset (); + out_buf_.reset (); + ap_set_content_type (rec_, nullptr); + } + } + + void request:: cookie (const char* name, const char* value, const chrono::seconds* max_age, @@ -126,6 +190,8 @@ namespace web { if (get_write_state ()) { + // Too late to send cookie if content is already written. + // throw sequence_error ("::web::apache::request::cookie"); } @@ -136,12 +202,12 @@ namespace web if (max_age) { - chrono::system_clock::time_point tp = - chrono::system_clock::now () + *max_age; + chrono::system_clock::time_point tp ( + chrono::system_clock::now () + *max_age); - time_t t = chrono::system_clock::to_time_t (tp); + time_t t (chrono::system_clock::to_time_t (tp)); - // Assume global "C" locale is not changed. + // Assume global locale is not changed and still "C". // char b[100]; strftime (b, sizeof (b), "%a, %d-%b-%Y %H:%M:%S GMT", gmtime (&t)); @@ -166,5 +232,139 @@ namespace web apr_table_add (rec_->err_headers_out, "Set-Cookie", s.str ().c_str ()); } + void request:: + parse_parameters (const char* args) + { + for (auto n (args); n != 0; ) + { + const char* v (strchr (n, '=')); + const char* e (strchr (n, '&')); + + if (e && e < v) + v = 0; + + string name (v + ? mime_url_decode (n, v) : + (e + ? mime_url_decode (n, e) + : mime_url_decode (n, n + strlen (n)))); + + string value; + + if (v++) + { + value = e + ? mime_url_decode (v, e) + : mime_url_decode (v, v + strlen (v)); + } + + if (!name.empty () || !value.empty ()) + parameters_->emplace_back (move (name), move (value)); + + n = e ? e + 1 : 0; + } + } + + void request:: + mime_url_encode (const char* v, ostream& o) + { + char f (o.fill ()); + ios_base::fmtflags g (o.flags ()); + o << hex << uppercase << right << setfill ('0'); + + char c; + + while ((c = *v++) != '\0') + { + if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || + (c >= '0' && c <= '9')) + { + o << c; + } + else + switch (c) + { + case ' ': o << '+'; break; + case '.': + case '_': + case '-': + case '~': o << c; break; + default: + { + o << "%" << setw (2) << static_cast<unsigned short> (c); + break; + } + } + } + + o.flags (g); + o.fill (f); + } + + string request:: + mime_url_decode (const char* b, const char* e, bool trim) + { + if (trim) + { + b += strspn (b, " "); + + if (b >= e) + return string (); + + while (*--e == ' '); + ++e; + } + + string value; + value.reserve (e - b); + + char bf[3]; + bf[2] = '\0'; + + while (b != e) + { + char c (*b++); + + switch (c) + { + case '+': + { + value.append (" "); + break; + } + case '%': + { + if (*b == '\0' || b[1] == '\0') + { + throw invalid_argument ( + "::web::apache::request::mime_url_decode short"); + } + + *bf = *b; + bf[1] = b[1]; + + char* ebf (nullptr); + size_t vl (strtoul (bf, &ebf, 16)); + + if (*ebf != '\0') + { + throw invalid_argument ( + "::web::apache::request::mime_url_decode wrong"); + } + + value.append (1, static_cast<char> (vl)); + b += 2; + break; + } + default: + { + value.append (1, c); + break; + } + } + } + + return value; + } } } diff --git a/web/apache/request.ixx b/web/apache/request.ixx index 06284fb..f7446e5 100644 --- a/web/apache/request.ixx +++ b/web/apache/request.ixx @@ -18,7 +18,7 @@ namespace web { if (buffer_ && out_buf_) { - auto b = dynamic_cast<std::stringbuf*> (out_buf_.get ()); + auto b (dynamic_cast<std::stringbuf*> (out_buf_.get ())); assert (b); std::string s (b->str ()); @@ -27,7 +27,7 @@ namespace web { // Before writing response read and discard request body if any. // - int r = ap_discard_request_body (rec_); + int r (ap_discard_request_body (rec_)); if (r == OK) { @@ -36,7 +36,6 @@ namespace web if (ap_rwrite (s.c_str (), s.length (), rec_) < 0) rec_->status = HTTP_REQUEST_TIME_OUT; } - else rec_->status = r; } @@ -48,13 +47,13 @@ namespace web return rec_->status == HTTP_OK || get_write_state () ? OK : rec_->status; } - inline const request::string_ptr& request:: + inline const std::string& request:: form_data () { if (!form_data_) { form_data_.reset (new std::string ()); - const char *ct = apr_table_get (rec_->headers_in, "Content-Type"); + const char* ct (apr_table_get (rec_->headers_in, "Content-Type")); if (ct && !strncasecmp ("application/x-www-form-urlencoded", ct, 33)) { @@ -72,143 +71,7 @@ namespace web } } - return form_data_; - } - - inline void request:: - parse_parameters (const char* args) - { - for (auto n (args); n != 0; ) - { - const char* v = std::strchr (n, '='); - const char* e = ::strchr (n, '&'); - - if (e && e < v) - v = 0; - - std::string name (v - ? mime_url_decode (n, v) : - (e - ? mime_url_decode (n, e) - : mime_url_decode (n, n + std::strlen (n)))); - - std::string value; - - if (v++) - { - value = e - ? mime_url_decode (v, e) - : mime_url_decode (v, v + std::strlen (v)); - } - - if (!name.empty () || !value.empty ()) - parameters_->emplace_back (std::move (name), std::move (value)); - - n = e ? e + 1 : 0; - } + return *form_data_; } - - inline void request:: - mime_url_encode (const char* v, std::ostream& o) - { - char f = o.fill (); - std::ios_base::fmtflags g = o.flags (); - o << std::hex << std::uppercase << std::right << std::setfill ('0'); - - char c; - - while ((c = *v++) != '\0') - { - if ((c >= 'A' && c <= 'Z') || (c >= 'a' && c <= 'z') || - (c >= '0' && c <= '9')) - { - o << c; - } - else - switch (c) - { - case ' ': o << '+'; break; - case '.': - case '_': - case '-': - case '~': o << c; break; - default: - { - o << "%" << std::setw (2) << static_cast<unsigned short> (c); - break; - } - } - } - - o.flags (g); - o.fill (f); - } - - inline std::string request:: - mime_url_decode (const char* b, const char* e, bool trim) - { - if (trim) - { - b += std::strspn (b, " "); - - if (b >= e) - return std::string (); - - while (*--e == ' '); - ++e; - } - - std::string value; - value.reserve (e - b); - - char bf[3]; - bf[2] = '\0'; - - while (b != e) - { - char c = *b++; - - switch (c) - { - case '+': - { - value.append (" "); - break; - } - case '%': - { - if (*b == '\0' || b[1] == '\0') - { - throw std::invalid_argument ( - "::web::apache::request::mime_url_decode short"); - } - - *bf = *b; - bf[1] = b[1]; - - char* ebf = 0; - size_t vl = std::strtoul (bf, &ebf, 16); - - if (*ebf != '\0') - { - throw std::invalid_argument ( - "::web::apache::request::mime_url_decode wrong"); - } - - value.append (1, static_cast<char> (vl)); - b += 2; - break; - } - default: - { - value.append (1, c); - break; - } - } - } - - return value; - } - } } diff --git a/web/apache/service b/web/apache/service index cd405ee..8456f12 100644 --- a/web/apache/service +++ b/web/apache/service @@ -5,18 +5,11 @@ #ifndef WEB_APACHE_SERVICE #define WEB_APACHE_SERVICE -#include <string.h> // memset() -#include <unistd.h> // getppid() -#include <signal.h> // kill() - #include <httpd/httpd.h> -#include <httpd/http_config.h> #include <string> #include <vector> -#include <memory> // unique_ptr #include <cassert> -#include <exception> #include <algorithm> // move() #include <web/module> @@ -30,7 +23,6 @@ namespace web class service: ::module { public: - using option_names = std::vector<std::string>; // Note that the module exemplar is stored by-reference. @@ -52,48 +44,17 @@ namespace web name_ (name), exemplar_ (exemplar), option_names_ (std::move (opts)) -// Doesn't look like handle_ member is required at all. -// handle_ (&handle_impl<M>) { - // Fill apache module directive definitions. Directives share - // common name space in apache configuration file, so to prevent name - // clash have to form directive name as a combination of module and - // option names: <module name>-<option name>. This why for option - // bar of module foo the corresponding directive will appear in apache - // configuration file as foo-bar. - // - std::unique_ptr<command_rec[]> directives ( - new command_rec[option_names_.size () + 1]); - - command_rec* d = directives.get (); - - for (auto& o: option_names_) - { - o = name_ + "-" + o; - - *d++ = - { - o.c_str (), - reinterpret_cast<cmd_func> (add_option), - this, - RSRC_CONF, - TAKE1, - nullptr - }; - } - - *d = {}; + init_directives(); // instance<M> () is invented to delegate processing from apache // request handler C function to the service non static member // function. This appoach resticts number of service objects per // specific module implementation class with just one instance. // - service*& srv = instance<M> (); + service*& srv (instance<M> ()); assert (srv == nullptr); srv = this; - - cmds = directives.release (); } ~service () @@ -101,23 +62,6 @@ namespace web delete [] cmds; } - static const char* - add_option (cmd_parms *parms, void *mconfig, const char *value) - { - service& srv = *reinterpret_cast<service*> (parms->cmd->cmd_data); - std::string name (parms->cmd->name + srv.name_.length () + 1); - - for (auto& v: srv.options_) - if (v.name == name) - { - v.value = value; - return 0; - } - - srv.options_.emplace_back (name, value); - return 0; - } - template <typename M> static service*& instance () noexcept @@ -144,144 +88,44 @@ namespace web static void worker_initializer (apr_pool_t*, server_rec* server) noexcept { - auto srv = instance<M> (); log l (server); - - static const std::string func_name ( - "web::apache::service<" + srv->name_ + ">::worker_initializer"); - - try - { - srv->exemplar_.init (srv->options_, l); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_EMERG, e.what ()); - - // Terminate the root apache process. - // - ::kill (::getppid (), SIGTERM); - } - catch (...) - { - l.write (nullptr, - 0, - func_name.c_str (), - APLOG_EMERG, - "unknown error"); - - // Terminate the root apache process. - // - ::kill (::getppid (), SIGTERM); - } + instance<M> ()->init_worker(l); } template <typename M> static int request_handler (request_rec* r) noexcept { - auto srv = instance<M> (); - - if (!r->handler || srv->name_ != r->handler) - return DECLINED; - - static const std::string func_name ( - "web::apache::service<" + srv->name_ + ">::request_handler"); + auto srv (instance<M> ()); + if (!r->handler || srv->name_ != r->handler) return DECLINED; request req (r); log l (r->server); + return srv->handle<M>(req, l); + } - try - { - M m (static_cast<const M&> (srv->exemplar_)); - static_cast<module&> (m).handle (req, req, l); - return req.flush (); - } - catch (const invalid_request& e) - { - if (!e.content.empty () && !req.get_write_state ()) - { - try - { - req.content (e.status, e.type) << e.content; - return req.flush (); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - } - } - - return e.status; - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - - if (*e.what () && !req.get_write_state ()) - { - try - { - req.content (HTTP_INTERNAL_SERVER_ERROR, - "text/plain;charset=utf-8") - << e.what (); - - return req.flush (); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - } - } - } - catch (...) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, "unknown error"); - - if (!req.get_write_state ()) - { - try - { - req.content (HTTP_INTERNAL_SERVER_ERROR, - "text/plain;charset=utf-8") - << "unknown error"; - - return req.flush (); - } - catch (const std::exception& e) - { - l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); - } - } + private: + void + init_directives(); - } + void + init_worker(log& l) noexcept; - return HTTP_INTERNAL_SERVER_ERROR; - } + static const char* + add_option (cmd_parms *parms, void *mconfig, const char *value) noexcept; - //@@ Implementation calls handle_ function pointer below: - // - // handle_ (rq, rs, l, exemplar_); - // + template <typename M> + int handle(request& r, log& l) noexcept; private: -/* - template <typename M> - static void - handle_impl (request& rq, response& rs, log& l, const module& exemplar) - { - M m (static_cast<const M&> (exemplar)); - static_cast<module&> (m).handle (rq, rs, l); - } -*/ std::string name_; module& exemplar_; option_names option_names_; name_values options_; - -// void (*handle_) (request&, response&, log&, const module&); }; } } +#include <web/apache/service.txx> + #endif // WEB_APACHE_SERVICE diff --git a/web/apache/service.cxx b/web/apache/service.cxx new file mode 100644 index 0000000..6b73e02 --- /dev/null +++ b/web/apache/service.cxx @@ -0,0 +1,109 @@ +// file : web/apache/service.cxx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include <web/apache/service> + +#include <unistd.h> // getppid() +#include <signal.h> // kill() + +#include <httpd/httpd.h> +#include <httpd/http_config.h> + +#include <memory> // unique_ptr +#include <string> +#include <exception> + +using namespace std; + +namespace web +{ + namespace apache + { + void service:: + init_directives() + { + assert(cmds == nullptr); + + // Fill apache module directive definitions. Directives share + // common name space in apache configuration file, so to prevent name + // clash have to form directive name as a combination of module and + // option names: <module name>-<option name>. This why for option + // bar of module foo the corresponding directive will appear in apache + // configuration file as foo-bar. + // + unique_ptr<command_rec[]> directives ( + new command_rec[option_names_.size () + 1]); + + command_rec* d (directives.get ()); + + for (auto& o: option_names_) + { + o = name_ + "-" + o; + + *d++ = + { + o.c_str (), + reinterpret_cast<cmd_func> (add_option), + this, + RSRC_CONF, + TAKE1, + nullptr + }; + } + + *d = {}; + + cmds = directives.release (); + } + + const char* service:: + add_option (cmd_parms *parms, void *mconfig, const char *value) noexcept + { + service& srv (*reinterpret_cast<service*> (parms->cmd->cmd_data)); + string name (parms->cmd->name + srv.name_.length () + 1); + + for (auto& v: srv.options_) + if (v.name == name) + { + v.value = value; + return 0; + } + + srv.options_.emplace_back (name, value); + return 0; + } + + void service:: + init_worker(log& l) noexcept + { + static const string func_name ( + "web::apache::service<" + name_ + ">::init_worker"); + + try + { + exemplar_.init (options_, l); + } + catch (const exception& e) + { + l.write (nullptr, 0, func_name.c_str (), APLOG_EMERG, e.what ()); + + // Terminate the root apache process. + // + ::kill (::getppid (), SIGTERM); + } + catch (...) + { + l.write (nullptr, + 0, + func_name.c_str (), + APLOG_EMERG, + "unknown error"); + + // Terminate the root apache process. + // + ::kill (::getppid (), SIGTERM); + } + } + } +} diff --git a/web/apache/service.txx b/web/apache/service.txx new file mode 100644 index 0000000..06f3599 --- /dev/null +++ b/web/apache/service.txx @@ -0,0 +1,85 @@ +// file : web/apache/service.txx -*- C++ -*- +// copyright : Copyright (c) 2014-2015 Code Synthesis Tools CC +// license : MIT; see accompanying LICENSE file + +#include <httpd/http_log.h> + +#include <exception> + +namespace web +{ + namespace apache + { + template <typename M> + int service:: + handle(request& r, log& l) noexcept + { + static const std::string func_name ( + "web::apache::service<" + name_ + ">::handle"); + + try + { + M m (static_cast<const M&> (exemplar_)); + static_cast<module&> (m).handle (r, r, l); + return r.flush (); + } + catch (const invalid_request& e) + { + if (!e.content.empty () && !r.get_write_state ()) + { + try + { + r.content (e.status, e.type) << e.content; + return r.flush (); + } + catch (const std::exception& e) + { + l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); + } + } + + return e.status; + } + catch (const std::exception& e) + { + l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); + + if (*e.what () && !r.get_write_state ()) + { + try + { + r.content (HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8") + << e.what (); + + return r.flush (); + } + catch (const std::exception& e) + { + l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); + } + } + } + catch (...) + { + l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, "unknown error"); + + if (!r.get_write_state ()) + { + try + { + r.content (HTTP_INTERNAL_SERVER_ERROR, "text/plain;charset=utf-8") + << "unknown error"; + + return r.flush (); + } + catch (const std::exception& e) + { + l.write (nullptr, 0, func_name.c_str (), APLOG_ERR, e.what ()); + } + } + } + + return HTTP_INTERNAL_SERVER_ERROR; + } + } +} diff --git a/web/apache/stream b/web/apache/stream index 5f76347..2aa674d 100644 --- a/web/apache/stream +++ b/web/apache/stream @@ -9,7 +9,7 @@ #include <httpd/http_protocol.h> #include <ios> // streamsize -#include <memory> // unique_ptr +#include <vector> #include <cstring> // memmove() #include <streambuf> #include <algorithm> // min(), max() @@ -52,7 +52,7 @@ namespace web { ws_.set_write_state (); - char chr = c; + char chr (c); // Throwing allows to distinguish comm failure from other IO error // conditions. @@ -89,7 +89,6 @@ namespace web } private: - request_rec* rec_; write_state& ws_; }; @@ -105,17 +104,17 @@ namespace web ws_ (ws), bufsize_ (std::max (bufsize, (size_t)1)), putback_ (std::min (putback, bufsize_ - 1)), - buf_ (new char[bufsize_]) + buf_ (bufsize_) { if (ws_.get_write_state ()) { throw sequence_error ("::web::apache::istreambuf::istreambuf"); } - char* p = buf_.get () + putback_; + char* p (buf_.data () + putback_); setg (p, p, p); - int status = ap_setup_client_block (rec_, REQUEST_CHUNKED_DECHUNK); + int status (ap_setup_client_block (rec_, REQUEST_CHUNKED_DECHUNK)); if (status != OK) { @@ -135,11 +134,11 @@ namespace web if (gptr () < egptr ()) return traits_type::to_int_type (*gptr ()); - size_t pb = std::min ((size_t)(gptr () - eback ()), putback_); - std::memmove (buf_.get () + putback_ - pb, gptr () - pb, pb); + size_t pb (std::min ((size_t)(gptr () - eback ()), putback_)); + std::memmove (buf_.data () + putback_ - pb, gptr () - pb, pb); - char* p = buf_.get () + putback_; - int rb = ap_get_client_block (rec_, p, bufsize_ - putback_); + char* p (buf_.data () + putback_); + int rb (ap_get_client_block (rec_, p, bufsize_ - putback_)); if (rb == 0) { @@ -156,14 +155,12 @@ namespace web } private: - request_rec* rec_; write_state& ws_; size_t bufsize_; size_t putback_; - std::unique_ptr<char[]> buf_; + std::vector<char> buf_; }; - } } |