# (but see version check in _process_queue above)
curl.setopt(pycurl.IPRESOLVE, pycurl.IPRESOLVE_V4)
- # Set the request method through curl's retarded interface which makes
+ # Set the request method through curl's irritating interface which makes
# up names for almost every single method
curl_options = {
"GET": pycurl.HTTPGET,
to be suitable for most users' needs. However, some applications may wish
to switch to `curl_httpclient` for reasons such as the following:
+* `curl_httpclient` has some features not found in `simple_httpclient`,
+ including support for HTTP proxies and the ability to use a specified
+ network interface.
+
* `curl_httpclient` is more likely to be compatible with sites that are
not-quite-compliant with the HTTP spec, or sites that use little-exercised
features of HTTP.
# in the ioloop.
http_client.fetch(url, callback)
ioloop.start()
+
+Most applications shouln't have to work with `StackContext` directly.
+Here are a few rules of thumb for when it's necessary:
+
+* If you're writing an asynchronous library that doesn't rely on a
+ stack_context-aware library like `tornado.ioloop` or `tornado.iostream`
+ (for example, if you're writing a thread pool), use
+ `stack_context.wrap()` before any asynchronous operations to capture the
+ stack context from where the operation was started.
+
+* If you're writing an asynchronous library that has some shared
+ resources (such as a connection pool), create those shared resources
+ within a ``with stack_context.NullContext():`` block. This will prevent
+ ``StackContexts`` from leaking from one request to another.
+
+* If you want to write something like an exception handler that will
+ persist across asynchronous calls, create a new `StackContext` (or
+ `ExceptionStackContext`), and make your asynchronous calls in a ``with``
+ block that references your `StackContext`.
'''
from __future__ import with_statement
# Test contents of response (failures and exceptions here
# will cause self.wait() to throw an exception and end the
# test).
+ # Exceptions thrown here are magically propagated to
+ # self.wait() in test_http_fetch() via stack_context.
+ self.assertIn("FriendFeed", response.body)
self.stop()
# This test uses the argument passing between self.stop and self.wait
- # for a simpler, more synchronous style
+ # for a simpler, more synchronous style.
+ # This style is recommended over the preceding example because it
+ # keeps the assertions in the test method itself, and is therefore
+ # less sensitive to the subtleties of stack_context.
class MyTestCase2(AsyncTestCase):
def test_http_fetch(self):
client = AsyncHTTPClient(self.io_loop)
client.fetch("http://www.tornadoweb.org/", self.stop)
response = self.wait()
# Test contents of response
+ self.assertIn("FriendFeed", response.body)
"""
def __init__(self, *args, **kwargs):
super(AsyncTestCase, self).__init__(*args, **kwargs)
* `tornado.iostream.IOStream.write` now works correctly when given an
empty string.
-* `tornado.simple_httpclient` no longer hangs on ``HEAD`` requests
- and responses with no content.
+* `tornado.simple_httpclient` no longer hangs on ``HEAD`` requests,
+ responses with no content, or empty ``POST``/``PUT`` response bodies.
* `tornado.websocket` has been updated to support the latest protocol
(as finalized in RFC 6455).
* `tornado.platform.twisted` compatibility has been improved. However,