]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
Implement synchronous HTTPClient in terms of AsyncHTTPClient.
authorBen Darnell <ben@bendarnell.com>
Tue, 22 Feb 2011 19:45:48 +0000 (11:45 -0800)
committerBen Darnell <ben@bendarnell.com>
Tue, 22 Feb 2011 19:45:48 +0000 (11:45 -0800)
Move curl_httpclient.main to httpclient.py

tornado/curl_httpclient.py
tornado/httpclient.py

index 1caa5506cd4e6a543593d9233ffe356c59ba53db..f662918a06dfb8da80c99aa3cf566b8a7ae99c9d 100644 (file)
@@ -44,54 +44,7 @@ from tornado import ioloop
 from tornado import stack_context
 
 from tornado.escape import utf8
-from tornado.httpclient import HTTPRequest, HTTPResponse, HTTPError
-
-class HTTPClient(object):
-    """A blocking HTTP client backed with pycurl.
-
-    Typical usage looks like this:
-
-        http_client = httpclient.HTTPClient()
-        try:
-            response = http_client.fetch("http://www.google.com/")
-            print response.body
-        except httpclient.HTTPError, e:
-            print "Error:", e
-
-    fetch() can take a string URL or an HTTPRequest instance, which offers
-    more options, like executing POST/PUT/DELETE requests.
-    """
-    def __init__(self, max_simultaneous_connections=None):
-        self._curl = _curl_create(max_simultaneous_connections)
-
-    def __del__(self):
-        self._curl.close()
-
-    def fetch(self, request, **kwargs):
-        """Executes an HTTPRequest, returning an HTTPResponse.
-
-        If an error occurs during the fetch, we raise an HTTPError.
-        """
-        if not isinstance(request, HTTPRequest):
-            request = HTTPRequest(url=request, **kwargs)
-        buffer = cStringIO.StringIO()
-        headers = httputil.HTTPHeaders()
-        try:
-            _curl_setup_request(self._curl, request, buffer, headers)
-            self._curl.perform()
-            code = self._curl.getinfo(pycurl.HTTP_CODE)
-            effective_url = self._curl.getinfo(pycurl.EFFECTIVE_URL)
-            buffer.seek(0)
-            response = HTTPResponse(
-                request=request, code=code, headers=headers,
-                buffer=buffer, effective_url=effective_url)
-            if code < 200 or code >= 300:
-                raise HTTPError(code, response=response)
-            return response
-        except pycurl.error, e:
-            buffer.close()
-            raise CurlError(*e)
-
+from tornado.httpclient import HTTPRequest, HTTPResponse, HTTPError, main
 
 class AsyncHTTPClient(object):
     """An non-blocking HTTP client backed with pycurl.
@@ -521,26 +474,6 @@ def _curl_debug(debug_type, debug_msg):
         logging.debug('%s %r', debug_types[debug_type], debug_msg)
 
 
-def main():
-    from tornado.options import define, options, parse_command_line
-    define("print_headers", type=bool, default=False)
-    define("print_body", type=bool, default=True)
-    define("follow_redirects", type=bool, default=True)
-    args = parse_command_line()
-    client = HTTPClient()
-    for arg in args:
-        try:
-            response = client.fetch(arg,
-                                    follow_redirects=options.follow_redirects)
-        except HTTPError, e:
-            if e.response is not None:
-                response = e.response
-            else:
-                raise
-        if options.print_headers:
-            print response.headers
-        if options.print_body:
-            print response.body
 
 # If the environment variable USE_SIMPLE_HTTPCLIENT is set to a non-empty
 # string, use SimpleAsyncHTTPClient instead of AsyncHTTPClient.
index 7faef4287a8da5fc4f5476c4253951e90f14ef75..ae028b77a8c4e0768bbbe125b3be697fc54f47a6 100644 (file)
@@ -3,6 +3,45 @@ import time
 
 from tornado.escape import utf8
 from tornado import httputil
+from tornado.ioloop import IOLoop
+
+class HTTPClient(object):
+    """A blocking HTTP client.
+
+    Typical usage looks like this:
+
+        http_client = httpclient.HTTPClient()
+        try:
+            response = http_client.fetch("http://www.google.com/")
+            print response.body
+        except httpclient.HTTPError, e:
+            print "Error:", e
+
+    fetch() can take a string URL or an HTTPRequest instance, which offers
+    more options, like executing POST/PUT/DELETE requests.
+    """
+    def __init__(self):
+        self._io_loop = IOLoop()
+        self._async_client = AsyncHTTPClient(self._io_loop)
+        self._response = None
+
+    def __del__(self):
+        self._async_client.close()
+
+    def fetch(self, request, **kwargs):
+        """Executes an HTTPRequest, returning an HTTPResponse.
+
+        If an error occurs during the fetch, we raise an HTTPError.
+        """
+        def callback(response):
+            self._response = response
+            self._io_loop.stop()
+        self._async_client.fetch(request, callback, **kwargs)
+        self._io_loop.start()
+        response = self._response
+        self._response = None
+        response.rethrow()
+        return response
 
 class HTTPRequest(object):
     def __init__(self, url, method="GET", headers=None, body=None,
@@ -147,4 +186,28 @@ class HTTPError(Exception):
         Exception.__init__(self, "HTTP %d: %s" % (self.code, message))
 
 
-from tornado.curl_httpclient import AsyncHTTPClient, HTTPClient
+def main():
+    from tornado.options import define, options, parse_command_line
+    define("print_headers", type=bool, default=False)
+    define("print_body", type=bool, default=True)
+    define("follow_redirects", type=bool, default=True)
+    args = parse_command_line()
+    client = HTTPClient()
+    for arg in args:
+        try:
+            response = client.fetch(arg,
+                                    follow_redirects=options.follow_redirects)
+        except HTTPError, e:
+            if e.response is not None:
+                response = e.response
+            else:
+                raise
+        if options.print_headers:
+            print response.headers
+        if options.print_body:
+            print response.body
+
+from tornado.curl_httpclient import AsyncHTTPClient
+
+if __name__ == "__main__":
+    main()