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'
 | |
| 
 | |
| 
 |