Changeset 6999 for ceda_http_fileserver


Ignore:
Timestamp:
11/06/10 16:39:42 (9 years ago)
Author:
pjkersha
Message:

Incomplete - task 9: Data Browser Replacement

  • fixes to do_get
Location:
ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/fileserver
Files:
1 added
3 edited

Legend:

Unmodified
Added
Removed
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/fileserver/app.py

    r6996 r6999  
    9797class FileServerApp(object): 
    9898    """Application to serve static content""" 
    99      
    100     def __init__(self, root_path, mount_point=None): 
     99    PARAM_PREFIX = 'fileserver.' 
     100     
     101    def __init__(self, root_path='', mount_point=None): 
    101102        self.path = os.path.abspath(os.path.expanduser(root_path)) 
    102103        self.mount_point = mount_point 
    103          
     104 
     105    @classmethod 
     106    def app_factory(cls, global_conf, prefix=PARAM_PREFIX, **app_conf):  
     107        """Function following Paste app factory signature 
     108         
     109        @type global_conf: dict         
     110        @param global_conf: PasteDeploy global configuration dictionary 
     111        @type prefix: basestring 
     112        @param prefix: prefix for configuration items 
     113        @type app_conf: dict         
     114        @param app_conf: PasteDeploy application specific configuration  
     115        dictionary 
     116        """ 
     117        # This app               
     118        app = cls(**app_conf) 
     119 
     120        return app 
     121     
    104122    def handler(self, environ, start_response): 
    105123        """Application to serve out windmill provided""" 
     
    117135         
    118136        def do_get(): 
    119             if serve_file.endswith('/') or os.path.isdir(os.path.join(self.path, serve_file)): 
    120                 if os.path.isdir(os.path.join(self.path, serve_file)): 
    121                     start_response('200 OK', [('Cache-Control','no-cache'), ('Pragma','no-cache'), 
    122                                               ('Content-Type', 'text/html; charset=utf-8')]) 
    123                     return [ '<html>' +  
    124                               '<br>'.join( ['<a href="%s/%s">%s</a>' % (serve_file.replace(filename, ''), filename, filename)  
    125                                           for filename in os.listdir(os.path.join(self.path, serve_file))]) 
    126                              + '</html>'   ] 
     137            # This if statement stops os.path.join doing a join with the  
     138            # absolute path '/'.  If this is done, the first argument is  
     139            # obliterated and the result is '/' exposing the root file system to 
     140            # the web client!! 
     141            if serve_file == '/': 
     142                file = self.path 
     143            else: 
     144                file = os.path.join(self.path, serve_file) 
     145             
     146            from urlparse import urljoin 
     147            isDir = os.path.isdir(file) 
     148            if serve_file.endswith('/') or isDir: 
     149                if isDir: 
     150                    dirContents = os.listdir(file) 
     151#                     
     152#                    lines = [ 
     153#                        '<a href="%s/%s">%s</a>' %  
     154#                        (serve_file.replace(filename, ''), filename, filename)  
     155#                        for filename in dirContents] 
     156 
     157                    lines = ['<a href="%s">%s</a>' %  
     158                             (urljoin(serve_file, filename), filename)  
     159                             for filename in dirContents] 
     160 
     161                    response = '<html>' + '<br>'.join(lines)+ '</html>' 
     162                    start_response('200 OK',  
     163                               [('Cache-Control','no-cache'),  
     164                                ('Pragma','no-cache'), 
     165                                ('Content-Type', 'text/html; charset=utf-8'), 
     166                                ('Content-Length', str(len(response)))]) 
     167                     
     168                    return [response] 
    127169                else: 
    128170                    logger.error('failed to list directory %s/%s' % (self.path, serve_file)) 
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/fileserver/test/__init__.py

    r6996 r6999  
    99__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1010__revision__ = '$Id$' 
     11import logging 
     12logging.basicConfig(level=logging.DEBUG) 
     13 
     14import paste.httpserver 
     15from threading import Thread 
     16from paste.deploy import loadapp 
     17from paste.script.util.logging_config import fileConfig 
     18 
     19 
     20class PasteDeployAppServer(object): 
     21    """Wrapper to paste.httpserver to enable background threading""" 
     22     
     23    def __init__(self, app=None, cfgFilePath=None, port=7443, host='0.0.0.0', 
     24                 ssl_context=None, withLoggingConfig=True): 
     25        """Load an application configuration from cfgFilePath ini file and  
     26        instantiate Paste server object 
     27        """        
     28        self.__thread = None 
     29         
     30        if cfgFilePath: 
     31            if withLoggingConfig: 
     32                fileConfig(cfgFilePath) 
     33            app = loadapp('config:%s' % cfgFilePath) 
     34             
     35        elif app is None: 
     36            raise KeyError('Either the "cfgFilePath" or "app" keyword must be ' 
     37                           'set') 
     38                        
     39        self.__pasteServer = paste.httpserver.serve(app, host=host, port=port,  
     40                                                    start_loop=False,  
     41                                                    ssl_context=ssl_context) 
     42     
     43    @property 
     44    def pasteServer(self): 
     45        return self.__pasteServer 
     46     
     47    @property 
     48    def thread(self): 
     49        return self.__thread 
     50     
     51    def start(self): 
     52        """Start server""" 
     53        self.pasteServer.serve_forever() 
     54         
     55    def startThread(self): 
     56        """Start server in a separate thread""" 
     57        self.__thread = Thread(target=PasteDeployAppServer.start, args=(self,)) 
     58        self.thread.start() 
     59         
     60    def terminateThread(self): 
     61        self.pasteServer.server_close() 
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/fileserver/test/test_fileserver.py

    r6996 r6999  
    1010__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1111__revision__ = '$Id$' 
     12import logging 
     13logging.basicConfig(level=logging.DEBUG) 
     14 
    1215import unittest 
     16from os import path 
     17 
     18import paste.fixture 
     19from paste.deploy import loadapp 
     20 
     21from ceda.server.wsgi.fileserver.app import FileServerApp 
    1322 
    1423 
    1524class FileServerAppTestCase(unittest.TestCase): 
     25    def __init__(self, *args, **kwargs): 
     26        app = FileServerApp() 
     27        self.app = paste.fixture.TestApp(app) 
     28          
     29        unittest.TestCase.__init__(self, *args, **kwargs) 
     30 
     31    def test01Assert(self): 
     32        # Check the middleware has set the MyProxy client object in environ 
     33        response = self.app.get('/', status=200) 
     34        self.assert_(response) 
     35 
    1636    def test01(self): 
    1737        pass 
    1838     
    1939     
     40class FileServerAppTestCaseBase(unittest.TestCase):   
     41    """Base class for common Paste Deploy related set-up""" 
     42    THIS_DIR = path.abspath(path.dirname(__file__)) 
     43    INI_FILENAME = 'fileserver.ini' 
     44    INI_FILEPATH = path.join(THIS_DIR, INI_FILENAME) 
     45     
     46    def __init__(self, *args, **kwargs): 
     47        wsgiapp = loadapp('config:' + self.__class__.INI_FILEPATH) 
     48        self.app = paste.fixture.TestApp(wsgiapp) 
     49                 
     50        unittest.TestCase.__init__(self, *args, **kwargs)   
     51    
    2052if __name__ == "__main__": 
    2153    unittest.main() 
Note: See TracChangeset for help on using the changeset viewer.