Changeset 6864


Ignore:
Timestamp:
12/05/10 14:54:48 (9 years ago)
Author:
pjkersha
Message:

Added unit test but calls fail with 404 error

Location:
TI12-security/trunk/EsgPyDapClient
Files:
8 added
1 edited

Legend:

Unmodified
Added
Removed
  • TI12-security/trunk/EsgPyDapClient/esg/pydap/client.py

    r6863 r6864  
    1 ''' 
    2 Created on 11 May 2010 
     1"""PyDAP client extension to support SSL based authentication with redirects 
     2devised for the Earth System Grid project 
     3""" 
     4__author__ = "P J Kershaw" 
     5__date__ = "11/05/10" 
     6__copyright__ = "" 
     7__license__ = "BSD - see LICENSE file in top-level directory" 
     8__contact__ = "Philip.Kershaw@stfc.ac.uk" 
     9__revision__ = '$Id:$' 
     10import re 
     11import urllib2 
     12import logging 
     13log = logging.getLogger(__name__) 
    314 
    4 @author: pjkersha 
    5 ''' 
    6 import urllib2 
    715from M2Crypto import SSL, m2urllib2 
    8 from myproxy.client import MyProxyClient 
    9  
    10 import logging 
    11 import re 
    12 import os 
    13 import getpass 
    14 from urlparse import urlparse 
    15 import pydap.lib 
    1616from pydap.exceptions import ClientError 
    1717 
    18 url = 'http://ndg3beta.badc.rl.ac.uk/' 
    19 cert_file = os.path.expanduser('~/.globus/badc_cert.pem') 
    2018 
    21 testfile = 'dap/rapid/chime/co2_1pc/1day/chime_co2_1pc_daily_0060_197.oc.nc' 
     19class DapClient(object): 
     20    """PyDAP client extended to support SSL based authentication with redirects 
     21    devised for the Earth System Grid project 
     22    """ 
     23    def __init__(self, certfile, keyfile=None): 
     24        """Set up an SSL Context based on the certificate and key file passed 
     25        """ 
     26        ctx = self.secure_init(certfile, keyfile) 
     27        opener = m2urllib2.build_opener(ctx, urllib2.HTTPCookieProcessor()) 
     28        urllib2.install_opener(opener) 
     29         
     30        self.install_ndg_client(certfile, keyfile) 
     31         
     32    def secure_init(self, certfile, keyfile=None): 
     33        # keyfile assumed to be the same as certfile if it's omitted 
     34        if keyfile is None: 
     35            keyfile = certfile 
     36             
     37        ctx = SSL.Context('sslv3') 
     38        ctx.load_cert(certfile=certfile, keyfile=keyfile) 
     39        return ctx 
    2240 
    23 def make_cert(): 
    24  
    25     # Get a proxy certificate from the CEDA MyProxy instance 
    26     mp = MyProxyClient(hostname='<CEDA MyProxy Service>', serverCNPrefix='') 
    27     username = getpass.getuser() 
    28     password = getpass.getpass() 
    29     cert, key = mp.logon(username, password) 
    30  
    31     # Save the certificate 
    32     cert_fh = open(cert_file, 'w') 
    33     cert_fh.write(key) 
    34     cert_fh.write(cert) 
    35     cert_fh.close() 
    36  
    37 def init(): 
    38     install_ndg_client(cert_file) 
    39     import pydap.client 
     41    def install_ndg_client(self, certfile, keyfile=None): 
     42        '''Override PyDAP default HTTP request function''' 
     43         
     44        def _request(url): 
     45            log.info('Opening [%s] ...' % url) 
     46                        
     47            response = urllib2.urlopen(url) 
     48            responseDict = response.headers.dict 
     49            data = response.read() 
     50     
     51            # When an error is returned, we parse the error message from the 
     52            # server and return it in a ``ClientError`` exception. 
     53            if responseDict.get("content-description") == "dods_error": 
     54                m = re.search('code = (?P<code>\d+);\s*message = "(?P<msg>.*)"', 
     55                        data, re.DOTALL | re.MULTILINE) 
     56                msg = 'Server error %(code)s: "%(msg)s"' % m.groupdict() 
     57                raise ClientError(msg) 
     58             
     59            responseDict['status'] = str(response.code) 
     60     
     61            return responseDict, data 
     62     
     63        from pydap.util import http 
     64        http.request = _request 
     65        self._request = _request 
     66         
     67    def open_url(self, url): 
     68        '''Wrap PyDAP open_url function as a method to this class ensuring that 
     69        it is called with the altered version of pydap.util.http.request set in 
     70        __init__ 
     71        ''' 
     72        import pydap.client 
     73        pydap.client.request = self._request 
     74        return pydap.client.open_url(url) 
    4075 
    4176 
    42 def secure_init(certfile, keyfile=None): 
    43     # keyfile assumed to be the same as certfile if it's omitted 
    44     if keyfile is None: 
    45         keyfile = certfile 
    46          
    47     ctx = SSL.Context('sslv3') 
    48     ctx.load_cert(certfile=certfile, keyfile=keyfile) 
    49  
    50     #!TODO: persistant cookiejar 
    51     opener = m2urllib2.build_opener(ctx, urllib2.HTTPCookieProcessor()) 
    52     urllib2.install_opener(opener) 
    53  
    54  
    55 def install_ndg_client(certfile, keyfile=None): 
    56     # Create special opener with support for Cookies. 
    57     secure_init(certfile, keyfile) 
    58  
    59     def new_request(url): 
    60         log = logging.getLogger('pydap') 
    61         log.info('Opening %s' % url) 
    62         r = urllib2.urlopen(url) 
    63  
    64         resp = r.headers.dict 
    65         resp['status'] = str(r.code) 
    66         data = r.read() 
    67  
    68         # When an error is returned, we parse the error message from the 
    69         # server and return it in a ``ClientError`` exception. 
    70         if resp.get("content-description") == "dods_error": 
    71             m = re.search('code = (?P<code>\d+);\s*message = "(?P<msg>.*)"', 
    72                     data, re.DOTALL | re.MULTILINE) 
    73             msg = 'Server error %(code)s: "%(msg)s"' % m.groupdict() 
    74             raise ClientError(msg) 
    75  
    76         return resp, data 
    77  
    78     from pydap.util import http 
    79     http.request = new_request 
    80  
    81 def get(): 
    82     return pydap.client.open_url(url + testfile) 
    83  
Note: See TracChangeset for help on using the changeset viewer.