Commits

ben...@pollen.nymphormation.net  committed 0a9c587

handle file management

  • Participants
  • Parent commits 79fec97

Comments (0)

Files changed (5)

File docs/resource.txt

     .. attribute:: httpclient
 
         Any http instance of object based on 
-        `restclient.http.HTTPClient`. By default it will use 
+        `restclient.http.HTTP`. By default it will use 
         a client based on `pycurl <http://pycurl.sourceforge.net/>`_ if 
         installed or urllib2. You could also use 
         `restclient.http.HTTPLib2HTTPClient`,a client based on 
 .. autoexception:: restclient.rest.ResourceNotFound
 .. autoexception:: restclient.rest.Unauthorized
 .. autoexception:: restclient.rest.RequestFailed
-
+.. autoexception:: restclient.rest.RequestError
 
 
 .. _Pycurl: http://pycurl.sourceforge.net/

File restclient/rest.py

 __docformat__ = 'restructuredtext en'
 
 
+
+
 class ResourceError(Exception):
     def __init__(self, message=None, http_code=None, response=None):
         self.message = message
     probably an HTML error page) is e.response.body.
     """
 
+class RequestError(Exception):
+    """Exception raised when a request is malformed"""
+
+
 class ResourceResult(str):
     """ result returned by `restclient.rest.RestClient`.
     
         
         headers = headers or {}
 
+        if hasattr(body, 'read'):
+            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(make_uri(uri, path, **params), 
                 method=method, body=body, headers=headers)
 

File restclient/transport.py

         
         if method in ['POST', 'PUT']:
             body = body or ''
-            headers.setdefault('Content-Length', str(len(body))) 
+            if not hasattr(body, 'read'):
+                headers.setdefault('Content-Length', str(len(body))) 
 
 
         c = pycurl.Curl()
                 c.setopt(pycurl.CUSTOMREQUEST, method)
 
             if method in ('POST','PUT'):
+                if hasattr(body, 'read'):
+                    content_length = int(headers.get('Content-Length',
+                        0))
+                    content = body
+                else:
+                    content = StringIO.StringIO(body)
+                    content_length = len(body)
+
                 if put:
-                    c.setopt(pycurl.INFILESIZE, len(body))
+                    c.setopt(pycurl.INFILESIZE, content_length)
                 if method in ('POST'):
-                    c.setopt(pycurl.POSTFIELDSIZE, len(body))
-                s = StringIO.StringIO(body)
-                c.setopt(pycurl.READFUNCTION, s.read)
+                    c.setopt(pycurl.POSTFIELDSIZE, content_length)
+                c.setopt(pycurl.READFUNCTION, content.read)
             
             try:
                 c.perform()
 
     def request(self, url, method='GET', body=None, headers=None):
         headers = headers or {}
-       
+      
+        content = ''
         if method in ['POST', 'PUT']:
             body = body or ''
-            headers.setdefault('Content-Length', str(len(body))) 
+            if hasattr(body, 'read'): # httplib2 don't suppport file read
+                content = body.read()
+            else:
+                content = body
+                headers.setdefault('Content-Length', str(len(body))) 
 
         if not (url.startswith('http://') or url.startswith('https://')):
             raise ValueError('URL is not a HTTP URL: %r' % (url,))
         headers.setdefault('User-Agent', USER_AGENT)
         
         httplib2_response, content = self.http.request(url,
-                method=method, body=body, headers=headers)
+                method=method, body=content, headers=headers)
 
 
         try:

File tests/resource_test.py

 
 from restclient.transport import HTTPLib2Transport
 from restclient.rest import Resource, RestClient, RequestFailed, \
-ResourceNotFound, Unauthorized
+ResourceNotFound, Unauthorized, RequestError
 
 
 from _server_test import HOST, PORT
         result = self.res.delete('/delete')
         self.assert_(result.http_code == 200)
 
+    def testFileSend(self):
+        content_length = len("test")
+        import StringIO
+        content = StringIO.StringIO("test")
+        result = self.res.post('/json', payload=content,
+                headers={
+                    'Content-Type': 'application/json',
+                    'Content-Length': str(content_length)
+                })
+
+        self.assert_(result.http_code == 200 )
+
+    def testFileSend2(self):
+        import StringIO
+        content = StringIO.StringIO("test")
+
+        def bad_post():
+            result = self.res.post('/json', payload=content,
+                headers={'Content-Type': 'application/json'})
+
+        self.assertRaises(RequestError, bad_post)
+
+
+
  
     
 if __name__ == '__main__':

File tests/transports_test.py

         result = self.res.delete('/delete')
         self.assert_(result.http_code == 200)
 
+    def testFileSend(self):
+        content_length = len("test")
+        import StringIO
+        content = StringIO.StringIO("test")
+        result = self.res.post('/json', payload=content,
+                headers={
+                    'Content-Type': 'application/json',
+                    'Content-Length': str(content_length)
+                })
+
+        self.assert_(result.http_code == 200 )
+
     def testAuth(self):
         httptransport = self.httptransport 
         httptransport.add_credentials("test", "test")