""" curl phus.lu/fileserver.py | env PORT=8001 python """ import os import re import sys import time try: from http.server import SimpleHTTPRequestHandler, HTTPServer from socketserver import ThreadingMixIn except ImportError: from BaseHTTPServer import SimpleHTTPRequestHandler, HTTPServer from SocketServer import ThreadingMixIn class Handler(SimpleHTTPRequestHandler): def do_GET(self): m = re.search(r'bytes=(\d*)-(\d*)', self.headers.get('Range', '')) if m is None: SimpleHTTPRequestHandler.do_GET(self) return filename = os.path.join(os.getcwd(), self.path[1:].split('?')[0]) begin = int(m.group(1)) if m.group(1) else 0 end = int(m.group(2)) if m.group(2) else 0 end = end if end else os.path.getsize(filename) - 1 length = end - begin + 1 self.send_response(206, 'Partial Content') self.send_header('Accept-Ranges', 'bytes') self.send_header('Content-Length', str(length)) self.send_header('Content-Type', 'application/octet-stream') self.send_header('Last-Modified', time.strftime('%a, %d %b %Y %H:%M:%S GMT', time.gmtime(os.path.getmtime(filename)))) self.end_headers() fd = 0 try: fd = os.open(filename, os.O_RDONLY, 0o666) sendfile = getattr(os, 'sendfile') if sendfile: sendfile(self.wfile.fileno(), fd, begin, length) else: os.lseek(fd, begin, 0) while length: size = length if length < 256*1024 else 256*1024 data = os.read(fd, size) if not data: break self.wfile.write(data) length -= size finally: if fd: os.close(fd) class Server(ThreadingMixIn, HTTPServer): pass if __name__ == '__main__': port = int(sys.argv[1] if len(sys.argv) > 1 else os.environ.get('PORT', '8000')) print('Serving HTTP on 0.0.0.0 port %d ...' % port) Server(('0.0.0.0', port), Handler).serve_forever()