From e5249538a65f4bada8292748d1a2f022c2241e25 Mon Sep 17 00:00:00 2001 From: Tatsuhiro Tsujikawa Date: Thu, 12 Jul 2012 23:39:11 +0900 Subject: [PATCH] Added --add-x-forwarded-for option. This option append X-Forwarded-For header field to the downstream request. --- examples/shrpx.cc | 15 +++++++++++++++ examples/shrpx_config.cc | 3 ++- examples/shrpx_config.h | 1 + examples/shrpx_downstream.cc | 29 ++++++++++++++++++----------- 4 files changed, 36 insertions(+), 12 deletions(-) diff --git a/examples/shrpx.cc b/examples/shrpx.cc index 0a5985fb..07ff9d23 100644 --- a/examples/shrpx.cc +++ b/examples/shrpx.cc @@ -344,6 +344,9 @@ void print_help(std::ostream& out) << " -D, --daemon Run in a background. If -D is used, the\n" << " current working directory is changed to '/'.\n" << " -s, --spdy-proxy SSL/SPDY proxy mode.\n" + << " --add-x-forwarded-for\n" + << " Append X-Forwarded-For header field to the\n" + << " downstream request.\n" << " -h, --help Print this help.\n" << std::endl; } @@ -361,6 +364,7 @@ int main(int argc, char **argv) uint16_t backend_port; while(1) { + int flag; static option long_options[] = { {"backend", required_argument, 0, 'b' }, {"frontend", required_argument, 0, 'f' }, @@ -369,6 +373,7 @@ int main(int argc, char **argv) {"log-level", required_argument, 0, 'L' }, {"daemon", no_argument, 0, 'D' }, {"spdy-proxy", no_argument, 0, 's' }, + {"add-x-forwarded-for", no_argument, &flag, 1}, {"help", no_argument, 0, 'h' }, {0, 0, 0, 0 } }; @@ -420,6 +425,16 @@ int main(int argc, char **argv) break; case '?': exit(EXIT_FAILURE); + case 0: + switch(flag) { + case 1: + // --add-x-forwarded-for + mod_config()->add_x_forwarded_for = true; + break; + default: + break; + } + break; default: break; } diff --git a/examples/shrpx_config.cc b/examples/shrpx_config.cc index 0a6bbcd6..e4e09534 100644 --- a/examples/shrpx_config.cc +++ b/examples/shrpx_config.cc @@ -41,7 +41,8 @@ Config::Config() downstream_addrlen(0), num_worker(0), spdy_max_concurrent_streams(0), - spdy_proxy(false) + spdy_proxy(false), + add_x_forwarded_for(false) {} namespace { diff --git a/examples/shrpx_config.h b/examples/shrpx_config.h index 7d8f9fb5..26b6d4d9 100644 --- a/examples/shrpx_config.h +++ b/examples/shrpx_config.h @@ -68,6 +68,7 @@ struct Config { size_t num_worker; size_t spdy_max_concurrent_streams; bool spdy_proxy; + bool add_x_forwarded_for; Config(); }; diff --git a/examples/shrpx_downstream.cc b/examples/shrpx_downstream.cc index decc15dd..486ffe6d 100644 --- a/examples/shrpx_downstream.cc +++ b/examples/shrpx_downstream.cc @@ -296,13 +296,13 @@ bool Downstream::get_output_buffer_full() // Downstream. Otherwise, the program will crash. int Downstream::push_request_headers() { - bool xff_found = false; std::string hdrs = request_method_; hdrs += " "; hdrs += request_path_; hdrs += " "; hdrs += "HTTP/1.1\r\n"; std::string via_value; + std::string xff_value; for(Headers::const_iterator i = request_headers_.begin(); i != request_headers_.end(); ++i) { if(util::strieq((*i).first.c_str(), "X-Forwarded-Proto") || @@ -315,6 +315,10 @@ int Downstream::push_request_headers() via_value = (*i).second; continue; } + if(util::strieq((*i).first.c_str(), "x-forwarded-for")) { + xff_value = (*i).second; + continue; + } if(util::strieq((*i).first.c_str(), "expect") && util::strifind((*i).second.c_str(), "100-continue")) { continue; @@ -322,22 +326,25 @@ int Downstream::push_request_headers() hdrs += (*i).first; hdrs += ": "; hdrs += (*i).second; - if(!xff_found && util::strieq((*i).first.c_str(), "X-Forwarded-For")) { - xff_found = true; - hdrs += ", "; - hdrs += upstream_->get_client_handler()->get_ipaddr(); - } hdrs += "\r\n"; } if(request_connection_close_) { hdrs += "Connection: close\r\n"; } - if(request_method_ != "CONNECT") { - if(!xff_found) { - hdrs += "X-Forwarded-For: "; - hdrs += upstream_->get_client_handler()->get_ipaddr(); - hdrs += "\r\n"; + if(get_config()->add_x_forwarded_for) { + hdrs += "X-Forwarded-For: "; + if(!xff_value.empty()) { + hdrs += xff_value; + hdrs += ", "; } + hdrs += upstream_->get_client_handler()->get_ipaddr(); + hdrs += "\r\n"; + } else if(!xff_value.empty()) { + hdrs += "X-Forwarded-For: "; + hdrs += xff_value; + hdrs += "\r\n"; + } + if(request_method_ != "CONNECT") { hdrs += "X-Forwarded-Proto: "; if(util::istartsWith(request_path_, "http:")) { hdrs += "http";