Until we've got the full arsenal of remote access tools ready and running on Minoca OS, we thought we'd share an extremely simple script we sometimes use to pull files off of the OS. It's basically a wrapper around Python's built in BaseHttpServer that serves files and directory listings.

Note that if you're using our Qemu demo, you won't be able to access the web server created by this script. This is because Qemu sets up its networking behind a virtual NAT, which means that while the Qemu guest can make outgoing connections, its IP is not directly accessible from your host machine.

When the script is fired up, it serves its current working directory. If you pass a URL containing a file in that directory, it serves the file. If you pass a URL to a directory, it serves a simple view of the directory contents.

Note that under no circumstances should this be used in a production environment or on a machine that is directly accessible by the Internet. Not only is it a poor design for a web server, it's also extremely insecure (for example, it does not guard against using .. to go up beyond the current working directory it started in). It is handy during development and test though.

License: Feel free to copy, modify, butcher, or destroy this script to suit your purposes.

## ## Copyright (c) 2014 Minoca Corp. ## ## Script Name: ## ## httpserver.py ## ## Abstract: ## ## This script runs a small HTTP server in the current directory. ## ## Environment: ## ## Python ## from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer import os import stat import time class MinocaHTTPRequestHandler(BaseHTTPRequestHandler): def do_GET(self): path = '.' + self.path try: if os.path.isdir(path): result = get_dir_contents(path) else: f = open(path) result = f.read() f.close() self.send_response(200) self.send_header('Content-Type', 'text-html') self.end_headers() self.wfile.write(result) except IOError: self.send_error(404, 'File not found!!') def run(): print('Firing up HTTP Server...') server_address = ('', 8000) httpd = HTTPServer(server_address, MinocaHTTPRequestHandler) print('HTTP Server is running...') httpd.serve_forever() def get_dir_contents(path): files = os.listdir(path) listings = '' for filename in files: listings += get_dir_file_listing(path, filename) title = 'Listing of %s' % path table = '<table border="0">%s</table>' % listings result = '<html><head></head><body><h2><p>%s</p></h2>%s</body></html>' % \ (title, table) return result def get_dir_file_listing(path, filename): complete_path = os.path.join(path, filename) info = os.stat(complete_path) file_type = '?' if stat.S_ISDIR(info.st_mode): file_type = 'd' elif stat.S_ISLNK(info.st_mode): file_type = 'l' elif stat.S_ISREG(info.st_mode): file_type = '-' permissions = get_permission_string(info.st_mode) mod_time = get_file_time_string(info.st_mtime) name = '<a href="/%s">%s</a>' % (complete_path.replace('\\', '/'), filename) format = '<tr><td>%s%s</td>' \ '<td>%d</td>' \ '<td>%d</td>' \ '<td>%d</td>' \ '<td>%d</td>' \ '<td>%s</td>' \ '<td>%s</td></tr>' result = format % (file_type, permissions, info.st_nlink, info.st_uid, info.st_gid, info.st_size, mod_time, name) return result def get_permission_string(mode): user = get_permission_group_string(mode & stat.S_IRUSR, mode & stat.S_IWUSR, mode & stat.S_IXUSR) group = get_permission_group_string(mode & stat.S_IRGRP, mode & stat.S_IWGRP, mode & stat.S_IXGRP) other = get_permission_group_string(mode & stat.S_IROTH, mode & stat.S_IWOTH, mode & stat.S_IXOTH) return '%s%s%s' % (user, group, other) def get_permission_group_string(read, write, execute): result = '%s%s%s' % (get_bit_or_dash(read, 'r'), get_bit_or_dash(write, 'w'), get_bit_or_dash(execute, 'x')) return result def get_bit_or_dash(bit, value): if bit: return value return '-' def get_file_time_string(filetime): return time.strftime('%Y-%m-%d %H:%M', time.localtime(filetime)) if __name__ == '__main__': run()