]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
curl_httpclient: run streaming and header callbacks on the IOLoop.
authorBen Darnell <ben@bendarnell.com>
Sun, 21 Sep 2014 16:25:11 +0000 (12:25 -0400)
committerBen Darnell <ben@bendarnell.com>
Sun, 21 Sep 2014 16:25:11 +0000 (12:25 -0400)
This ensures a more consistent execution environment and allows
a streaming or header callback to invoke other CurlAsyncHTTPClient
methods.

This change also fills in HTTPResponse.headers even when a header_callback
is used, similar to simple_httpclient's behavior.

Closes #1188.

tornado/curl_httpclient.py

index 406f80c1026a886e759cebc4a9682aafa648c8c8..eba6af9ed11c63ae54dc39b4da2e87cb8833d5c2 100644 (file)
@@ -19,6 +19,7 @@
 from __future__ import absolute_import, division, print_function, with_statement
 
 import collections
+import functools
 import logging
 import pycurl
 import threading
@@ -287,15 +288,12 @@ class CurlAsyncHTTPClient(AsyncHTTPClient):
             curl.setopt(pycurl.HTTPHEADER,
                         [native_str("%s: %s" % i) for i in request.headers.items()])
 
-        if request.header_callback:
-            curl.setopt(pycurl.HEADERFUNCTION,
-                        lambda line: request.header_callback(native_str(line)))
-        else:
-            curl.setopt(pycurl.HEADERFUNCTION,
-                        lambda line: self._curl_header_callback(
-                            headers, native_str(line)))
+        curl.setopt(pycurl.HEADERFUNCTION,
+                    functools.partial(self._curl_header_callback,
+                        headers, request.header_callback))
         if request.streaming_callback:
-            write_function = request.streaming_callback
+            write_function = lambda chunk: self.io_loop.add_callback(
+                request.streaming_callback, chunk)
         else:
             write_function = buffer.write
         if bytes is str:  # py2
@@ -434,7 +432,10 @@ class CurlAsyncHTTPClient(AsyncHTTPClient):
         if request.prepare_curl_callback is not None:
             request.prepare_curl_callback(curl)
 
-    def _curl_header_callback(self, headers, header_line):
+    def _curl_header_callback(self, headers, header_callback, header_line):
+        header_line = native_str(header_line)
+        if header_callback is not None:
+            self.io_loop.add_callback(header_callback, header_line)
         # header_line as returned by curl includes the end-of-line characters.
         header_line = header_line.strip()
         if header_line.startswith("HTTP/"):