From dc3119303aa0bc602cefc64bf91235df33ae9a12 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Sun, 20 Mar 2016 17:55:17 +0900 Subject: [PATCH] Rewrite concat_string_ref --- src/HttpServer.cc | 13 +++------ src/allocator.h | 54 ++++++++++++++++++++++--------------- src/shrpx_http.cc | 19 ++++--------- src/shrpx_https_upstream.cc | 10 ++----- src/template.h | 18 +++++++------ 5 files changed, 53 insertions(+), 61 deletions(-) diff --git a/src/HttpServer.cc b/src/HttpServer.cc index 68973d38..ccad1f26 100644 --- a/src/HttpServer.cc +++ b/src/HttpServer.cc @@ -1187,17 +1187,10 @@ void prepare_redirect_response(Stream *stream, Http2Handler *hd, authority = stream->header.host; } - size_t len = scheme.size() + str_size("://") + authority.size() + path.size(); - auto iov = make_byte_ref(stream->balloc, len + 1); - auto p = iov.base; - p = std::copy(std::begin(scheme), std::end(scheme), p); - p = util::copy_lit(p, "://"); - p = std::copy(std::begin(authority), std::end(authority), p); - p = std::copy(std::begin(path), std::end(path), p); - *p = '\0'; + auto location = concat_string_ref( + stream->balloc, scheme, StringRef::from_lit("://"), authority, path); - auto headers = - HeaderRefs{{StringRef::from_lit("location"), StringRef{iov.base, p}}}; + auto headers = HeaderRefs{{StringRef::from_lit("location"), location}}; auto sessions = hd->get_sessions(); auto status_page = sessions->get_server()->get_status_page(status); diff --git a/src/allocator.h b/src/allocator.h index 64bdff49..701ccf30 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -120,31 +120,43 @@ StringRef make_string_ref(BlockAllocator &alloc, const StringRef &src) { return StringRef{dst, src.size()}; } -// Returns the string which is the concatenation of |a| and |b| in -// this order. The resulting string will be NULL-terminated. -template -StringRef concat_string_ref(BlockAllocator &alloc, const StringRef &a, - const StringRef &b) { - auto len = a.size() + b.size(); - auto dst = static_cast(alloc.alloc(len + 1)); - auto p = dst; - p = std::copy(std::begin(a), std::end(a), p); - p = std::copy(std::begin(b), std::end(b), p); - *p = '\0'; - return StringRef{dst, len}; +// private function used in concat_string_ref. this is the base +// function of concat_string_ref_count(). +inline size_t concat_string_ref_count(size_t acc) { return acc; } + +// private function used in concat_string_ref. This function counts +// the sum of length of given arguments. The calculated length is +// accumulated, and passed to the next function. +template +size_t concat_string_ref_count(size_t acc, const StringRef &value, + Args &&... args) { + return concat_string_ref_count(acc + value.size(), + std::forward(args)...); } -// Returns the string which is the concatenation of |a|, |b| and |c| -// in this order. The resulting string will be NULL-terminated. -template -StringRef concat_string_ref(BlockAllocator &alloc, const StringRef &a, - const StringRef &b, const StringRef &c) { - auto len = a.size() + b.size() + c.size(); +// private function used in concat_string_ref. this is the base +// function of concat_string_ref_copy(). +inline uint8_t *concat_string_ref_copy(uint8_t *p) { return p; } + +// private function used in concat_string_ref. This function copies +// given strings into |p|. |p| is incremented by the copied length, +// and returned. In the end, return value points to the location one +// beyond the last byte written. +template +uint8_t *concat_string_ref_copy(uint8_t *p, const StringRef &value, + Args &&... args) { + p = std::copy(std::begin(value), std::end(value), p); + return concat_string_ref_copy(p, std::forward(args)...); +} + +// Returns the string which is the concatenation of |args| in the +// given order. The resulting string will be NULL-terminated. +template +StringRef concat_string_ref(BlockAllocator &alloc, Args &&... args) { + size_t len = concat_string_ref_count(0, std::forward(args)...); auto dst = static_cast(alloc.alloc(len + 1)); auto p = dst; - p = std::copy(std::begin(a), std::end(a), p); - p = std::copy(std::begin(b), std::end(b), p); - p = std::copy(std::begin(c), std::end(c), p); + p = concat_string_ref_copy(p, std::forward(args)...); *p = '\0'; return StringRef{dst, len}; } diff --git a/src/shrpx_http.cc b/src/shrpx_http.cc index 8f1bc751..c2939c7e 100644 --- a/src/shrpx_http.cc +++ b/src/shrpx_http.cc @@ -48,20 +48,11 @@ StringRef create_error_html(BlockAllocator &balloc, unsigned int http_status) { auto status_string = http2::get_status_string(balloc, http_status); const auto &server_name = httpconf.server_name; - size_t len = 256 + server_name.size() + status_string.size() * 2; - - auto iov = make_byte_ref(balloc, len + 1); - auto p = iov.base; - - p = util::copy_lit(p, R"()"); - p = std::copy(std::begin(status_string), std::end(status_string), p); - p = util::copy_lit(p, "

"); - p = std::copy(std::begin(status_string), std::end(status_string), p); - p = util::copy_lit(p, "

"); - p = std::copy(std::begin(server_name), std::end(server_name), p); - p = util::copy_lit(p, "
"); - *p = '\0'; - return StringRef{iov.base, p}; + return concat_string_ref( + balloc, StringRef::from_lit(R"()"), + status_string, StringRef::from_lit("

"), status_string, + StringRef::from_lit("

")); } StringRef create_forwarded(BlockAllocator &balloc, int params, diff --git a/src/shrpx_https_upstream.cc b/src/shrpx_https_upstream.cc index ad57e32d..f2236731 100644 --- a/src/shrpx_https_upstream.cc +++ b/src/shrpx_https_upstream.cc @@ -264,14 +264,8 @@ void rewrite_request_host_path_from_uri(BlockAllocator &balloc, Request &req, auto q = util::get_uri_field(uri.c_str(), u, UF_QUERY); path = StringRef{std::begin(path), std::end(q)}; } else { - auto iov = make_byte_ref(balloc, path.size() + 1 + fdata.len + 1); - auto p = iov.base; - - p = std::copy(std::begin(path), std::end(path), p); - *p++ = '?'; - p = std::copy_n(&uri[fdata.off], fdata.len, p); - *p = '\0'; - path = StringRef{iov.base, p}; + path = concat_string_ref(balloc, path, StringRef::from_lit("?"), + StringRef{&uri[fdata.off], fdata.len}); } } diff --git a/src/template.h b/src/template.h index 981a2934..264f0473 100644 --- a/src/template.h +++ b/src/template.h @@ -437,11 +437,11 @@ public: return StringRef(s); } - const_iterator begin() const { return base; }; - const_iterator cbegin() const { return base; }; + constexpr const_iterator begin() const { return base; }; + constexpr const_iterator cbegin() const { return base; }; - const_iterator end() const { return base + len; }; - const_iterator cend() const { return base + len; }; + constexpr const_iterator end() const { return base + len; }; + constexpr const_iterator cend() const { return base + len; }; const_reverse_iterator rbegin() const { return const_reverse_iterator{base + len}; @@ -453,10 +453,12 @@ public: const_reverse_iterator rend() const { return const_reverse_iterator{base}; } const_reverse_iterator crend() const { return const_reverse_iterator{base}; } - const char *c_str() const { return base; } - size_type size() const { return len; } - bool empty() const { return len == 0; } - const_reference operator[](size_type pos) const { return *(base + pos); } + constexpr const char *c_str() const { return base; } + constexpr size_type size() const { return len; } + constexpr bool empty() const { return len == 0; } + constexpr const_reference operator[](size_type pos) const { + return *(base + pos); + } std::string str() const { return std::string(base, len); } const uint8_t *byte() const {