-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathBasicHttpServer.py
More file actions
101 lines (75 loc) · 2.81 KB
/
BasicHttpServer.py
File metadata and controls
101 lines (75 loc) · 2.81 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
96
97
98
99
100
101
from Tug.Protocol import Protocol
from Tug.Storage.Filesystem import Filesystem
from Tug.Util import Checksum
from Tug.Artefacts.Blob import Blob
from Tug.Artefacts.File import File
from Tug.Artefacts.Map import Map
from Tug.Artefacts.Key import Key
from http.server import HTTPServer
from http.server import BaseHTTPRequestHandler
import queue
store = Filesystem("store")
protocol = Protocol(store)
class BasicHttpServer(BaseHTTPRequestHandler):
def do_GET(self):
self.done = False
# Attempt to get the artefact
subject = protocol.retrieve_artefact(Checksum.parse(self.path[1:]))
subject.subscribe(self.got_artefact, self.error)
while not self.done:
pass
def got_artefact(self, artefact):
if(isinstance(artefact, Blob)):
self.handle_blob(artefact)
if(isinstance(artefact, File)):
self.handle_file(artefact)
if(isinstance(artefact, Map)):
self.handle_map(artefact)
if(isinstance(artefact, Key)):
self.handle_key(artefact)
def handle_key(self, artefact: Key):
self.done = True
pass
def handle_map(self, artefact: Map):
self.send_response(200)
self.end_headers()
html = """
<h1>Map Listing for {}</h1>
<hr/>
<ul>
""".format(Checksum.stringify(artefact.checksum))
for entry in artefact.destinations:
html += """
<li><a href="/{}">{}</a></li>
""".format(Checksum.stringify(entry.reference.checksum), entry.name)
html += """</ul>"""
self.wfile.write(html.encode("utf-8"))
self.wfile.flush()
self.done = True
def handle_file(self, artefact: File):
blob_queue = queue.Queue()
for reference in artefact.blob_refs:
blob_queue.put(reference)
def write_blob(blob: Blob):
self.wfile.write(blob.blob_data_stream().read())
self.wfile.flush()
if(blob_queue.qsize() > 0):
ref = blob_queue.get()
protocol.retrieve_artefact(ref.checksum).subscribe(write_blob, self.error)
else:
self.done = True
self.send_response(200)
self.end_headers()
ref = blob_queue.get()
protocol.retrieve_artefact(ref.checksum).subscribe(write_blob, self.error)
def handle_blob(self, artefact: Blob):
self.send_response(200)
self.end_headers()
self.wfile.write(artefact.blob_data_stream().read())
self.wfile.flush()
self.done = True
def error(self, exception):
self.send_error(404, "Could not retreive artefact '{}'".format(self.path[1:]), str(exception))
self.done = True
httpd = HTTPServer(('localhost', 8080), BasicHttpServer)
httpd.serve_forever()