From dfe26cd5ba27e2d7b22c79e1e7b8fc627dc60cee Mon Sep 17 00:00:00 2001 From: Thomas Leonard Date: Sat, 13 Dec 2008 20:28:49 +0000 Subject: [PATCH] Use HTTP protocol for requesting implementations --- 0share | 2 +- client.py | 25 ++++++++++++++++++------- server.py | 35 +++++++++++++++++++++++++---------- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/0share b/0share index d83c645..67065d8 100755 --- a/0share +++ b/0share @@ -6,7 +6,7 @@ from optparse import OptionParser from logging import info, debug version = '0.1' -port = 308339 +port = 38339 parser = OptionParser(usage="usage: %prog\n" "usage: %prog --fetch DIGEST...") diff --git a/client.py b/client.py index 92586d4..e2aea8e 100644 --- a/client.py +++ b/client.py @@ -3,8 +3,9 @@ from logging import info, debug import socket, sys, select +import httplib -port = 308339 +port = 38339 def fetch(host, digests): if not digests: @@ -26,7 +27,7 @@ def fetch(host, digests): needed = set(digests) n_responses = 0 - while True: + while needed: r = select.select([client], [], [], 1)[0] if r: data, addr = client.recvfrom(128) @@ -45,13 +46,23 @@ def fetch(host, digests): info("Invalid reply from %s: %s", addr, repr(data)) else: break - if n_responses: - info("No further responses for one second") + if needed: + if n_responses: + info("No further responses for one second") + else: + info("No responses within one second") + for x in needed: + print "Failed to fetch", x else: - info("No responses within one second") + print "Success" def fetch_impl(digest, addr): info("Connecting to %s to request %s", addr, digest) - client = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) - client.connect((addr, port)) + client = httplib.HTTPConnection(addr, port, strict = True) + client.request('GET', '/implementation/' + digest) + response = client.getresponse() + + if response.status != 200: + raise Exception("Error fetching implementation (%d): %s" % (response.status, response.reason)) + info("Got: %s", response.read()) client.close() diff --git a/server.py b/server.py index f4609d0..de93caf 100644 --- a/server.py +++ b/server.py @@ -4,6 +4,7 @@ from logging import info, debug import socket import select +from BaseHTTPServer import HTTPServer, BaseHTTPRequestHandler from zeroinstall.zerostore import Stores, BadDigest, NotStored @@ -19,19 +20,15 @@ def serve(host, port): udp_socket.bind((host or '', port)) # The TCP socket is used to send the requested implementations - tcp_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM, 0) - tcp_socket.bind((host or '', port)) - tcp_socket.listen(2) + http_server = HTTPServer((host or '', port), FetchRequestHandler) info("0share started and listening for requests...") while True: - ready = select.select([udp_socket, tcp_socket], [], [])[0] + ready = select.select([udp_socket, http_server.socket], [], [])[0] if udp_socket in ready: handle_query(udp_socket) - if tcp_socket in ready: - client, addr = tcp_socket.accept() - info("Fetch connection from %s", addr) - handle_fetch(client) + if http_server.socket in ready: + http_server.handle_request() def handle_query(ss): data, addr = ss.recvfrom(128) @@ -57,5 +54,23 @@ def handle_query(ss): info("Sending reply...") ss.sendto('0share-reply\n' + '\n'.join(got), addr) -def handle_fetch(client): - client.close() +class FetchRequestHandler(BaseHTTPRequestHandler): + def do_GET(self): + info("GET %s", self.path) + bits = self.path.split('/') + if len(bits) == 3 and bits[0] == '' and bits[1] == 'implementation': + digest = bits[2] + else: + self.send_error(404, "Not an implementation") + return + + try: + path = stores.lookup(digest) + except (BadDigest, NotStored), ex: + info("Lookup error: %s", str(ex)) + self.send_error(404, "Implementation %s not found" % digest) + return + + self.send_response(200, "OK") + self.end_headers() + self.wfile.write('' % path) -- 2.11.4.GIT