diff --git a/src/allocator.h b/src/allocator.h index 00acdbcf..cd92d3fd 100644 --- a/src/allocator.h +++ b/src/allocator.h @@ -104,12 +104,26 @@ StringRef make_string_ref(BlockAllocator &alloc, const StringRef &src) { template StringRef concat_string_ref(BlockAllocator &alloc, const StringRef &a, const StringRef &b) { - auto dst = static_cast(alloc.alloc(a.size() + b.size() + 1)); + 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, a.size() + b.size()}; + return StringRef{dst, len}; +} + +template +StringRef concat_string_ref(BlockAllocator &alloc, const StringRef &a, + const StringRef &b, const StringRef &c) { + auto len = a.size() + b.size() + c.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 = std::copy(std::begin(c), std::end(c), p); + *p = '\0'; + return StringRef{dst, len}; } struct ByteRef { diff --git a/src/shrpx_http2_downstream_connection.cc b/src/shrpx_http2_downstream_connection.cc index 2e5fb177..c9df0369 100644 --- a/src/shrpx_http2_downstream_connection.cc +++ b/src/shrpx_http2_downstream_connection.cc @@ -387,17 +387,18 @@ int Http2DownstreamConnection::push_request_headers() { auto xff = xffconf.strip_incoming ? nullptr : req.fs.header(http2::HD_X_FORWARDED_FOR); - std::string xff_value; - if (xffconf.add) { + StringRef xff_value; + auto addr = StringRef{upstream->get_client_handler()->get_ipaddr()}; if (xff) { - xff_value = (*xff).value.str(); - xff_value += ", "; + xff_value = concat_string_ref(balloc, xff->value, + StringRef::from_lit(", "), addr); + } else { + xff_value = addr; } - xff_value += upstream->get_client_handler()->get_ipaddr(); - nva.push_back(http2::make_nv_ls("x-forwarded-for", xff_value)); + nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-for", xff_value)); } else if (xff) { - nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-for", (*xff).value)); + nva.push_back(http2::make_nv_ls_nocopy("x-forwarded-for", xff->value)); } if (!get_config()->http2_proxy && req.method != HTTP_CONNECT) {