134 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
			
		
		
	
	
			134 lines
		
	
	
		
			3.8 KiB
		
	
	
	
		
			Python
		
	
	
		
			Executable File
		
	
	
#!/usr/bin/env python
 | 
						|
# -*- coding: utf-8 -*-
 | 
						|
 | 
						|
# Copyright 2008 (C) Pierre Duquesne <stackp@online.fr>
 | 
						|
# 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 ('<html><body><pre>' +
 | 
						|
            '\n'.join(['<a href="%s">%s</a>' % (root + f, f) for f in keys])+
 | 
						|
            '</pre></body></html>').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'
 | 
						|
 | 
						|
 |