-
Notifications
You must be signed in to change notification settings - Fork 5
Expand file tree
/
Copy pathserver.py
More file actions
51 lines (44 loc) · 1.7 KB
/
Copy pathserver.py
File metadata and controls
51 lines (44 loc) · 1.7 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
#!/usr/bin/env python3
import os
import hashlib
from http.server import HTTPServer, SimpleHTTPRequestHandler
from urllib.parse import urlparse, unquote
class ETagRequestHandler(SimpleHTTPRequestHandler):
def send_head(self):
path = self.translate_path(self.path)
if os.path.isdir(path):
return super().send_head()
try:
f = open(path, 'rb')
except OSError:
self.send_error(404, "File not found")
return None
fs = os.fstat(f.fileno())
etag = f'W/"{fs.st_mtime_ns:x}-{fs.st_size:x}"'
ims = self.headers.get('If-Modified-Since')
inm = self.headers.get('If-None-Match')
if inm and inm == etag:
f.close()
self.send_response(304)
self.send_header("ETag", etag)
self.send_header("Cache-Control", "public, max-age=0, must-revalidate")
self.end_headers()
return None
self.send_response(200)
ctype = self.guess_type(path)
self.send_header("Content-type", ctype)
self.send_header("Content-Length", str(fs.st_size))
self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
self.send_header("ETag", etag)
self.send_header("Cache-Control", "public, max-age=0, must-revalidate")
self.end_headers()
return f
def run(addr="0.0.0.0", port=9999, directory="."):
handler = ETagRequestHandler
def factory(*args, **kwargs):
return handler(*args, directory=directory, **kwargs)
httpd = HTTPServer((addr, port), factory)
print(f"Serving on http://{addr}:{port} dir={os.path.abspath(directory)}")
httpd.serve_forever()
if __name__ == "__main__":
run()