5454# Cache uploads for 5 minutes by default. These files can be overwritten by
5555# users, so high cache times can be frustrating to the user.
5656CACHE_TIME_UPLOADS = 300
57+ # The name of the header to use for remote IP addresses.
58+ REMOTE_IP_HEADER = None
5759
5860
5961class ErrorOnlyAccessLogger (AccessLogger ):
6062 def log (self , request , response , time ):
6163 # Only log if the status was not successful
6264 if not (200 <= response .status < 400 ):
65+ if REMOTE_IP_HEADER and REMOTE_IP_HEADER in request .headers :
66+ request = request .clone (remote = request .headers [REMOTE_IP_HEADER ])
6367 super ().log (request , response , time )
6468
6569
@@ -80,6 +84,13 @@ async def remove_cookie_middleware(request, handler):
8084 return response
8185
8286
87+ @web .middleware
88+ async def remote_ip_header_middleware (request , handler ):
89+ if REMOTE_IP_HEADER in request .headers :
90+ request = request .clone (remote = request .headers [REMOTE_IP_HEADER ])
91+ return await handler (request )
92+
93+
8394async def cache_on_prepare (request , response , cache_time_uploads ):
8495 if request .path .startswith ("/static" ):
8596 # Cache everything in the /static folder for a day.
@@ -111,6 +122,10 @@ async def wait_for_storage():
111122 "--frontend-url" ,
112123 help = "URL of the frontend, used for creating absolute links in the sitemap.xml" ,
113124)
125+ @click .option (
126+ "--remote-ip-header" ,
127+ help = "Header which contains the remote IP address. Make sure you trust this header!" ,
128+ )
114129@click .option (
115130 "--cache-time" , help = "Cache time of uploaded images (in seconds)" , default = CACHE_TIME_UPLOADS , show_default = True
116131)
@@ -126,7 +141,7 @@ async def wait_for_storage():
126141@click_user_microsoft
127142@click_page
128143@click .option ("--validate-all" , help = "Validate all mediawiki files and report all errors" , is_flag = True )
129- def main (bind , port , storage , frontend_url , cache_time , validate_all ):
144+ def main (bind , port , storage , frontend_url , cache_time , remote_ip_header , validate_all ):
130145 if frontend_url and frontend_url .endswith ("/" ):
131146 frontend_url = frontend_url [:- 1 ]
132147 singleton .FRONTEND_URL = frontend_url
@@ -150,6 +165,10 @@ def main(bind, port, storage, frontend_url, cache_time, validate_all):
150165
151166 webapp = web .Application (client_max_size = MAX_UPLOAD_SIZE , middlewares = [remove_cookie_middleware ])
152167 webapp .on_response_prepare .append (lambda request , response : cache_on_prepare (request , response , cache_time ))
168+ if remote_ip_header :
169+ global REMOTE_IP_HEADER
170+ REMOTE_IP_HEADER = remote_ip_header .upper ()
171+ webapp .middlewares .insert (0 , remote_ip_header_middleware )
153172
154173 # Ensure these folders exists, otherwise add_static() will complain.
155174 os .makedirs (f"{ instance .folder } /File" , exist_ok = True )
0 commit comments