#!/usr/bin/env python # -*- coding: utf-8 -*- # Copyright 2008 (C) Pierre Duquesne # Licensed under the Python Software Foundation License # (http://www.python.org/psf/license/) # 20081219 - Initial release import BaseHTTPServer import SocketServer import mimetypes import optparse import socket socket.setdefaulttimeout(3 * 60) import urllib import shutil import sys import os files = {} password = "" def make_index(): keys = files.keys() keys.sort() if password: root = '/' + password + '/' else: root = '/' return ('
' + 
            '\n'.join(['%s' % (root + f, f) for f in keys])+
            '
').encode('utf-8') class HTTPRequestHandler(BaseHTTPServer.BaseHTTPRequestHandler): protocol_version = "HTTP/1.0" def do_GET(self): path = urllib.unquote(self.path) if password != '': if path[:len(password)+1] != '/' + password: return path = path[len(password)+1:] if path.lstrip('/') == '': self.send_response(200) self.send_header('Content-type', 'text/html; charset=utf-8') self.end_headers() self.wfile.write(make_index()) else: filename = path.lstrip('/') if filename in files: localpath = files[filename] f = open(localpath, 'rb') self.send_response(200) self.send_header('Content-type', mimetypes.guess_type(localpath)[0]) self.send_header('Content-length', os.fstat(f.fileno())[6]) self.end_headers() shutil.copyfileobj(f, self.wfile) else: self.send_response(404) self.end_headers() class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer): pass def parse_args(): "Parse command-line arguments." usage = "weblink [options] FILE1 [FILE2 ...]" parser = optparse.OptionParser(usage=usage) parser.add_option('-p', dest='port', type='int', default=8888, help="set the port") parser.add_option('--pass', dest='password', default=None, help="set the url-based password") parser.add_option('--randompass', dest='randompass', default=False, action='store_true', help="generate a random url-based password") options, remainder = parser.parse_args(sys.argv[1:]) return options, remainder if __name__ == '__main__': options, args = parse_args() if options.password: password = options.password if options.randompass: import random import string charset = string.ascii_letters + string.digits password = ''.join(random.sample(charset, 30)) port = options.port # -- Insert file names in the global dictionary ``files`` for f in args: if not os.path.exists(f): print "%s does not exist, skipping." % f continue if os.path.isdir(f): print "%s is a directory, skipping." % f continue base = os.path.basename(f) # Get a unique name for the file # (for example, /a/file.txt and /b/file.txt will be called # file.txt and file-1.txt) i = 1 root, ext = os.path.splitext(base) while (base in files): base = "%s-%d%s" % (root, i, ext) i = i+1 files[base] = f print "" print "HTTP server running at http://localhost:%d/%s" % (port, password) try: ThreadedHTTPServer(('', port), HTTPRequestHandler).serve_forever() except KeyboardInterrupt: print '^C received, shutting down server'