@@ -19,16 +19,16 @@ def __init__(self, *args, **kwargs):
1919 self .organize_uploads = kwargs .pop ('organize_uploads' , False )
2020 super ().__init__ (* args , ** kwargs )
2121
22- # Definer our handler method for restricting access by client ip
22+ # Define our handler method for restricting access by client ip
2323 def restrict_access (self ):
2424 if not self .allowed_ip :
25- # No IP restriction, allow access
25+ # Access is permitted by default
2626 return True
2727
28- # Obtain client ip
28+ # Obtain the client ip
2929 client_ip = ip_address (self .client_address [0 ])
3030
31- # Parse through each entry in allowed_ips
31+ # Cycle through each entry in allowed_ips for permitted access
3232 allowed_ips = self .allowed_ip .split (',' )
3333 for ip in allowed_ips :
3434 ip = ip .strip ()
@@ -43,22 +43,25 @@ def restrict_access(self):
4343 elif client_ip == ip_address (ip ):
4444 return True
4545
46- # If none of the addresses check out, send a 403
46+ # The client ip is not permitted access to the handler
47+ # Respond back to the client with a 403 status code
4748 self .send_response (403 )
4849 self .end_headers ()
4950 return False
5051
5152 # Define our GET handler method
5253 def do_GET (self ):
5354 if self .path == '/' :
54- # Check access restrictions
55+ # Check if we are restricting access
5556 if not self .restrict_access ():
5657 return
5758
58- # Send HTTP response status code 200 back to the client
59+ # Respond back to the client with a 200 status code
5960 self .send_response (200 )
6061 self .send_header ('Content-type' , 'text/html' )
6162 self .end_headers ()
63+
64+ # Send an HTML response to the client with the upload form
6265 self .wfile .write (b"""
6366 <!DOCTYPE html>
6467 <html>
@@ -77,7 +80,7 @@ def do_GET(self):
7780 # Define our POST handler method
7881 def do_POST (self ):
7982 if self .path == '/' :
80- # Check access restrictions
83+ # Check if we are restricting access
8184 if not self .restrict_access ():
8285 return
8386
@@ -97,34 +100,36 @@ def do_POST(self):
97100
98101 for part in parts :
99102 if b'filename="' in part :
100- # Extract filename from Content-Disposition header
103+ # Extract the filename from Content-Disposition header
101104 headers , data = part .split (b'\r \n \r \n ' , 1 )
102105 content_disposition = headers .decode ()
103106 filename = re .search (r'filename="(.+)"' , content_disposition ).group (1 )
104107
105- # Sanitize the filename
108+ # Sanitize the filename based on our requirements
106109 filename = sanitize_filename (filename )
107110
108- # Organize uploads into subfolders by remote client IP
111+ # Organize uploads into subfolders by client IP otherwise use the default
109112 if self .organize_uploads and self .client_address :
110113 client_ip = self .client_address [0 ]
111114 upload_folder = os .path .join (self .upload_folder , client_ip )
112115 os .makedirs (upload_folder , exist_ok = True )
113116 file_path = os .path .join (upload_folder , filename )
114117 else :
115- upload_folder = self .upload_folder # Use the original upload folder
118+ upload_folder = self .upload_folder
116119 file_path = os .path .join (upload_folder , filename )
117120
118121 # Generate a unique filename in case the file already exists
119122 file_path = prevent_clobber (upload_folder , filename )
120123
121- # Save the uploaded file in binary mode
124+ # Save the uploaded file in binary mode so we don't corrupt any content
122125 with open (file_path , 'wb' ) as f :
123126 f .write (data )
124127
125- # Send HTTP response status code 200 back to the client
128+ # Respond back to the client with a 200 status code
126129 self .send_response (200 )
127130 self .end_headers ()
131+
132+ # Send an HTML response to the client for redirection
128133 self .wfile .write (b"""
129134 <!DOCTYPE html>
130135 <html>
@@ -137,24 +142,25 @@ def do_POST(self):
137142 </html>
138143 """ )
139144
140- # Print the path where the uploaded file was saved
145+ # Print the path where the uploaded file was saved to the terminal
141146 now = datetime .now ().strftime ("%d/%b/%Y %H:%M:%S" )
142147 print (f"{ self .client_address [0 ]} - - [{ now } ] \" File saved { file_path } \" " )
143148 return
144149 except Exception as e :
145150 print (f"Error processing the uploaded file: { str (e )} " )
146151
147- # Send HTTP response status code 400 back to the client
152+ # Something bad happened if we get to this point
153+ # Error details are provided by http.server on the terminal
154+ # Respond back to the client with a 400 status code
148155 self .send_response (400 )
149156 self .end_headers ()
150- self .wfile .write (b'No file uploaded.' )
151157
152158
153159# Normalizes the filename, then remove any characters that are not letters, numbers, underscores, dots, or hyphens
154160def sanitize_filename (filename ):
155- pass1 = os .path .normpath (filename )
156- final = re .sub (r'[^\w.-]' , '_' , pass1 )
157- return final
161+ normalized = os .path .normpath (filename )
162+ sanitized = re .sub (r'[^\w.-]' , '_' , normalized )
163+ return sanitized
158164
159165
160166# Appends a file name with an incrementing number if it happens to exist already
@@ -193,7 +199,7 @@ def main():
193199 parser .print_help ()
194200 sys .exit (1 )
195201
196- # Initializing variables
202+ # Initializing configuration variables
197203 host = args .host
198204 port = args .port
199205 allowed_ip = args .allowed_ip
@@ -206,13 +212,13 @@ def main():
206212 if not os .path .exists (upload_folder ):
207213 os .makedirs (upload_folder )
208214
209- # Create our HTTP request handler with the new parameter
215+ # Create an HTTP server instance with our custom request handling
210216 server = socketserver .TCPServer ((host , port ), lambda * args , ** kwargs : FileUploadHandler (* args , ** kwargs , upload_folder = upload_folder , allowed_ip = allowed_ip , organize_uploads = organize_uploads ))
211217
212- # Output HTTP request handler details
218+ # Print our handler details to the terminal
213219 print (f"[*] Serving HTTP on { host } port { port } (http://{ host } :{ port } /)" )
214220
215- # Output additional details
221+ # Print additional details to the terminal
216222 if allowed_ip :
217223 print (f"[*] Listener access is restricted to { allowed_ip } " )
218224 else :
@@ -223,7 +229,7 @@ def main():
223229 else :
224230 print (f"[*] Uploads will be saved in { upload_folder } " )
225231
226- # Start our HTTP request handler
232+ # Start the HTTP server and keep it running until we stop it
227233 server .serve_forever ()
228234 except KeyboardInterrupt :
229235 print ("\n Keyboard interrupt received, exiting." )
0 commit comments