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

Incomplete - task 9: Data Browser Replacement

Location:
ceda_http_fileserver/trunk/ceda_http_fileserver
Files:
2 added
6 edited

Legend:

Unmodified
Added
Removed
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/__init__.py

    • Property svn:keywords set to Id
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/__init__.py

    • Property svn:keywords set to Id
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/__init__.py

    • Property svn:keywords set to Id
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/fileserver/__init__.py

    • Property svn:keywords set to Id
    r6993 r6996  
    99__contact__ = "Philip.Kershaw@stfc.ac.uk" 
    1010__revision__ = '$Id$' 
    11 #   Copyright (c) 2006-2007 Open Source Applications Foundation 
    12 # 
    13 #   Licensed under the Apache License, Version 2.0 (the "License"); 
    14 #   you may not use this file except in compliance with the License. 
    15 #   You may obtain a copy of the License at 
    16 # 
    17 #       http://www.apache.org/licenses/LICENSE-2.0 
    18 # 
    19 #   Unless required by applicable law or agreed to in writing, software 
    20 #   distributed under the License is distributed on an "AS IS" BASIS, 
    21 #   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 
    22 #   See the License for the specific language governing permissions and 
    23 #   limitations under the License. 
    24  
    25 from urlparse import urlparse 
    26 import os, sys 
    27 import logging 
    28  
    29 logger = logging.getLogger(__name__) 
    30  
    31 # Content type sources taken from http://en.wikipedia.org/wiki/MIME_type 
    32 content_type_table = { 
    33     'js': 'application/x-javascript',  
    34     'html': 'text/html; charset=utf-8', 
    35     'fallback':'text/plain; charset=utf-8',  
    36     'ogg': 'application/ogg',  
    37     'xhtml':'text/html; charset=utf-8',  
    38     'rm':'audio/vnd.rn-realaudio',  
    39     'swf':'application/x-shockwave-flash',  
    40     'mp3': 'audio/mpeg',  
    41     'wma':'audio/x-ms-wma',  
    42     'ra':'audio/vnd.rn-realaudio',  
    43     'wav':'audio/x-wav',  
    44     'gif':'image/gif',  
    45     'jpeg':'image/jpeg', 
    46     'jpg':'image/jpeg',  
    47     'png':'image/png',  
    48     'tiff':'image/tiff',  
    49     'css':'text/css; charset=utf-8', 
    50     'mpeg':'video/mpeg',  
    51     'mp4':'video/mp4',  
    52     'qt':'video/quicktime',  
    53     'mov':'video/quicktime', 
    54     'wmv':'video/x-ms-wmv',  
    55     'atom':'application/atom+xml; charset=utf-8', 
    56     'xslt':'application/xslt+xml',  
    57     'svg':'image/svg+xml', 'mathml':'application/mathml+xml',  
    58     'rss':'application/rss+xml; charset=utf-8', 
    59     'ics':'text/calendar; charset=utf-8 ' 
    60 } 
    61  
    62  
    63 def reconstruct_url(environ): 
    64     # From WSGI spec, PEP 333 
    65     from urllib import quote 
    66     url = environ['wsgi.url_scheme']+'://' 
    67     if environ.get('HTTP_HOST'): url += environ['HTTP_HOST'] 
    68     else: 
    69         url += environ['SERVER_NAME'] 
    70         if environ['wsgi.url_scheme'] == 'https': 
    71             if environ['SERVER_PORT'] != '443': 
    72                url += ':' + environ['SERVER_PORT'] 
    73         else: 
    74             if environ['SERVER_PORT'] != '80': 
    75                url += ':' + environ['SERVER_PORT'] 
    76     url += quote(environ.get('SCRIPT_NAME','')) 
    77     url += quote(environ.get('PATH_INFO','')).replace(url.replace(':', '%3A'), '') 
    78     if environ.get('QUERY_STRING'): 
    79         url += '?' + environ['QUERY_STRING'] 
    80     environ['reconstructed_url'] = url 
    81     return url 
    82      
    83      
    84 class FileResponse(object): 
    85     readsize = 1024 
    86      
    87     def __init__(self, f, filename): 
    88         self.size = os.path.getsize(filename) 
    89         self.f = f 
    90          
    91     def __iter__(self): 
    92         output = '\n' 
    93         while len(output) is not 0: 
    94             output = self.f.read(self.readsize) 
    95             yield output 
    96  
    97  
    98 class FileServerApp(object): 
    99     """Application to serve static content""" 
    100      
    101     def __init__(self, root_path, mount_point=None): 
    102         self.path = os.path.abspath(os.path.expanduser(root_path)) 
    103         self.mount_point = mount_point 
    104          
    105     def handler(self, environ, start_response): 
    106         """Application to serve out windmill provided""" 
    107         url = urlparse(reconstruct_url(environ)) 
    108          
    109         if self.mount_point is not None: 
    110             #split_url = url.path.split(self.mount_point, 1) 
    111             split_url = url[2].split(self.mount_point, 1) 
    112             serve_file = split_url[1] 
    113         else: 
    114             #serve_file = url.path 
    115             serve_file = url[2] 
    116          
    117         serve_file = serve_file.replace('%20', ' ') 
    118          
    119         def do_get(): 
    120             if serve_file.endswith('/') or os.path.isdir(os.path.join(self.path, serve_file)): 
    121                 if os.path.isdir(os.path.join(self.path, serve_file)): 
    122                     start_response('200 OK', [('Cache-Control','no-cache'), ('Pragma','no-cache'), 
    123                                               ('Content-Type', 'text/html; charset=utf-8')]) 
    124                     return [ '<html>' +  
    125                               '<br>'.join( ['<a href="%s/%s">%s</a>' % (serve_file.replace(filename, ''), filename, filename)  
    126                                           for filename in os.listdir(os.path.join(self.path, serve_file))]) 
    127                              + '</html>'   ] 
    128                 else: 
    129                     logger.error('failed to list directory %s/%s' % (self.path, serve_file)) 
    130                     start_response('404 Not found', [('Content-Type', 'text/plain')]) 
    131                     return ['404 Not Found'] 
    132              
    133             try: 
    134                 if os.name == 'nt' or sys.platform == 'cygwin': 
    135                     f = open(os.path.join(self.path, serve_file), 'rb') 
    136                 else: 
    137                     f = open(os.path.join(self.path, serve_file), 'r') 
    138                 logger.debug('opened file %s' % serve_file) 
    139             except IOError: 
    140                 logger.error('failed to open file %s/%s' % (self.path, serve_file)) 
    141                 start_response('404 Not found', [('Content-Type', 'text/plain')]) 
    142                 return ['404 Not Found'] 
    143              
    144             response = FileResponse(f, os.path.join(self.path, serve_file)) 
    145             start_response('200 OK', [('Cache-Control','no-cache'), ('Pragma','no-cache'),  
    146                                       ('Content-Length', str(response.size),), 
    147                                       ('Content-Type', self.guess_content_type(environ['PATH_INFO']))]) 
    148             return response 
    149              
    150         def do_put(): 
    151             #Write file 
    152             try: 
    153                 f = open(os.path.join(self.path, serve_file), 'w') 
    154                 logger.debug('opened file for writing %s' % serve_file) 
    155             except: 
    156                 logger.error('failed to open file for writiing %s/%s' % (self.path, serve_file)) 
    157                 start_response('403 Forbidden', [('Content-Type', 'text/plain')]) 
    158                 return ['403 Forbidden'] 
    159              
    160             f.write(environ['wsgi.input'].read()) 
    161              
    162         def do_mkcollection(): 
    163             pass 
    164              
    165         http_method_map = {'GET':do_get, 'PUT':do_put, 'MKCOLLECTION':do_mkcollection} 
    166         return http_method_map[environ['REQUEST_METHOD']]() 
    167              
    168  
    169     def guess_content_type(self, path_info): 
    170         """Make a best guess at the content type""" 
    171         extention_split = path_info.split('.') 
    172  
    173         if content_type_table.has_key(extention_split[-1]): 
    174             return content_type_table[extention_split[-1]] 
    175         else: 
    176             return content_type_table['fallback'] 
    177              
    178     def __call__(self, environ, start_response): 
    179         return self.handler(environ, start_response) 
  • ceda_http_fileserver/trunk/ceda_http_fileserver/ceda/server/wsgi/fileserver/test/__init__.py

    • Property svn:keywords set to Id
  • ceda_http_fileserver/trunk/ceda_http_fileserver/wsgi_fileserver/__init__.py

    • Property svn:keywords set to Id
Note: See TracChangeset for help on using the changeset viewer.