-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathserver.py
More file actions
95 lines (79 loc) · 3.08 KB
/
server.py
File metadata and controls
95 lines (79 loc) · 3.08 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
from http.server import BaseHTTPRequestHandler, HTTPServer
import cgi
import os
import sys
import urllib.parse
class FileHandler(BaseHTTPRequestHandler):
def do_GET(self):
# Parse the URL path to get the requested filename
parsed_path = urllib.parse.unquote(self.path.lstrip('/'))
if not parsed_path:
# List files in current directory
self.send_response(200)
self.send_header('Content-Type', 'text/html')
self.end_headers()
files = os.listdir('.')
file_list = '<br>'.join(f'<a href="/{f}">{f}</a>' for f in files if os.path.isfile(f))
self.wfile.write(f"<html><body><h2>Files:</h2>{file_list}</body></html>".encode())
return
# Security: prevent directory traversal
filename = os.path.basename(parsed_path)
if not os.path.isfile(filename):
self.send_response(404)
self.end_headers()
self.wfile.write(b"File not found")
return
# Send the file
self.send_response(200)
self.send_header('Content-Type', 'application/octet-stream')
self.send_header('Content-Disposition', f'attachment; filename="{filename}"')
self.send_header('Content-Length', os.path.getsize(filename))
self.end_headers()
with open(filename, 'rb') as f:
self.wfile.write(f.read())
def do_POST(self):
# Parse content type and boundary
content_type, params = cgi.parse_header(self.headers.get('Content-Type'))
if content_type != 'multipart/form-data':
self.send_response(400)
self.end_headers()
return
# Parse the form data
form = cgi.FieldStorage(
fp=self.rfile,
headers=self.headers,
environ={'REQUEST_METHOD': 'POST'}
)
# Get the file field (assuming the field name is 'file')
if 'file' not in form:
self.send_response(400)
self.end_headers()
self.wfile.write(b"No file uploaded")
return
file_item = form['file']
if not file_item.filename:
self.send_response(400)
self.end_headers()
self.wfile.write(b"No filename")
return
# Save the file
filename = os.path.basename(file_item.filename)
with open(filename, 'wb') as f:
f.write(file_item.file.read())
# Respond
self.send_response(200)
self.end_headers()
self.wfile.write(f"File '{filename}' uploaded successfully".encode())
if __name__ == '__main__':
if len(sys.argv) != 3:
print(f"Usage: {sys.argv[0]} <ip> <port>")
print(f"Example: {sys.argv[0]} 0.0.0.0 8000")
sys.exit(1)
ip = sys.argv[1]
port = int(sys.argv[2])
server = HTTPServer((ip, port), FileHandler)
print(f"Server running at http://{ip}:{port}")
print("GET / - List files")
print("GET /<file> - Download file")
print("POST / - Upload file (multipart/form-data, field: 'file')")
server.serve_forever()