diff -r 000000000000 -r 2e8eeb919028 configurationengine/source/cone/storage/tests/simplewebserver.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/configurationengine/source/cone/storage/tests/simplewebserver.py Thu Mar 11 17:04:37 2010 +0200 @@ -0,0 +1,169 @@ +# +# Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies). +# All rights reserved. +# This component and the accompanying materials are made available +# under the terms of "Eclipse Public License v1.0" +# which accompanies this distribution, and is available +# at the URL "http://www.eclipse.org/legal/epl-v10.html". +# +# Initial Contributors: +# Nokia Corporation - initial contribution. +# +# Contributors: +# +# Description: +# + +import SimpleHTTPServer +import SocketServer +import threading +import httplib +import os +import simplejson +import urllib +import urlparse +import posixpath +import cgi +from StringIO import StringIO + +class SimpleWebHandler(SimpleHTTPServer.SimpleHTTPRequestHandler): + def __init__(self, request, client_address, server): + SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server) + self.action = '' + + def send_head(self): + """Common code for GET and HEAD commands. + + This sends the response code and MIME headers. + + Return value is either a file object (which has to be copied + to the outputfile by the caller unless the command was HEAD, + and must be closed by the caller under all circumstances), or + None, in which case the caller has nothing further to do. + + """ + (action,path) = self.translate_path(self.path) + + if action == 'list_resources': + return self.list_directory(path) + elif action == 'get_resource': + return self.get_resource(path) + else: + self.send_error(404, "File not found") + return None + + def get_resource(self,path): + f = None + ctype = self.guess_type(path) + if ctype.startswith('text/'): + mode = 'r' + else: + mode = 'rb' + try: + f = open(path, mode) + except IOError: + self.send_error(404, "File not found") + return None + self.send_response(200) + self.send_header("Content-type", ctype) + fs = os.fstat(f.fileno()) + self.send_header("Content-Length", str(fs[6])) + self.send_header("Last-Modified", self.date_time_string(fs.st_mtime)) + self.end_headers() + return f + + def list_directory(self, path): + """Helper to produce a directory listing (absent index.html). + + Return value is either a file object, or None (indicating an + error). In either case, the headers are sent, making the + interface the same as for send_head(). + + """ + try: + list = os.listdir(path) + except os.error: + self.send_error(404, "No permission to list directory") + return None + list.sort(key=lambda a: a.lower()) + f = StringIO() + displaypath = cgi.escape(urllib.unquote(self.path)) + files = [] + for name in list: + fullname = os.path.join(path, name) + displayname = linkname = name + # Append / for directories or @ for symbolic links + if os.path.isdir(fullname): + displayname = name + "/" + linkname = name + "/" + if os.path.islink(fullname): + displayname = name + "@" + # Note: a link to a directory displays with @ and links with / + files.append(displayname) + + f.write(simplejson.dumps(files)) + length = f.tell() + f.seek(0) + self.send_response(200) + self.send_header("Content-type", "text/html") + self.send_header("Content-Length", str(length)) + self.end_headers() + return f + + def translate_path(self, path): + """Translate a /-separated PATH to the local filename syntax. + + Components that mean special things to the local file system + (e.g. drive or directory names) are ignored. (XXX They should + probably be diagnosed.) + @return: action,path + """ + # abandon query parameters + action = '' + path = urlparse.urlparse(path)[2] + path = path.lstrip('/') + splittedpath = path.split('/') + if len(splittedpath) > 1: + action = splittedpath[1] + path = "/".join(splittedpath[2:]) + path = posixpath.normpath(urllib.unquote(path)) + words = path.split('/') + words = filter(None, words) + path = os.getcwd() + for word in words: + drive, word = os.path.splitdrive(word) + head, word = os.path.split(word) + if word in (os.curdir, os.pardir): continue + path = os.path.join(path, word) + return (action,path) + + +class SimpleWebServer(threading.Thread): + def __init__(self, folder=".", port=8000): + super(SimpleWebServer,self).__init__() + self.PORT = port + self.folder = folder + self.handler = SimpleWebHandler + self.httpd = SocketServer.TCPServer(("localhost", self.PORT), self.handler) + self.active = False + print "serving at port", self.PORT + + def run(self): + # minimal web server. serves files relative to the + # current directory. + os.chdir(self.folder) + self.active = True + while self.active: + self.httpd.handle_request() + return 0 + + def stop(self): + self.active = False + conn = httplib.HTTPConnection('localhost', self.PORT) + conn.request("GET", "/") + r1 = conn.getresponse() + print r1.status, r1.reason + +if __name__ == '__main__': + server = SimpleWebServer() + server.start()