]> git.ipfire.org Git - thirdparty/tornado.git/commitdiff
206 in response to Range, refactor ETag checking 790/head
authorDavid Wolever <david@wolever.net>
Sat, 18 May 2013 20:36:37 +0000 (16:36 -0400)
committerDavid Wolever <david@wolever.net>
Sat, 18 May 2013 20:36:37 +0000 (16:36 -0400)
tornado/test/web_test.py
tornado/web.py

index 751cde929ada07ecf2c858b2e5bb43549ae09eb4..00d0ea0d3d41fb63e8a717accc23d46de36db8d4 100644 (file)
@@ -871,6 +871,7 @@ class StaticFileTest(WebTestCase):
     def test_static_with_range(self):
         response = self.fetch('/static/robots.txt', headers={
                 'Range': 'bytes=0-9'})
+        self.assertEqual(response.code, 206)
         self.assertEqual(response.body, b"User-agent")
         self.assertEqual(utf8(response.headers.get("Etag")),
                          b'"' + self.robots_txt_hash + b'"')
index 447c5b7385cf15a1c835d72588843e54a35d4c3e..690d2ecc44922ed62ae2061f88a59f304c5bd62a 100644 (file)
@@ -730,13 +730,10 @@ class RequestHandler(object):
             if (self._status_code == 200 and
                 self.request.method in ("GET", "HEAD") and
                     "Etag" not in self._headers):
-                etag = self.compute_etag()
-                if etag is not None:
-                    self.set_header("Etag", etag)
-                    inm = self.request.headers.get("If-None-Match")
-                    if inm and inm.find(etag) != -1:
-                        self._write_buffer = []
-                        self.set_status(304)
+                self.set_etag_header()
+                if self.check_etag_header():
+                    self._write_buffer = []
+                    self.set_status(304)
             if self._status_code == 304:
                 assert not self._write_buffer, "Cannot send body with 304"
                 self._clear_headers_for_304()
@@ -1063,6 +1060,30 @@ class RequestHandler(object):
             hasher.update(part)
         return '"%s"' % hasher.hexdigest()
 
+    def set_etag_header(self):
+        """Sets the response's Etag header using ``self.compute_etag()``.
+
+        Note: no header will be set if ``compute_etag()`` returns ``None``.
+        """
+        etag = self.compute_etag()
+        if etag is not None:
+            self.set_header("Etag", etag)
+
+    def check_etag_header(self):
+        """Checks the ``Etag`` header against requests's ``If-None-Match``.
+
+        Returns ``True`` if the request's Etag matches and a 304 should be
+        returned. For example::
+
+            self.set_etag_header()
+            if self.check_etag_header():
+                self.set_status(304)
+                return
+        """
+        etag = self._headers.get("Etag")
+        inm = utf8(self.request.headers.get("If-None-Match", ""))
+        return bool(etag and inm and inm.find(etag) >= 0)
+
     def _stack_context_handle_exception(self, type, value, traceback):
         try:
             # For historical reasons _handle_request_exception only takes
@@ -1754,6 +1775,11 @@ class StaticFileHandler(RequestHandler):
                 self.set_status(304)
                 return
 
+        self.set_etag_header()
+        if self.check_etag_header():
+            self.set_status(304)
+            return
+
         self.set_header("Accept-Ranges", "bytes")
         request_range = None
         range_header = self.request.headers.get("Range")
@@ -1771,6 +1797,8 @@ class StaticFileHandler(RequestHandler):
         with open(abspath, "rb") as file:
             data = file.read()
             if request_range:
+                # 206: Partial Content
+                self.set_status(206)
                 content_range = httputil.get_content_range(data, request_range)
                 self.set_header("Content-Range", content_range)
                 data = data[request_range]