Browse Source

* added test_urllib2 - tests build_opener
* tidying get module


git-svn-id: http://proj.badc.rl.ac.uk/svn/ndg-security/trunk/ndg_httpsclient@7984 051b1e3e-aa0c-0410-b6c2-bfbade6052be

pjkersha 13 years ago
parent
commit
afa453a66e

+ 25 - 19
ndg/httpsclient/get.py

@@ -11,6 +11,10 @@ from ndg.httpsclient.https import HTTPSContextHandler
 from ndg.httpsclient import ssl_context_util
 
 
+class URLFetchError(Exception):
+    """Error fetching content from URL"""
+    
+
 def fetch_from_url(url, config):
     """Returns data retrieved from a URL.
     @param url - URL to attempt to open
@@ -23,7 +27,7 @@ def fetch_from_url(url, config):
         response.close()
         return return_data
     else:
-        raise Exception(return_message)
+        raise URLFetchError(return_message)
 
 def fetch_from_url_to_file(url, config, output_file):
     """Writes data retrieved from a URL to a file.
@@ -91,25 +95,25 @@ def open_url(url, config):
             return_message = response.msg
             return_code = response.code
         else:
-            return_message = ('Redirected (%s  %s)' % (response.code, response.url))
+            return_message = 'Redirected (%s  %s)' % response.code, response.url
         if config.debug:
             for index, cookie in enumerate(cj):
                 print index, '  :  ', cookie        
     except urllib2.HTTPError, exc:
         return_code = exc.code
-        return_message = ("Error: %s" % exc.msg)
+        return_message = "Error: %s" % exc.msg
         if config.debug:
             print exc.code, exc.msg
     except Exception, exc:
-        return_message = ("Error: %s" % exc.__str__())
+        return_message = "Error: %s" % exc.__str__()
         if config.debug:
             print exc.__class__, exc.__str__()
     return (return_code, return_message, response)
 
 
 def _should_use_proxy(url):
-    """Determines whether a proxy should be used to open a connection to the specified URL, based on
-        the value of the no_proxy environment variable.
+    """Determines whether a proxy should be used to open a connection to the 
+    specified URL, based on the value of the no_proxy environment variable.
     @param url - URL string
     """
     no_proxy = os.environ.get('no_proxy', '')
@@ -154,9 +158,9 @@ def main():
                       help="Print debug information.")
     parser.add_option("-f", "--fetch", dest="output_file", metavar="FILE",
                       default=None, help="Output file.")
-    parser.add_option("-v", "--verify-peer", action="store_true", 
-                      dest="verify_peer", default=False,
-                      help="Verify peer certificate.")
+    parser.add_option("-n", "--no-verify-peer", action="store_true", 
+                      dest="no_verify_peer", default=False,
+                      help="Skip verification of peer certificate.")
     (options, args) = parser.parse_args()
     if len(args) != 1:
         parser.error("Incorrect number of arguments")
@@ -178,21 +182,23 @@ def main():
     else:
         ca_dir = None
         
+    verify_peer = not options.no_verify_peer
+    
     # If a private key file is not specified, the key is assumed to be stored in 
     # the certificate file.
-    ssl_context = ssl_context_util.make_ssl_context(
-        key_file,
-        cert_file,
-        None,
-        ca_dir,
-        options.verify_peer, url)
+    ssl_context = ssl_context_util.make_ssl_context(key_file,
+                                                    cert_file,
+                                                    None,
+                                                    ca_dir,
+                                                    verify_peer, 
+                                                    url)
 
     config = Configuration(ssl_context, options.debug)
     if options.output_file:
-        return_code, return_message, success = fetch_from_url_to_file(url, 
-                                                          config,
-                                                          options.output_file)
-        print(return_code, return_message)
+        return_code, return_message = fetch_from_url_to_file(url, 
+                                                      config,
+                                                      options.output_file)[:2]
+        raise SystemExit(return_code, return_message)
     else:
         data = fetch_from_url(url, config)
         print(data)

+ 1 - 9
ndg/httpsclient/https.py

@@ -47,12 +47,8 @@ class HTTPSConnection(HTTPConnection):
 
     def connect(self):
         """Create SSL socket and connect to peer
-        """ 
+        """
         if getattr(self, 'ssl_context', None):
-            if not isinstance(self.ssl_context, SSL.Context):
-                raise TypeError('Expecting OpenSSL.SSL.Context type for "'
-                                'ssl_context" keyword; got %r instead' %
-                                self.ssl_context)
             ssl_context = self.ssl_context
         else:
             ssl_context = SSL.Context(self.__class__.default_ssl_method)
@@ -86,10 +82,6 @@ class HTTPSContextHandler(AbstractHTTPHandler):
         AbstractHTTPHandler.__init__(self, debuglevel)
 
         if ssl_context is not None:
-            if not isinstance(ssl_context, SSL.Context):
-                raise TypeError('Expecting OpenSSL.SSL.Context type for "'
-                                'ssl_context" keyword; got %r instead' %
-                                ssl_context)
             self.ssl_context = ssl_context
         else:
             self.ssl_context = SSL.Context(SSL.SSLv23_METHOD)

+ 3 - 1
ndg/httpsclient/test/__init__.py

@@ -11,5 +11,7 @@ __contact__ = "Philip.Kershaw@stfc.ac.uk"
 __revision__ = '$Id$'
 class Constants(object):
     PORT = 4443
+    PORT2 = 4444
     HOSTNAME = 'localhost'
-    TEST_URI = 'https://%s:%d' % (HOSTNAME, PORT)
+    TEST_URI = 'https://%s:%d' % (HOSTNAME, PORT)
+    TEST_URI2 = 'https://%s:%d' % (HOSTNAME, PORT2)

+ 6 - 1
ndg/httpsclient/test/test_https.py

@@ -6,6 +6,7 @@ Created on Jan 6, 2012
 import logging
 logging.basicConfig(level=logging.DEBUG)
 import unittest
+import socket
 
 from ndg.httpsclient.test import Constants
 from ndg.httpsclient.https import HTTPSConnection
@@ -14,7 +15,7 @@ from ndg.httpsclient.https import HTTPSConnection
 class TestHTTPSConnection(unittest.TestCase):
     '''Test ndg HTTPS client HTTPSConnection class'''
 
-    def test01(self):
+    def test01_open(self):
         conn = HTTPSConnection(Constants.HOSTNAME, port=Constants.PORT)
         conn.connect()
         conn.request('GET', '/')
@@ -22,6 +23,10 @@ class TestHTTPSConnection(unittest.TestCase):
         print('Response = %s' % resp.read())
         conn.close()
 
+    def test02_open_fails(self):
+        conn = HTTPSConnection(Constants.HOSTNAME, port=Constants.PORT2)
+        self.failUnlessRaises(socket.error, conn.connect)
+
 
 if __name__ == "__main__":
     unittest.main()

+ 11 - 4
ndg/httpsclient/test/test.py

@@ -3,13 +3,15 @@ Created on Jan 5, 2012
 
 @author: philipkershaw
 '''
+from urllib2 import URLError
 import unittest
+
+from ndg.httpsclient.test import Constants
 from ndg.httpsclient.urllib2_build_opener import build_opener
 
 
-class Urllib2PyOpenSslTestCase(unittest.TestCase):
-    """Unit tests for PyOpenSSL HTTPS interface for urllib2"""
-    TEST_URI = 'https://localhost:4443'
+class Urllib2TestCase(unittest.TestCase):
+    """Unit tests for urllib2 functionality"""
     
     def test01_urllib2_build_opener(self):     
         opener = build_opener()
@@ -17,9 +19,14 @@ class Urllib2PyOpenSslTestCase(unittest.TestCase):
 
     def test02_open(self):
         opener = build_opener()
-        res = opener.open(self.__class__.TEST_URI)
+        res = opener.open(Constants.TEST_URI)
         self.assert_(res)
         print("res = %s" % res.read())
 
+    def test03_open_fails(self):
+        opener = build_opener()
+        self.failUnlessRaises(URLError, opener.open, Constants.TEST_URI2)
+        
+
 if __name__ == "__main__":
     unittest.main()