2626import io
2727import logging
2828import os
29+ import re
2930import socket
3031import sys # modify sys.path when running in source tree
3132import time
@@ -534,11 +535,27 @@ def inner_run_cgi(self):
534535 tracker .Client (tracker , self , env ).main ()
535536
536537 def address_string (self ):
538+ """Get IP address of client from:
539+ left most element of X-Forwarded-For header element if set
540+ client ip address otherwise.
541+ if returned string is from X-Forwarded-For append + to string.
542+ """
543+ from_forwarded_header = ""
544+ forwarded_for = None
545+ if 'X-FORWARDED-FOR' in self .headers :
546+ forwarded_for = re .split (r'[,\s]' ,
547+ self .headers ['X-FORWARDED-FOR' ],
548+ maxsplit = 1 )[0 ]
549+ from_forwarded_header = "+"
537550 if self .LOG_IPADDRESS :
538- return self .client_address [0 ]
551+ return "%s%s" % (forwarded_for or self .client_address [0 ],
552+ from_forwarded_header )
539553 else :
540- host , port = self .client_address
541- return socket .getfqdn (host )
554+ if forwarded_for :
555+ host = forwarded_for
556+ else :
557+ host , port = self .client_address
558+ return "%s%s" % (socket .getfqdn (host ), from_forwarded_header )
542559
543560 def log_message (self , format , * args ):
544561 ''' Try to *safely* log to stderr.
@@ -547,7 +564,7 @@ def log_message(self, format, *args):
547564 logger = logging .getLogger ('roundup.http' )
548565
549566 logger .info ("%s - - [%s] %s" %
550- (self .client_address [ 0 ] ,
567+ (self .address_string () ,
551568 self .log_date_time_string (),
552569 format % args ))
553570 else :
@@ -680,6 +697,11 @@ class ServerConfig(configuration.Config):
680697 "If set to yes the python logging module is used with "
681698 "qualname\n 'roundup.http'. Otherwise logging is done to "
682699 "stderr or the file\n specified using the -l/logfile option." ),
700+ (configuration .BooleanOption , "log_proxy_header" , "no" ,
701+ "Use first element of reverse proxy header X-Forwarded-For "
702+ "as client IP address.\n This appends a '+' sign to the logged "
703+ "host ip/name. Use only if server is\n accessible only via "
704+ "trusted reverse proxy." ),
683705 (configuration .NullableFilePathOption , "pidfile" , "" ,
684706 "File to which the server records "
685707 "the process id of the daemon.\n "
@@ -734,6 +756,7 @@ class ServerConfig(configuration.Config):
734756 "multiprocess" : "t:" ,
735757 "template" : "i:" ,
736758 "loghttpvialogger" : 'L' ,
759+ "log_proxy_header" : 'P' ,
737760 "ssl" : "s" ,
738761 "pem" : "e:" ,
739762 "include_headers" : "I:" ,
@@ -952,7 +975,8 @@ def usage(message=''):
952975 -g <GID> runs the Roundup web server as this GID
953976 -d <PIDfile> run the server in the background and write the server's PID
954977 to the file indicated by PIDfile. The -l option *must* be
955- specified if -d is used.'''
978+ specified if -d is used.
979+ -D run the server in the foreground even when -d is used.'''
956980 if message :
957981 message += '\n \n '
958982 print (_ ('''\n %(message)sUsage: roundup-server [options] [name=tracker home]*
@@ -974,6 +998,9 @@ def usage(message=''):
974998 -m <children> maximum number of children to spawn in fork multiprocess mode
975999 -s enable SSL
9761000 -L http request logging uses python logging (roundup.http)
1001+ -P log client address/name using reverse proxy X-Forwarded-For
1002+ header and not the connection IP (which is the reverse proxy).
1003+ Appends a '+' sign to the logged address/name.
9771004 -e <fname> PEM file containing SSL key and certificate
9781005 -t <mode> multiprocess mode (default: %(mp_def)s).
9791006 Allowed values: %(mp_types)s.
0 commit comments