prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Double check conditional HTTP implementation
  The conditional HTTP implementation doesn't check the status code of the response at all. Determine if it should, and if it should update it to do the right thing.
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `warehouse/cache/http.py`
  Content:
  ```
  1 # Licensed under the Apache License, Version 2.0 (the "License");
  2 # you may not use this file except in compliance with the License.
  3 # You may obtain a copy of the License at
  4 #
  5 # http://www.apache.org/licenses/LICENSE-2.0
  6 #
  7 # Unless required by applicable law or agreed to in writing, software
  8 # distributed under the License is distributed on an "AS IS" BASIS,
  9 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10 # See the License for the specific language governing permissions and
  11 # limitations under the License.
  12 
  13 import collections.abc
  14 import functools
  15 
  16 from pyramid.tweens import EXCVIEW
  17 
  18 
  19 def _add_vary_callback(*varies):
  20     def inner(request, response):
  21         vary = set(response.vary if response.vary is not None else [])
  22         vary |= set(varies)
  23         response.vary = vary
  24     return inner
  25 
  26 
  27 def add_vary(*varies):
  28     def inner(view):
  29         @functools.wraps(view)
  30         def wrapped(context, request):
  31             request.add_response_callback(_add_vary_callback(*varies))
  32             return view(context, request)
  33         return wrapped
  34     return inner
  35 
  36 
  37 def cache_control(seconds, public=True):
  38     def inner(view):
  39         @functools.wraps(view)
  40         def wrapped(context, request):
  41             response = view(context, request)
  42 
  43             if not request.registry.settings.get(
  44                     "pyramid.prevent_http_cache", False):
  45                 if seconds:
  46                     if public:
  47                         response.cache_control.public = True
  48                     else:
  49                         response.cache_control.private = True
  50 
  51                     response.cache_control.max_age = seconds
  52                 else:
  53                     response.cache_control.no_cache = True
  54                     response.cache_control.no_store = True
  55                     response.cache_control.must_revalidate = True
  56 
  57             return response
  58         return wrapped
  59     return inner
  60 
  61 
  62 def conditional_http_tween_factory(handler, registry):
  63     def conditional_http_tween(request):
  64         response = handler(request)
  65 
  66         # If the Last-Modified header has been set, we want to enable the
  67         # conditional response processing.
  68         if response.last_modified is not None:
  69             response.conditional_response = True
  70 
  71         # We want to only enable the conditional machinery if either we
  72         # were given an explicit ETag header by the view or we have a
  73         # buffered response and can generate the ETag header ourself.
  74         if response.etag is not None:
  75             response.conditional_response = True
  76         elif (isinstance(response.app_iter, collections.abc.Sequence) and
  77                 len(response.app_iter) == 1):
  78             response.conditional_response = True
  79             response.md5_etag()
  80 
  81         return response
  82     return conditional_http_tween
  83 
  84 
  85 def includeme(config):
  86     config.add_tween(
  87         "warehouse.cache.http.conditional_http_tween_factory",
  88         under=EXCVIEW,
  89     )
  90
  ```
  --- END FILES ---
  
  Please first localize the bug based on the issue statement, and then generate a patch according to the `git diff` format fenced by three backticks.
  
  Here is an example:
  
  ```diff
  diff --git a/examples/server_async.py b/examples/server_async.py
  --- a/examples/server_async.py
  +++ b/examples/server_async.py
  @@ -313,4 +313,4 @@
   
   
   if __name__ == "__main__":
  -    asyncio.run(run_async_server("."), debug=True)
  +    asyncio.run(run_async_server(), debug=True)
  diff --git a/examples/server_sync.py b/examples/server_sync.py
  --- a/examples/server_sync.py
  +++ b/examples/server_sync.py
  @@ -313,5 +313,5 @@
   
   
   if __name__ == "__main__":
  -    server = run_sync_server(".")
  +    server = run_sync_server()
       server.shutdown()
  
  ```
  
golden_diff: diff --git a/warehouse/cache/http.py b/warehouse/cache/http.py
  --- a/warehouse/cache/http.py
  +++ b/warehouse/cache/http.py
  @@ -75,8 +75,13 @@
               response.conditional_response = True
           elif (isinstance(response.app_iter, collections.abc.Sequence) and
                   len(response.app_iter) == 1):
  -            response.conditional_response = True
  -            response.md5_etag()
  +            # We can only reasonably implement automatic ETags on 200 responses
  +            # to GET or HEAD requests. The subtles of doing it in other cases
  +            # are too hard to get right.
  +            if (request.method in {"GET", "HEAD"} and
  +                    response.status_code == 200):
  +                response.conditional_response = True
  +                response.md5_etag()
   
           return response
       return conditional_http_tween
  
verification_info: {"golden_diff": "diff --git a/warehouse/cache/http.py b/warehouse/cache/http.py\n--- a/warehouse/cache/http.py\n+++ b/warehouse/cache/http.py\n@@ -75,8 +75,13 @@\n             response.conditional_response = True\n         elif (isinstance(response.app_iter, collections.abc.Sequence) and\n                 len(response.app_iter) == 1):\n-            response.conditional_response = True\n-            response.md5_etag()\n+            # We can only reasonably implement automatic ETags on 200 responses\n+            # to GET or HEAD requests. The subtles of doing it in other cases\n+            # are too hard to get right.\n+            if (request.method in {\"GET\", \"HEAD\"} and\n+                    response.status_code == 200):\n+                response.conditional_response = True\n+                response.md5_etag()\n \n         return response\n     return conditional_http_tween\n", "issue": "Double check conditional HTTP implementation\nThe conditional HTTP implementation doesn't check the status code of the response at all. Determine if it should, and if it should update it to do the right thing.\n\n", "before_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport collections.abc\nimport functools\n\nfrom pyramid.tweens import EXCVIEW\n\n\ndef _add_vary_callback(*varies):\n    def inner(request, response):\n        vary = set(response.vary if response.vary is not None else [])\n        vary |= set(varies)\n        response.vary = vary\n    return inner\n\n\ndef add_vary(*varies):\n    def inner(view):\n        @functools.wraps(view)\n        def wrapped(context, request):\n            request.add_response_callback(_add_vary_callback(*varies))\n            return view(context, request)\n        return wrapped\n    return inner\n\n\ndef cache_control(seconds, public=True):\n    def inner(view):\n        @functools.wraps(view)\n        def wrapped(context, request):\n            response = view(context, request)\n\n            if not request.registry.settings.get(\n                    \"pyramid.prevent_http_cache\", False):\n                if seconds:\n                    if public:\n                        response.cache_control.public = True\n                    else:\n                        response.cache_control.private = True\n\n                    response.cache_control.max_age = seconds\n                else:\n                    response.cache_control.no_cache = True\n                    response.cache_control.no_store = True\n                    response.cache_control.must_revalidate = True\n\n            return response\n        return wrapped\n    return inner\n\n\ndef conditional_http_tween_factory(handler, registry):\n    def conditional_http_tween(request):\n        response = handler(request)\n\n        # If the Last-Modified header has been set, we want to enable the\n        # conditional response processing.\n        if response.last_modified is not None:\n            response.conditional_response = True\n\n        # We want to only enable the conditional machinery if either we\n        # were given an explicit ETag header by the view or we have a\n        # buffered response and can generate the ETag header ourself.\n        if response.etag is not None:\n            response.conditional_response = True\n        elif (isinstance(response.app_iter, collections.abc.Sequence) and\n                len(response.app_iter) == 1):\n            response.conditional_response = True\n            response.md5_etag()\n\n        return response\n    return conditional_http_tween\n\n\ndef includeme(config):\n    config.add_tween(\n        \"warehouse.cache.http.conditional_http_tween_factory\",\n        under=EXCVIEW,\n    )\n", "path": "warehouse/cache/http.py"}], "after_files": [{"content": "# Licensed under the Apache License, Version 2.0 (the \"License\");\n# you may not use this file except in compliance with the License.\n# You may obtain a copy of the License at\n#\n# http://www.apache.org/licenses/LICENSE-2.0\n#\n# Unless required by applicable law or agreed to in writing, software\n# distributed under the License is distributed on an \"AS IS\" BASIS,\n# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n# See the License for the specific language governing permissions and\n# limitations under the License.\n\nimport collections.abc\nimport functools\n\nfrom pyramid.tweens import EXCVIEW\n\n\ndef _add_vary_callback(*varies):\n    def inner(request, response):\n        vary = set(response.vary if response.vary is not None else [])\n        vary |= set(varies)\n        response.vary = vary\n    return inner\n\n\ndef add_vary(*varies):\n    def inner(view):\n        @functools.wraps(view)\n        def wrapped(context, request):\n            request.add_response_callback(_add_vary_callback(*varies))\n            return view(context, request)\n        return wrapped\n    return inner\n\n\ndef cache_control(seconds, public=True):\n    def inner(view):\n        @functools.wraps(view)\n        def wrapped(context, request):\n            response = view(context, request)\n\n            if not request.registry.settings.get(\n                    \"pyramid.prevent_http_cache\", False):\n                if seconds:\n                    if public:\n                        response.cache_control.public = True\n                    else:\n                        response.cache_control.private = True\n\n                    response.cache_control.max_age = seconds\n                else:\n                    response.cache_control.no_cache = True\n                    response.cache_control.no_store = True\n                    response.cache_control.must_revalidate = True\n\n            return response\n        return wrapped\n    return inner\n\n\ndef conditional_http_tween_factory(handler, registry):\n    def conditional_http_tween(request):\n        response = handler(request)\n\n        # If the Last-Modified header has been set, we want to enable the\n        # conditional response processing.\n        if response.last_modified is not None:\n            response.conditional_response = True\n\n        # We want to only enable the conditional machinery if either we\n        # were given an explicit ETag header by the view or we have a\n        # buffered response and can generate the ETag header ourself.\n        if response.etag is not None:\n            response.conditional_response = True\n        elif (isinstance(response.app_iter, collections.abc.Sequence) and\n                len(response.app_iter) == 1):\n            # We can only reasonably implement automatic ETags on 200 responses\n            # to GET or HEAD requests. The subtles of doing it in other cases\n            # are too hard to get right.\n            if (request.method in {\"GET\", \"HEAD\"} and\n                    response.status_code == 200):\n                response.conditional_response = True\n                response.md5_etag()\n\n        return response\n    return conditional_http_tween\n\n\ndef includeme(config):\n    config.add_tween(\n        \"warehouse.cache.http.conditional_http_tween_factory\",\n        under=EXCVIEW,\n    )\n", "path": "warehouse/cache/http.py"}]}