From: Ben Darnell Date: Tue, 22 Feb 2011 19:45:48 +0000 (-0800) Subject: Implement synchronous HTTPClient in terms of AsyncHTTPClient. X-Git-Tag: v2.0.0~130 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=b9ba02585867f38f850086e1cfa9dbc66d16ae64;p=thirdparty%2Ftornado.git Implement synchronous HTTPClient in terms of AsyncHTTPClient. Move curl_httpclient.main to httpclient.py --- diff --git a/tornado/curl_httpclient.py b/tornado/curl_httpclient.py index 1caa5506c..f662918a0 100644 --- a/tornado/curl_httpclient.py +++ b/tornado/curl_httpclient.py @@ -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. diff --git a/tornado/httpclient.py b/tornado/httpclient.py index 7faef4287..ae028b77a 100644 --- a/tornado/httpclient.py +++ b/tornado/httpclient.py @@ -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()