Anonymous avatar Anonymous committed d80d29e


Comments (0)

Files changed (3)


 import urllib
-from restclient.transport import getDefaultHTTPTransport, HTTPTransportBase 
+from restclient.transport import getDefaultHTTPTransport, HTTPTransportBase, TransportError 
 __all__ = ['Resource', 'RestClient', 'ResourceNotFound', \
         'Unauthorized', 'RequestFailed', 'ResourceError',
-        'ResourceResult']
+        'ResourceResult', 'RequestError']
 __docformat__ = 'restructuredtext en'
             if not 'Content-Length' in headers:
                 raise RequestError("'Content-Lenght' should be specified when body is a File like instance") 
-        resp, data = self.transport.request(self.make_uri(uri, path, **params), 
+        try:
+            resp, data = self.transport.request(self.make_uri(uri, path, **params), 
                 method=method, body=body, headers=headers)
+        except TransportError, e:
+            raise RequestError(e)
         status_code = int(resp.status)
                 raise RequestFailed(error, http_code=status_code,
-                        response=resp)
+                    response=resp)
         return ResourceResult(data, status_code, resp)


 _default_http = None
+class TransportError(Exception):
+    """Error raised by a transport """
 USER_AGENT = "py-restclient/%s (%s)" % (restclient.__version__, sys.platform)
         return s
-def createHTTPClient():
+def createHTTPTransport():
     """Create default HTTP client instance
     prefers Curl to urllib"""
         raise NotImplementedError
+def _get_pycurl_errcode(symbol, default):
+    """
+    Returns the numerical error code for a symbol defined by pycurl.
+    Different pycurl implementations define different symbols for error
+    codes. Old versions never define some symbols (wether they can return the
+    corresponding error code or not). The following addresses the problem by
+    defining the symbols we care about.  Note: this allows to define symbols
+    for errors that older versions will never return, which is fine.
+    """
+    return pycurl.__dict__.get(symbol, default)
+CURLE_COULDNT_CONNECT = _get_pycurl_errcode('E_COULDNT_CONNECT', 7)
+CURLE_GOT_NOTHING = _get_pycurl_errcode('E_GOT_NOTHING', 52)
+CURLE_PARTIAL_FILE = _get_pycurl_errcode('E_PARTIAL_FILE', 18)
+CURLE_SEND_ERROR = _get_pycurl_errcode('E_SEND_ERROR', 55)
+CURLE_SSL_CACERT = _get_pycurl_errcode('E_SSL_CACERT', 60)
+CURLE_SSL_CACERT_BADFILE = _get_pycurl_errcode('E_SSL_CACERT_BADFILE', 77)    
 class CurlTransport(HTTPTransportBase):
             except pycurl.error, e:
-                errno, message = e
-                return self._make_response(final_url=url, status=errno,
-                        body=message)
+                if e[0] != CURLE_SEND_ERROR:
+                    raise TransportError(e)
             response_headers = self._parseHeaders(header)
             code = c.getinfo(pycurl.RESPONSE_CODE)
     def _make_response(self, final_url=None, status=None, headers=None,
         resp = HTTPResponse()
-        resp.headers = headers
+        resp.headers = headers or {}
         resp.status = status
         resp.final_url = final_url
         resp.body = body
     name = 'py-restclient',
-    version = '1.1',
+    version = '1.1.1',
     description = 'Python REST client',
     long_description = \
 """A simple REST client for Python, inspired by the microframework (Camping, Sinatra) style of specifying actions: get, put, post, delete.""",
Tip: Filter by directory path e.g. /media app.js to search for public/media/app.js.
Tip: Use camelCasing e.g. ProjME to search for
Tip: Filter by extension type e.g. /repo .js to search for all .js files in the /repo directory.
Tip: Separate your search with spaces e.g. /ssh pom.xml to search for src/ssh/pom.xml.
Tip: Use ↑ and ↓ arrow keys to navigate and return to view the file.
Tip: You can also navigate files with Ctrl+j (next) and Ctrl+k (previous) and view the file with Ctrl+o.
Tip: You can also navigate files with Alt+j (next) and Alt+k (previous) and view the file with Alt+o.