tornado and tr/http_test.py: fix HTTPServer-related circular references.

Among other things, every web.RequestHandler object would end up leaking and
need to be picked up later by the garbage collector.

Add some checks to tr/http_test to make sure that these particular bugs
don't come back.  Note that we *didn't* add a GcChecker to
http_test.HttpTest itself (the bulk of the tests) yet, because it still
leaks objects, albeit fewer than before.  We can fix the rest in a future
commit.

Change-Id: Icd66b5fe1b775b80e6fc0f199cb2b89d60a57ee6
diff --git a/tornado/httpclient.py b/tornado/httpclient.py
index 6ad591b..849b762 100644
--- a/tornado/httpclient.py
+++ b/tornado/httpclient.py
@@ -180,6 +180,7 @@
             if self._instance_cache.get(self.io_loop) is not self:
                 raise RuntimeError("inconsistent AsyncHTTPClient cache")
             del self._instance_cache[self.io_loop]
+            self._instance_cache = None
 
     def fetch(self, request, callback, **kwargs):
         """Executes a request, calling callback with an `HTTPResponse`.
@@ -419,7 +420,7 @@
     def __init__(self, code, message=None, response=None):
         self.code = code
         message = message or httplib.responses.get(code, "Unknown")
-        self.response = response
+        # self.response = response  # removed to avoid circular references
         Exception.__init__(self, "HTTP %d: %s" % (self.code, message))
 
 
diff --git a/tornado/httpserver.py b/tornado/httpserver.py
index 0c5bd00..bbe4a21 100644
--- a/tornado/httpserver.py
+++ b/tornado/httpserver.py
@@ -182,6 +182,9 @@
         callback()
         # Delete any unfinished callbacks to break up reference cycles.
         self._write_callback = None
+        self._header_callback = None
+        self.request_callback = None
+        self.stream = None
 
     def write(self, chunk, callback=None):
         """Writes a chunk of output to the stream."""
diff --git a/tornado/testing.py b/tornado/testing.py
index de67214..9e29292 100644
--- a/tornado/testing.py
+++ b/tornado/testing.py
@@ -165,6 +165,9 @@
             self.io_loop.stop()
             self.__running = False
         self.__stopped = True
+        if self.__timeout is not None:
+          self.io_loop.remove_timeout(self.__timeout)
+          self.__timeout = None
 
     def wait(self, condition=None, timeout=5):
         """Runs the IOLoop until stop is called or timeout has passed.
diff --git a/tornado/web.py b/tornado/web.py
index 10e3420..5a0422f 100644
--- a/tornado/web.py
+++ b/tornado/web.py
@@ -689,7 +689,8 @@
                 content_length = sum(len(part) for part in self._write_buffer)
                 self.set_header("Content-Length", content_length)
 
-        if hasattr(self.request, "connection"):
+        # NOTE(apenwarr): breaks httpserver.HTTPConnection.set_close_callback
+        if 0 and hasattr(self.request, "connection"):
             # Now that the request is finished, clear the callback we
             # set on the IOStream (which would otherwise prevent the
             # garbage collection of the RequestHandler when there
@@ -702,6 +703,7 @@
             self._log()
         self._finished = True
         self.on_finish()
+        self.ui = None
 
     def send_error(self, status_code=500, **kwargs):
         """Sends the given HTTP error code to the browser.