configurationengine/source/cone/storage/tests/simplewebserver.py
changeset 0 2e8eeb919028
equal deleted inserted replaced
-1:000000000000 0:2e8eeb919028
       
     1 #
       
     2 # Copyright (c) 2009 Nokia Corporation and/or its subsidiary(-ies).
       
     3 # All rights reserved.
       
     4 # This component and the accompanying materials are made available
       
     5 # under the terms of "Eclipse Public License v1.0"
       
     6 # which accompanies this distribution, and is available
       
     7 # at the URL "http://www.eclipse.org/legal/epl-v10.html".
       
     8 #
       
     9 # Initial Contributors:
       
    10 # Nokia Corporation - initial contribution.
       
    11 #
       
    12 # Contributors:
       
    13 #
       
    14 # Description:
       
    15 #
       
    16 
       
    17 import SimpleHTTPServer
       
    18 import SocketServer
       
    19 import threading
       
    20 import httplib
       
    21 import os
       
    22 import simplejson
       
    23 import urllib
       
    24 import urlparse
       
    25 import posixpath
       
    26 import cgi
       
    27 from StringIO import StringIO
       
    28 
       
    29 class SimpleWebHandler(SimpleHTTPServer.SimpleHTTPRequestHandler):
       
    30     def __init__(self, request, client_address, server):
       
    31         SimpleHTTPServer.SimpleHTTPRequestHandler.__init__(self, request, client_address, server)
       
    32         self.action = ''
       
    33 
       
    34     def send_head(self):
       
    35         """Common code for GET and HEAD commands.
       
    36 
       
    37         This sends the response code and MIME headers.
       
    38 
       
    39         Return value is either a file object (which has to be copied
       
    40         to the outputfile by the caller unless the command was HEAD,
       
    41         and must be closed by the caller under all circumstances), or
       
    42         None, in which case the caller has nothing further to do.
       
    43 
       
    44         """
       
    45         (action,path) = self.translate_path(self.path)
       
    46         
       
    47         if action == 'list_resources':
       
    48             return self.list_directory(path)
       
    49         elif action == 'get_resource':
       
    50             return self.get_resource(path) 
       
    51         else:
       
    52             self.send_error(404, "File not found")
       
    53             return None
       
    54 
       
    55     def get_resource(self,path):
       
    56         f = None
       
    57         ctype = self.guess_type(path)
       
    58         if ctype.startswith('text/'):
       
    59             mode = 'r'
       
    60         else:
       
    61             mode = 'rb'
       
    62         try:
       
    63             f = open(path, mode)
       
    64         except IOError:
       
    65             self.send_error(404, "File not found")
       
    66             return None
       
    67         self.send_response(200)
       
    68         self.send_header("Content-type", ctype)
       
    69         fs = os.fstat(f.fileno())
       
    70         self.send_header("Content-Length", str(fs[6]))
       
    71         self.send_header("Last-Modified", self.date_time_string(fs.st_mtime))
       
    72         self.end_headers()
       
    73         return f
       
    74 
       
    75     def list_directory(self, path):
       
    76         """Helper to produce a directory listing (absent index.html).
       
    77 
       
    78         Return value is either a file object, or None (indicating an
       
    79         error).  In either case, the headers are sent, making the
       
    80         interface the same as for send_head().
       
    81 
       
    82         """
       
    83         try:
       
    84             list = os.listdir(path)
       
    85         except os.error:
       
    86             self.send_error(404, "No permission to list directory")
       
    87             return None
       
    88         list.sort(key=lambda a: a.lower())
       
    89         f = StringIO()
       
    90         displaypath = cgi.escape(urllib.unquote(self.path))
       
    91         files = []
       
    92         for name in list:
       
    93             fullname = os.path.join(path, name)
       
    94             displayname = linkname = name
       
    95             # Append / for directories or @ for symbolic links
       
    96             if os.path.isdir(fullname):
       
    97                 displayname = name + "/"
       
    98                 linkname = name + "/"
       
    99             if os.path.islink(fullname):
       
   100                 displayname = name + "@"
       
   101                 # Note: a link to a directory displays with @ and links with /
       
   102             files.append(displayname)
       
   103         
       
   104         f.write(simplejson.dumps(files))
       
   105         length = f.tell()
       
   106         f.seek(0)
       
   107         self.send_response(200)
       
   108         self.send_header("Content-type", "text/html")
       
   109         self.send_header("Content-Length", str(length))
       
   110         self.end_headers()
       
   111         return f
       
   112 
       
   113     def translate_path(self, path):
       
   114         """Translate a /-separated PATH to the local filename syntax.
       
   115 
       
   116         Components that mean special things to the local file system
       
   117         (e.g. drive or directory names) are ignored.  (XXX They should
       
   118         probably be diagnosed.)
       
   119         @return: action,path
       
   120         """
       
   121         # abandon query parameters
       
   122         action = ''
       
   123         path = urlparse.urlparse(path)[2]
       
   124         path = path.lstrip('/')
       
   125         splittedpath = path.split('/')
       
   126         if len(splittedpath) > 1:
       
   127             action = splittedpath[1]
       
   128             path   = "/".join(splittedpath[2:])
       
   129             path = posixpath.normpath(urllib.unquote(path))
       
   130             words = path.split('/')
       
   131             words = filter(None, words)
       
   132             path = os.getcwd()
       
   133             for word in words:
       
   134                 drive, word = os.path.splitdrive(word)
       
   135                 head, word = os.path.split(word)
       
   136                 if word in (os.curdir, os.pardir): continue
       
   137                 path = os.path.join(path, word)
       
   138         return (action,path)
       
   139         
       
   140 
       
   141 class SimpleWebServer(threading.Thread):
       
   142     def __init__(self, folder=".", port=8000):
       
   143         super(SimpleWebServer,self).__init__()
       
   144         self.PORT    = port
       
   145         self.folder  = folder
       
   146         self.handler = SimpleWebHandler
       
   147         self.httpd   = SocketServer.TCPServer(("localhost", self.PORT), self.handler)
       
   148         self.active  = False
       
   149         print "serving at port", self.PORT
       
   150  
       
   151     def run(self):
       
   152         # minimal web server.  serves files relative to the
       
   153         # current directory.
       
   154         os.chdir(self.folder)
       
   155         self.active = True
       
   156         while self.active:
       
   157             self.httpd.handle_request()
       
   158         return 0
       
   159 
       
   160     def stop(self):
       
   161         self.active = False
       
   162         conn = httplib.HTTPConnection('localhost', self.PORT)
       
   163         conn.request("GET", "/")
       
   164         r1 = conn.getresponse()
       
   165         print r1.status, r1.reason
       
   166 
       
   167 if __name__ == '__main__':
       
   168     server = SimpleWebServer()
       
   169     server.start()