prompt: We are currently solving the following issue within our repository. Here is the issue text:
  --- BEGIN ISSUE ---
  Missing CORS header on /v1/buckets/default/collections/tasks/records
  > 09:19:55,733 Blocage d'une requête multi-origines (Cross-Origin Request) : la politique « Same Origin » ne permet pas de consulter la ressource distante située sur http://0.0.0.0:8888/v1/buckets/default/collections/tasks/records?_since=1436512795672. Raison : l'en-tête CORS « Access-Control-Allow-Origin » est manquant.1 <inconnu>
  
  
  --- END ISSUE ---
  
  Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
  --- BEGIN FILES ---
  Path: `kinto/views/buckets.py`
  Content:
  ```
  1 from six import text_type
  2 from uuid import UUID
  3 
  4 from pyramid.httpexceptions import HTTPForbidden, HTTPPreconditionFailed
  5 from pyramid.security import NO_PERMISSION_REQUIRED
  6 from pyramid.view import view_config
  7 
  8 from cliquet import resource
  9 from cliquet.utils import hmac_digest, build_request
  10 
  11 from kinto.views import NameGenerator
  12 
  13 
  14 def create_bucket(request, bucket_id):
  15     """Create a bucket if it doesn't exists."""
  16     bucket_put = (request.method.lower() == 'put' and
  17                   request.path.endswith('buckets/default'))
  18 
  19     if not bucket_put:
  20         subrequest = build_request(request, {
  21             'method': 'PUT',
  22             'path': '/buckets/%s' % bucket_id,
  23             'body': {"data": {}},
  24             'headers': {'If-None-Match': '*'.encode('utf-8')}
  25         })
  26 
  27         try:
  28             request.invoke_subrequest(subrequest)
  29         except HTTPPreconditionFailed:
  30             # The bucket already exists
  31             pass
  32 
  33 
  34 def create_collection(request, bucket_id):
  35     subpath = request.matchdict['subpath']
  36     if subpath.startswith('/collections/'):
  37         collection_id = subpath.split('/')[2]
  38         collection_put = (request.method.lower() == 'put' and
  39                           request.path.endswith(collection_id))
  40         if not collection_put:
  41             subrequest = build_request(request, {
  42                 'method': 'PUT',
  43                 'path': '/buckets/%s/collections/%s' % (
  44                     bucket_id, collection_id),
  45                 'body': {"data": {}},
  46                 'headers': {'If-None-Match': '*'.encode('utf-8')}
  47             })
  48             try:
  49                 request.invoke_subrequest(subrequest)
  50             except HTTPPreconditionFailed:
  51                 # The collection already exists
  52                 pass
  53 
  54 
  55 @view_config(route_name='default_bucket', permission=NO_PERMISSION_REQUIRED)
  56 def default_bucket(request):
  57     if request.method.lower() == 'options':
  58         path = request.path.replace('default', 'unknown')
  59         subrequest = build_request(request, {
  60             'method': 'OPTIONS',
  61             'path': path
  62         })
  63         return request.invoke_subrequest(subrequest)
  64 
  65     if getattr(request, 'prefixed_userid', None) is None:
  66         raise HTTPForbidden  # Pass through the forbidden_view_config
  67 
  68     settings = request.registry.settings
  69     hmac_secret = settings['cliquet.userid_hmac_secret']
  70     # Build the user unguessable bucket_id UUID from its user_id
  71     digest = hmac_digest(hmac_secret, request.prefixed_userid)
  72     bucket_id = text_type(UUID(digest[:32]))
  73     path = request.path.replace('default', bucket_id)
  74     querystring = request.url[(request.url.index(request.path) +
  75                                len(request.path)):]
  76 
  77     # Make sure bucket exists
  78     create_bucket(request, bucket_id)
  79 
  80     # Make sure the collection exists
  81     create_collection(request, bucket_id)
  82 
  83     subrequest = build_request(request, {
  84         'method': request.method,
  85         'path': path + querystring,
  86         'body': request.body
  87     })
  88 
  89     return request.invoke_subrequest(subrequest)
  90 
  91 
  92 @resource.register(name='bucket',
  93                    collection_methods=('GET',),
  94                    collection_path='/buckets',
  95                    record_path='/buckets/{{id}}')
  96 class Bucket(resource.ProtectedResource):
  97     permissions = ('read', 'write', 'collection:create', 'group:create')
  98 
  99     def __init__(self, *args, **kwargs):
  100         super(Bucket, self).__init__(*args, **kwargs)
  101         self.collection.id_generator = NameGenerator()
  102 
  103     def get_parent_id(self, request):
  104         # Buckets are not isolated by user, unlike Cliquet resources.
  105         return ''
  106 
  107     def delete(self):
  108         result = super(Bucket, self).delete()
  109 
  110         # Delete groups.
  111         storage = self.collection.storage
  112         parent_id = '/buckets/%s' % self.record_id
  113         storage.delete_all(collection_id='group', parent_id=parent_id)
  114 
  115         # Delete collections.
  116         deleted = storage.delete_all(collection_id='collection',
  117                                      parent_id=parent_id)
  118 
  119         # Delete records.
  120         id_field = self.collection.id_field
  121         for collection in deleted:
  122             parent_id = '/buckets/%s/collections/%s' % (self.record_id,
  123                                                         collection[id_field])
  124             storage.delete_all(collection_id='record', parent_id=parent_id)
  125 
  126         return result
  127
  ```
  --- 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/kinto/views/buckets.py b/kinto/views/buckets.py
  --- a/kinto/views/buckets.py
  +++ b/kinto/views/buckets.py
  @@ -1,12 +1,13 @@
   from six import text_type
   from uuid import UUID
   
  -from pyramid.httpexceptions import HTTPForbidden, HTTPPreconditionFailed
  +from pyramid.httpexceptions import (HTTPForbidden, HTTPPreconditionFailed,
  +                                    HTTPException)
   from pyramid.security import NO_PERMISSION_REQUIRED
   from pyramid.view import view_config
   
   from cliquet import resource
  -from cliquet.utils import hmac_digest, build_request
  +from cliquet.utils import hmac_digest, build_request, reapply_cors
   
   from kinto.views import NameGenerator
   
  @@ -86,7 +87,11 @@
           'body': request.body
       })
   
  -    return request.invoke_subrequest(subrequest)
  +    try:
  +        response = request.invoke_subrequest(subrequest)
  +    except HTTPException as error:
  +        response = reapply_cors(subrequest, error)
  +    return response
   
   
   @resource.register(name='bucket',
  
verification_info: {"golden_diff": "diff --git a/kinto/views/buckets.py b/kinto/views/buckets.py\n--- a/kinto/views/buckets.py\n+++ b/kinto/views/buckets.py\n@@ -1,12 +1,13 @@\n from six import text_type\n from uuid import UUID\n \n-from pyramid.httpexceptions import HTTPForbidden, HTTPPreconditionFailed\n+from pyramid.httpexceptions import (HTTPForbidden, HTTPPreconditionFailed,\n+                                    HTTPException)\n from pyramid.security import NO_PERMISSION_REQUIRED\n from pyramid.view import view_config\n \n from cliquet import resource\n-from cliquet.utils import hmac_digest, build_request\n+from cliquet.utils import hmac_digest, build_request, reapply_cors\n \n from kinto.views import NameGenerator\n \n@@ -86,7 +87,11 @@\n         'body': request.body\n     })\n \n-    return request.invoke_subrequest(subrequest)\n+    try:\n+        response = request.invoke_subrequest(subrequest)\n+    except HTTPException as error:\n+        response = reapply_cors(subrequest, error)\n+    return response\n \n \n @resource.register(name='bucket',\n", "issue": "Missing CORS header on /v1/buckets/default/collections/tasks/records\n> 09:19:55,733 Blocage d'une requ\u00eate multi-origines (Cross-Origin Request)\u00a0: la politique \u00ab\u00a0Same Origin\u00a0\u00bb ne permet pas de consulter la ressource distante situ\u00e9e sur http://0.0.0.0:8888/v1/buckets/default/collections/tasks/records?_since=1436512795672. Raison\u00a0: l'en-t\u00eate CORS \u00ab\u00a0Access-Control-Allow-Origin\u00a0\u00bb est manquant.1 <inconnu>\n\n", "before_files": [{"content": "from six import text_type\nfrom uuid import UUID\n\nfrom pyramid.httpexceptions import HTTPForbidden, HTTPPreconditionFailed\nfrom pyramid.security import NO_PERMISSION_REQUIRED\nfrom pyramid.view import view_config\n\nfrom cliquet import resource\nfrom cliquet.utils import hmac_digest, build_request\n\nfrom kinto.views import NameGenerator\n\n\ndef create_bucket(request, bucket_id):\n    \"\"\"Create a bucket if it doesn't exists.\"\"\"\n    bucket_put = (request.method.lower() == 'put' and\n                  request.path.endswith('buckets/default'))\n\n    if not bucket_put:\n        subrequest = build_request(request, {\n            'method': 'PUT',\n            'path': '/buckets/%s' % bucket_id,\n            'body': {\"data\": {}},\n            'headers': {'If-None-Match': '*'.encode('utf-8')}\n        })\n\n        try:\n            request.invoke_subrequest(subrequest)\n        except HTTPPreconditionFailed:\n            # The bucket already exists\n            pass\n\n\ndef create_collection(request, bucket_id):\n    subpath = request.matchdict['subpath']\n    if subpath.startswith('/collections/'):\n        collection_id = subpath.split('/')[2]\n        collection_put = (request.method.lower() == 'put' and\n                          request.path.endswith(collection_id))\n        if not collection_put:\n            subrequest = build_request(request, {\n                'method': 'PUT',\n                'path': '/buckets/%s/collections/%s' % (\n                    bucket_id, collection_id),\n                'body': {\"data\": {}},\n                'headers': {'If-None-Match': '*'.encode('utf-8')}\n            })\n            try:\n                request.invoke_subrequest(subrequest)\n            except HTTPPreconditionFailed:\n                # The collection already exists\n                pass\n\n\n@view_config(route_name='default_bucket', permission=NO_PERMISSION_REQUIRED)\ndef default_bucket(request):\n    if request.method.lower() == 'options':\n        path = request.path.replace('default', 'unknown')\n        subrequest = build_request(request, {\n            'method': 'OPTIONS',\n            'path': path\n        })\n        return request.invoke_subrequest(subrequest)\n\n    if getattr(request, 'prefixed_userid', None) is None:\n        raise HTTPForbidden  # Pass through the forbidden_view_config\n\n    settings = request.registry.settings\n    hmac_secret = settings['cliquet.userid_hmac_secret']\n    # Build the user unguessable bucket_id UUID from its user_id\n    digest = hmac_digest(hmac_secret, request.prefixed_userid)\n    bucket_id = text_type(UUID(digest[:32]))\n    path = request.path.replace('default', bucket_id)\n    querystring = request.url[(request.url.index(request.path) +\n                               len(request.path)):]\n\n    # Make sure bucket exists\n    create_bucket(request, bucket_id)\n\n    # Make sure the collection exists\n    create_collection(request, bucket_id)\n\n    subrequest = build_request(request, {\n        'method': request.method,\n        'path': path + querystring,\n        'body': request.body\n    })\n\n    return request.invoke_subrequest(subrequest)\n\n\n@resource.register(name='bucket',\n                   collection_methods=('GET',),\n                   collection_path='/buckets',\n                   record_path='/buckets/{{id}}')\nclass Bucket(resource.ProtectedResource):\n    permissions = ('read', 'write', 'collection:create', 'group:create')\n\n    def __init__(self, *args, **kwargs):\n        super(Bucket, self).__init__(*args, **kwargs)\n        self.collection.id_generator = NameGenerator()\n\n    def get_parent_id(self, request):\n        # Buckets are not isolated by user, unlike Cliquet resources.\n        return ''\n\n    def delete(self):\n        result = super(Bucket, self).delete()\n\n        # Delete groups.\n        storage = self.collection.storage\n        parent_id = '/buckets/%s' % self.record_id\n        storage.delete_all(collection_id='group', parent_id=parent_id)\n\n        # Delete collections.\n        deleted = storage.delete_all(collection_id='collection',\n                                     parent_id=parent_id)\n\n        # Delete records.\n        id_field = self.collection.id_field\n        for collection in deleted:\n            parent_id = '/buckets/%s/collections/%s' % (self.record_id,\n                                                        collection[id_field])\n            storage.delete_all(collection_id='record', parent_id=parent_id)\n\n        return result\n", "path": "kinto/views/buckets.py"}], "after_files": [{"content": "from six import text_type\nfrom uuid import UUID\n\nfrom pyramid.httpexceptions import (HTTPForbidden, HTTPPreconditionFailed,\n                                    HTTPException)\nfrom pyramid.security import NO_PERMISSION_REQUIRED\nfrom pyramid.view import view_config\n\nfrom cliquet import resource\nfrom cliquet.utils import hmac_digest, build_request, reapply_cors\n\nfrom kinto.views import NameGenerator\n\n\ndef create_bucket(request, bucket_id):\n    \"\"\"Create a bucket if it doesn't exists.\"\"\"\n    bucket_put = (request.method.lower() == 'put' and\n                  request.path.endswith('buckets/default'))\n\n    if not bucket_put:\n        subrequest = build_request(request, {\n            'method': 'PUT',\n            'path': '/buckets/%s' % bucket_id,\n            'body': {\"data\": {}},\n            'headers': {'If-None-Match': '*'.encode('utf-8')}\n        })\n\n        try:\n            request.invoke_subrequest(subrequest)\n        except HTTPPreconditionFailed:\n            # The bucket already exists\n            pass\n\n\ndef create_collection(request, bucket_id):\n    subpath = request.matchdict['subpath']\n    if subpath.startswith('/collections/'):\n        collection_id = subpath.split('/')[2]\n        collection_put = (request.method.lower() == 'put' and\n                          request.path.endswith(collection_id))\n        if not collection_put:\n            subrequest = build_request(request, {\n                'method': 'PUT',\n                'path': '/buckets/%s/collections/%s' % (\n                    bucket_id, collection_id),\n                'body': {\"data\": {}},\n                'headers': {'If-None-Match': '*'.encode('utf-8')}\n            })\n            try:\n                request.invoke_subrequest(subrequest)\n            except HTTPPreconditionFailed:\n                # The collection already exists\n                pass\n\n\n@view_config(route_name='default_bucket', permission=NO_PERMISSION_REQUIRED)\ndef default_bucket(request):\n    if request.method.lower() == 'options':\n        path = request.path.replace('default', 'unknown')\n        subrequest = build_request(request, {\n            'method': 'OPTIONS',\n            'path': path\n        })\n        return request.invoke_subrequest(subrequest)\n\n    if getattr(request, 'prefixed_userid', None) is None:\n        raise HTTPForbidden  # Pass through the forbidden_view_config\n\n    settings = request.registry.settings\n    hmac_secret = settings['cliquet.userid_hmac_secret']\n    # Build the user unguessable bucket_id UUID from its user_id\n    digest = hmac_digest(hmac_secret, request.prefixed_userid)\n    bucket_id = text_type(UUID(digest[:32]))\n    path = request.path.replace('default', bucket_id)\n    querystring = request.url[(request.url.index(request.path) +\n                               len(request.path)):]\n\n    # Make sure bucket exists\n    create_bucket(request, bucket_id)\n\n    # Make sure the collection exists\n    create_collection(request, bucket_id)\n\n    subrequest = build_request(request, {\n        'method': request.method,\n        'path': path + querystring,\n        'body': request.body\n    })\n\n    try:\n        response = request.invoke_subrequest(subrequest)\n    except HTTPException as error:\n        response = reapply_cors(subrequest, error)\n    return response\n\n\n@resource.register(name='bucket',\n                   collection_methods=('GET',),\n                   collection_path='/buckets',\n                   record_path='/buckets/{{id}}')\nclass Bucket(resource.ProtectedResource):\n    permissions = ('read', 'write', 'collection:create', 'group:create')\n\n    def __init__(self, *args, **kwargs):\n        super(Bucket, self).__init__(*args, **kwargs)\n        self.collection.id_generator = NameGenerator()\n\n    def get_parent_id(self, request):\n        # Buckets are not isolated by user, unlike Cliquet resources.\n        return ''\n\n    def delete(self):\n        result = super(Bucket, self).delete()\n\n        # Delete groups.\n        storage = self.collection.storage\n        parent_id = '/buckets/%s' % self.record_id\n        storage.delete_all(collection_id='group', parent_id=parent_id)\n\n        # Delete collections.\n        deleted = storage.delete_all(collection_id='collection',\n                                     parent_id=parent_id)\n\n        # Delete records.\n        id_field = self.collection.id_field\n        for collection in deleted:\n            parent_id = '/buckets/%s/collections/%s' % (self.record_id,\n                                                        collection[id_field])\n            storage.delete_all(collection_id='record', parent_id=parent_id)\n\n        return result\n", "path": "kinto/views/buckets.py"}]}