Commit 3a3f4991 by willmcgugan@gmail.com

Fixes an issue serving binary files

parent c564dcf1
...@@ -17,15 +17,15 @@ def _datetime_to_epoch(d): ...@@ -17,15 +17,15 @@ def _datetime_to_epoch(d):
return mktime(d.timetuple()) return mktime(d.timetuple())
class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
"""A hacked together version of SimpleHTTPRequestHandler""" """A hacked together version of SimpleHTTPRequestHandler"""
def __init__(self, fs, request, client_address, server): def __init__(self, fs, request, client_address, server):
self._fs = fs self._fs = fs
SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server) SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
def do_GET(self): def do_GET(self):
"""Serve a GET request.""" """Serve a GET request."""
f = None f = None
try: try:
f = self.send_head() f = self.send_head()
...@@ -33,10 +33,10 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): ...@@ -33,10 +33,10 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
try: try:
self.copyfile(f, self.wfile) self.copyfile(f, self.wfile)
except socket.error: except socket.error:
pass pass
finally: finally:
if f is not None: if f is not None:
f.close() f.close()
def send_head(self): def send_head(self):
"""Common code for GET and HEAD commands. """Common code for GET and HEAD commands.
...@@ -65,15 +65,15 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): ...@@ -65,15 +65,15 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
break break
else: else:
return self.list_directory(path) return self.list_directory(path)
ctype = self.guess_type(path) ctype = self.guess_type(path)
try: try:
info = self._fs.getinfo(path) info = self._fs.getinfo(path)
f = self._fs.open(path, 'r') f = self._fs.open(path, 'rb')
except FSError, e: except FSError, e:
self.send_error(404, str(e)) self.send_error(404, str(e))
return None return None
self.send_response(200) self.send_response(200)
self.send_header("Content-type", ctype) self.send_header("Content-type", ctype)
self.send_header("Content-Length", str(info['size'])) self.send_header("Content-Length", str(info['size']))
if 'modified_time' in info: if 'modified_time' in info:
self.send_header("Last-Modified", self.date_time_string(_datetime_to_epoch(info['modified_time']))) self.send_header("Last-Modified", self.date_time_string(_datetime_to_epoch(info['modified_time'])))
...@@ -103,11 +103,11 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): ...@@ -103,11 +103,11 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath) f.write("<html>\n<title>Directory listing for %s</title>\n" % displaypath)
f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath) f.write("<body>\n<h2>Directory listing for %s</h2>\n" % displaypath)
f.write("<hr>\n<ul>\n") f.write("<hr>\n<ul>\n")
parent = dirname(path) parent = dirname(path)
if path != parent: if path != parent:
f.write('<li><a href="%s">../</a></li>' % urllib.quote(parent.rstrip('/') + '/')) f.write('<li><a href="%s">../</a></li>' % urllib.quote(parent.rstrip('/') + '/'))
for path in paths: for path in paths:
f.write('<li><a href="%s">%s</a>\n' f.write('<li><a href="%s">%s</a>\n'
% (urllib.quote(path), cgi.escape(path))) % (urllib.quote(path), cgi.escape(path)))
...@@ -119,45 +119,45 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): ...@@ -119,45 +119,45 @@ class FSHTTPRequestHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
self.send_header("Content-Length", str(length)) self.send_header("Content-Length", str(length))
self.end_headers() self.end_headers()
return f return f
def translate_path(self, path): def translate_path(self, path):
# abandon query parameters # abandon query parameters
path = path.split('?',1)[0] path = path.split('?',1)[0]
path = path.split('#',1)[0] path = path.split('#',1)[0]
path = posixpath.normpath(urllib.unquote(path)) path = posixpath.normpath(urllib.unquote(path))
return path return path
def serve_fs(fs, address='', port=8000): def serve_fs(fs, address='', port=8000):
"""Serve an FS instance over http """Serve an FS instance over http
:param fs: an FS object :param fs: an FS object
:param address: IP address to serve on :param address: IP address to serve on
:param port: port number :param port: port number
""" """
def Handler(request, client_address, server): def Handler(request, client_address, server):
return FSHTTPRequestHandler(fs, request, client_address, server) return FSHTTPRequestHandler(fs, request, client_address, server)
#class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer): #class ThreadedTCPServer(SocketServer.ThreadingMixIn, SocketServer.TCPServer):
# pass # pass
httpd = SocketServer.TCPServer((address, port), Handler, bind_and_activate=False) httpd = SocketServer.TCPServer((address, port), Handler, bind_and_activate=False)
#httpd = ThreadedTCPServer((address, port), Handler, bind_and_activate=False) #httpd = ThreadedTCPServer((address, port), Handler, bind_and_activate=False)
httpd.allow_reuse_address = True httpd.allow_reuse_address = True
httpd.server_bind() httpd.server_bind()
httpd.server_activate() httpd.server_activate()
server_thread = threading.Thread(target=httpd.serve_forever) server_thread = threading.Thread(target=httpd.serve_forever)
server_thread.start() server_thread.start()
try: try:
while True: while True:
time.sleep(0.1) time.sleep(0.1)
except (KeyboardInterrupt, SystemExit): except (KeyboardInterrupt, SystemExit):
httpd.shutdown() httpd.shutdown()
if __name__ == "__main__": if __name__ == "__main__":
from fs.osfs import OSFS from fs.osfs import OSFS
serve_fs(OSFS('~/')) serve_fs(OSFS('~/'))
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment