Added --add-x-forwarded-for option.

This option append X-Forwarded-For header field to the downstream
request.
This commit is contained in:
Tatsuhiro Tsujikawa 2012-07-12 23:39:11 +09:00
parent 63adaad93a
commit e5249538a6
4 changed files with 36 additions and 12 deletions

View File

@ -344,6 +344,9 @@ void print_help(std::ostream& out)
<< " -D, --daemon Run in a background. If -D is used, the\n" << " -D, --daemon Run in a background. If -D is used, the\n"
<< " current working directory is changed to '/'.\n" << " current working directory is changed to '/'.\n"
<< " -s, --spdy-proxy SSL/SPDY proxy mode.\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" << " -h, --help Print this help.\n"
<< std::endl; << std::endl;
} }
@ -361,6 +364,7 @@ int main(int argc, char **argv)
uint16_t backend_port; uint16_t backend_port;
while(1) { while(1) {
int flag;
static option long_options[] = { static option long_options[] = {
{"backend", required_argument, 0, 'b' }, {"backend", required_argument, 0, 'b' },
{"frontend", required_argument, 0, 'f' }, {"frontend", required_argument, 0, 'f' },
@ -369,6 +373,7 @@ int main(int argc, char **argv)
{"log-level", required_argument, 0, 'L' }, {"log-level", required_argument, 0, 'L' },
{"daemon", no_argument, 0, 'D' }, {"daemon", no_argument, 0, 'D' },
{"spdy-proxy", no_argument, 0, 's' }, {"spdy-proxy", no_argument, 0, 's' },
{"add-x-forwarded-for", no_argument, &flag, 1},
{"help", no_argument, 0, 'h' }, {"help", no_argument, 0, 'h' },
{0, 0, 0, 0 } {0, 0, 0, 0 }
}; };
@ -420,6 +425,16 @@ int main(int argc, char **argv)
break; break;
case '?': case '?':
exit(EXIT_FAILURE); 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: default:
break; break;
} }

View File

@ -41,7 +41,8 @@ Config::Config()
downstream_addrlen(0), downstream_addrlen(0),
num_worker(0), num_worker(0),
spdy_max_concurrent_streams(0), spdy_max_concurrent_streams(0),
spdy_proxy(false) spdy_proxy(false),
add_x_forwarded_for(false)
{} {}
namespace { namespace {

View File

@ -68,6 +68,7 @@ struct Config {
size_t num_worker; size_t num_worker;
size_t spdy_max_concurrent_streams; size_t spdy_max_concurrent_streams;
bool spdy_proxy; bool spdy_proxy;
bool add_x_forwarded_for;
Config(); Config();
}; };

View File

@ -296,13 +296,13 @@ bool Downstream::get_output_buffer_full()
// Downstream. Otherwise, the program will crash. // Downstream. Otherwise, the program will crash.
int Downstream::push_request_headers() int Downstream::push_request_headers()
{ {
bool xff_found = false;
std::string hdrs = request_method_; std::string hdrs = request_method_;
hdrs += " "; hdrs += " ";
hdrs += request_path_; hdrs += request_path_;
hdrs += " "; hdrs += " ";
hdrs += "HTTP/1.1\r\n"; hdrs += "HTTP/1.1\r\n";
std::string via_value; std::string via_value;
std::string xff_value;
for(Headers::const_iterator i = request_headers_.begin(); for(Headers::const_iterator i = request_headers_.begin();
i != request_headers_.end(); ++i) { i != request_headers_.end(); ++i) {
if(util::strieq((*i).first.c_str(), "X-Forwarded-Proto") || if(util::strieq((*i).first.c_str(), "X-Forwarded-Proto") ||
@ -315,6 +315,10 @@ int Downstream::push_request_headers()
via_value = (*i).second; via_value = (*i).second;
continue; continue;
} }
if(util::strieq((*i).first.c_str(), "x-forwarded-for")) {
xff_value = (*i).second;
continue;
}
if(util::strieq((*i).first.c_str(), "expect") && if(util::strieq((*i).first.c_str(), "expect") &&
util::strifind((*i).second.c_str(), "100-continue")) { util::strifind((*i).second.c_str(), "100-continue")) {
continue; continue;
@ -322,22 +326,25 @@ int Downstream::push_request_headers()
hdrs += (*i).first; hdrs += (*i).first;
hdrs += ": "; hdrs += ": ";
hdrs += (*i).second; 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"; hdrs += "\r\n";
} }
if(request_connection_close_) { if(request_connection_close_) {
hdrs += "Connection: close\r\n"; hdrs += "Connection: close\r\n";
} }
if(request_method_ != "CONNECT") { if(get_config()->add_x_forwarded_for) {
if(!xff_found) {
hdrs += "X-Forwarded-For: "; hdrs += "X-Forwarded-For: ";
if(!xff_value.empty()) {
hdrs += xff_value;
hdrs += ", ";
}
hdrs += upstream_->get_client_handler()->get_ipaddr(); hdrs += upstream_->get_client_handler()->get_ipaddr();
hdrs += "\r\n"; 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: "; hdrs += "X-Forwarded-Proto: ";
if(util::istartsWith(request_path_, "http:")) { if(util::istartsWith(request_path_, "http:")) {
hdrs += "http"; hdrs += "http";