#!/usr/bin/python import sys # Python 3. try: from http.server import HTTPServer from http.server import SimpleHTTPRequestHandler # Python 2. except ImportError: from BaseHTTPServer import HTTPServer from SimpleHTTPServer import SimpleHTTPRequestHandler import glob import os import base64 class HTTPRequestHandler(SimpleHTTPRequestHandler): # Implementation. def do_GET(self): tool.process(self) def do_POST(self): tool.process(self) def listFiles(path): items = [] fileNames = glob.glob(path + "/*") fileNames.sort() for fileName in fileNames: file = { } # Path. file["path"] = os.path.basename(fileName) # Type. file["type"] = None if (os.path.isdir(fileName)): file["type"] = "dir" elif (os.path.isfile(fileName)): file["type"] = "file"; items.append(file) return items def fileListToJSON(fileList): out = "" for file in fileList: if (len(out)): out += "," out += "{\"path\":\"%s\",\"type\":\"%s\"}" % (file["path"], file["type"]) return "[" + out + "]" def jsonToPathContents(json): # This function takes `abc` and `def` from string of the following format: # `{"path": "abc", "contents": "def"}`. parts = json.split('"') if (len(parts) == 9): return (parts[3], parts[7]) return (None, None) class Tool(object): # Configuration. def __init__(self, arguments): self.arguments = arguments self.PORT = 8000 self.serverHost = "" # Main execution sequence. def run(self): self.validateArguments() self.parseArguments() self.printArguments() self.runServer() # Implementation. def validateArguments(self): if (len(self.arguments) < 2): print( ( "Usage: %s DIR [PORT]" "\n\n" "\tPORT defaults to 8000" ) % self.arguments[0] ) sys.exit(1) def printArguments(self): print("DIR: '%s'" % self.DIR) print("PORT: '%s'" % self.PORT) def parseArguments(self): self.DIR = self.arguments[1] # Override default port if specified. if (len(self.arguments) >= 3): self.PORT = self.arguments[2] def runServer(self): addr = (self.serverHost, int(self.PORT)) self.httpd = HTTPServer(addr, HTTPRequestHandler) self.httpd.serve_forever() def process(self, requestHandler): if (requestHandler.path == "/path"): self.processPath(requestHandler) if (requestHandler.path == "/list"): self.processFileList(requestHandler) if (requestHandler.path == "/read"): self.processReadFile(requestHandler) if (requestHandler.path == "/write"): self.processWriteFile(requestHandler) def processPath(self, request): request.send_response(200) request.send_header("Access-Control-Allow-Origin", "*") request.end_headers() data = self.DIR.encode() request.wfile.write(data) def processFileList(self, request): request.send_response(200) request.send_header("Access-Control-Allow-Origin", "*") request.end_headers() size = int(request.headers["Content-Length"]) path = request.rfile.read(size) path = path.decode() absPath = "%s/%s" % (self.DIR, path) fileList = listFiles(absPath) fileListJSON = fileListToJSON(fileList) data = fileListJSON.encode() request.wfile.write(data) def processReadFile(self, request): request.send_response(200) request.send_header("Access-Control-Allow-Origin", "*") request.end_headers() size = int(request.headers["Content-Length"]) path = request.rfile.read(size) path = path.decode() absPath = "%s/%s" % (self.DIR, path) print("Reading '%s'" % absPath) f = open(absPath, "r") contents = f.read() f.close() # Perform Python3 compatible encoding. # If this crashes for Python2 (when there are non-ASCII symbols), # it's probably fine for `contents` to stay intact. try: contents = contents.encode() except: pass request.wfile.write(contents) def processWriteFile(self, request): request.send_response(200) request.send_header("Access-Control-Allow-Origin", "*") request.end_headers() size = int(request.headers["Content-Length"]) data = request.rfile.read(size) # Extract path and contents. (path, contents) = jsonToPathContents(data) if ((path is None) or (contents is None)): print("ERROR Writing failed due to corrupt incoming data") # Try to convert using pre-Python2.4 API. try: contents = base64.decodestring(contents) # Resort to Python2.4+ API. except: contents = base64.b64decode(contents) # Perform Python3 compatible DEcoding. # If this crashes for Python2 (when there are non-ASCII symbols), # it's probably fine for `contents` to stay intact. try: contents = contents.decode() except: pass # Write. absPath = "%s/%s" % (self.DIR, path) print("Writing '%s'" % absPath) f = open(absPath, "w") f.write(contents) f.close() tool = Tool(sys.argv) tool.run()