#!/usr/bin/env python2.7 # -*- coding: utf-8 -*- import cgi import logging import os ''' Factory to make the request handler and add arguments to it. It exists to allow the handler to access the opts.path variable locally. ''' class HTTPRequestHandler: def do_GET(BaseHTTPRequestHandler): m_BaseHTTPRequest = BaseHTTPRequestHandler # Parse out the arguments. # The arguments follow a '?' in the URL. Here is an example: # http://example.com?arg1=val1 args = {} idx = m_BaseHTTPRequest.path.find('?') if idx >= 0: rpath = m_BaseHTTPRequest.path[:idx] args = cgi.parse_qs(m_BaseHTTPRequest.path[idx+1:]) else: rpath = m_BaseHTTPRequest.path # Print out logging information about the path and args. if 'content-type' in m_BaseHTTPRequest.headers: ctype, _ = cgi.parse_header(m_BaseHTTPRequest.headers['content-type']) logging.debug('TYPE %s' % (ctype)) logging.debug('PATH %s' % (rpath)) logging.debug('ARGS %d' % (len(args))) if len(args): i = 0 for key in sorted(args): logging.debug('ARG[%d] %s=%s' % (i, key, args[key])) i += 1 # Check to see whether the file is stored locally, # if it is, display it. # Get the file path. path = HTTPRequestHandler.m_opts.rootdir + rpath dirpath = None logging.debug('FILE %s' % (path)) # If it is a directory look for index.html # or process it directly if there are 3 # trailing slashed. if rpath[-3:] == '///': dirpath = path elif os.path.exists(path) and os.path.isdir(path): dirpath = path # the directory portion index_files = ['/index.html', '/index.htm', ] for index_file in index_files: tmppath = path + index_file if os.path.exists(tmppath): path = tmppath break # Allow the user to type "///" at the end to see the # directory listing. if os.path.exists(path) and os.path.isfile(path): # This is valid file, send it as the response # after determining whether it is a type that # the server recognizes. _, ext = os.path.splitext(path) ext = ext.lower() content_type = { '.css': 'text/css', '.gif': 'image/gif', '.htm': 'text/html', '.html': 'text/html', '.jpeg': 'image/jpeg', '.jpg': 'image/jpg', '.js': 'text/javascript', '.png': 'image/png', '.text': 'text/plain', '.txt': 'text/plain', } # If it is a known extension, set the correct # content type in the response. if ext in content_type: m_BaseHTTPRequest.send_response(200) # OK m_BaseHTTPRequest.send_header('Content-type', content_type[ext]) m_BaseHTTPRequest.end_headers() with open(path) as ifp: m_BaseHTTPRequest.wfile.write(ifp.read()) else: # Unknown file type or a directory. # Treat it as plain text. m_BaseHTTPRequest.send_response(200) # OK m_BaseHTTPRequest.send_header('Content-type', 'text/plain') m_BaseHTTPRequest.end_headers() with open(path) as ifp: m_BaseHTTPRequest.wfile.write(ifp.read()) elif 1 == 2: # There is special handling for http://127.0.0.1/info. That URL # displays some internal information. if m_BaseHTTPRequest.path == '/info' or m_BaseHTTPRequest.path == '/info/': m_BaseHTTPRequest.send_response(200) # OK m_BaseHTTPRequest.send_header('Content-type', 'text/html') m_BaseHTTPRequest.end_headers() m_BaseHTTPRequest.info() else: if dirpath is None or m_BaseHTTPRequest.m_opts.no_dirlist == True: # Invalid file path, respond with a server access error m_BaseHTTPRequest.send_response(500) # generic server error for now m_BaseHTTPRequest.send_header('Content-type', 'text/html') m_BaseHTTPRequest.end_headers() m_BaseHTTPRequest.wfile.write('') m_BaseHTTPRequest.wfile.write('
') m_BaseHTTPRequest.wfile.write('Server access error.
') m_BaseHTTPRequest.wfile.write('%r
' % (repr(m_BaseHTTPRequest.path))) m_BaseHTTPRequest.wfile.write(' ' % (rpath)) m_BaseHTTPRequest.wfile.write(' ') m_BaseHTTPRequest.wfile.write('') else: # List the directory contents. Allow simple navigation. logging.debug('DIR %s' % (dirpath)) m_BaseHTTPRequest.send_response(200) # OK m_BaseHTTPRequest.send_header('Content-type', 'text/html') m_BaseHTTPRequest.end_headers() m_BaseHTTPRequest.wfile.write('') m_BaseHTTPRequest.wfile.write(' ') m_BaseHTTPRequest.wfile.write('Directory: %s
' % (dirstr)) # Write out the simple directory list (name and size). m_BaseHTTPRequest.wfile.write('| ') path = rpath + '/' + fname fpath = os.path.join(dirpath, fname) if os.path.isdir(path): m_BaseHTTPRequest.wfile.write(' %s/' % (path, fname)) else: m_BaseHTTPRequest.wfile.write(' %s' % (path, fname)) m_BaseHTTPRequest.wfile.write(' | ') m_BaseHTTPRequest.wfile.write(' ') m_BaseHTTPRequest.wfile.write(' | %d | ' % (os.path.getsize(fpath))) m_BaseHTTPRequest.wfile.write('