We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
GET on default bucket increases quota usage
While investigating #1225, I discovered that *every* GET request to e.g. `/buckets/default/collections/some-collection` causes quota usage to increase. For example,

```
select * from records where collection_id='quota';
       id        |                                    parent_id                 
                   | collection_id |       last_modified        |               
                data                                
-----------------+--------------------------------------------------------------
-------------------+---------------+----------------------------+---------------
----------------------------------------------------
 bucket_info     | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5                
                   | quota         | 2017-05-22 18:07:14.715782 | {"record_count
": 0, "storage_size": 1745, "collection_count": 13}
 collection_info | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5/collections/a-n
ewest-collection-3 | quota         | 2017-05-22 18:07:14.716923 | {"record_count
": 0, "storage_size": 540}
```

```
> http --auth 'user:pass6' 'localhost:8888/v1/buckets/default/collections/a-newest-collection-3'
HTTP/1.1 200 OK
..... more junk .....
```

```
select * from records where collection_id='quota';
       id        |                                    parent_id                 
                   | collection_id |       last_modified        |               
                data                                
-----------------+--------------------------------------------------------------
-------------------+---------------+----------------------------+---------------
----------------------------------------------------
 bucket_info     | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5                
                   | quota         | 2017-05-22 18:56:52.448115 | {"record_count
": 0, "storage_size": 1880, "collection_count": 14}
 collection_info | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5/collections/a-n
ewest-collection-3 | quota         | 2017-05-22 18:56:52.4493   | {"record_count
": 0, "storage_size": 600}
```

This appears to be partly because every request that goes to the default bucket "creates" a bucket and collection.

--- 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/plugins/default_bucket/__init__.py`
Content:
```
1 import uuid
2 
3 from pyramid import httpexceptions
4 from pyramid.settings import asbool
5 from pyramid.security import NO_PERMISSION_REQUIRED, Authenticated
6 
7 from kinto.core.errors import raise_invalid
8 from kinto.core.events import ACTIONS
9 from kinto.core.utils import (
10     build_request, reapply_cors, hmac_digest, instance_uri, view_lookup)
11 
12 from kinto.authorization import RouteFactory
13 from kinto.views.buckets import Bucket
14 from kinto.views.collections import Collection
15 
16 
17 def create_bucket(request, bucket_id):
18     """Create a bucket if it doesn't exists."""
19     bucket_put = (request.method.lower() == 'put' and
20                   request.path.endswith('buckets/default'))
21     # Do nothing if current request will already create the bucket.
22     if bucket_put:
23         return
24 
25     # Do not intent to create multiple times per request (e.g. in batch).
26     already_created = request.bound_data.setdefault('buckets', {})
27     if bucket_id in already_created:
28         return
29 
30     bucket_uri = instance_uri(request, 'bucket', id=bucket_id)
31     bucket = resource_create_object(request=request,
32                                     resource_cls=Bucket,
33                                     uri=bucket_uri)
34     already_created[bucket_id] = bucket
35 
36 
37 def create_collection(request, bucket_id):
38     # Do nothing if current request does not involve a collection.
39     subpath = request.matchdict.get('subpath')
40     if not (subpath and subpath.rstrip('/').startswith('collections/')):
41         return
42 
43     collection_id = subpath.split('/')[1]
44     collection_uri = instance_uri(request, 'collection',
45                                   bucket_id=bucket_id,
46                                   id=collection_id)
47 
48     # Do not intent to create multiple times per request (e.g. in batch).
49     already_created = request.bound_data.setdefault('collections', {})
50     if collection_uri in already_created:
51         return
52 
53     # Do nothing if current request will already create the collection.
54     collection_put = (request.method.lower() == 'put' and
55                       request.path.endswith(collection_id))
56     if collection_put:
57         return
58 
59     collection = resource_create_object(request=request,
60                                         resource_cls=Collection,
61                                         uri=collection_uri)
62     already_created[collection_uri] = collection
63 
64 
65 def resource_create_object(request, resource_cls, uri):
66     """In the default bucket, the bucket and collection are implicitly
67     created. This helper instantiate the resource and simulate a request
68     with its RootFactory on the instantiated resource.
69     :returns: the created object
70     :rtype: dict
71     """
72     resource_name, matchdict = view_lookup(request, uri)
73 
74     # Build a fake request, mainly used to populate the create events that
75     # will be triggered by the resource.
76     fakerequest = build_request(request, {
77         'method': 'PUT',
78         'path': uri,
79     })
80     fakerequest.matchdict = matchdict
81     fakerequest.bound_data = request.bound_data
82     fakerequest.authn_type = request.authn_type
83     fakerequest.selected_userid = request.selected_userid
84     fakerequest.errors = request.errors
85     fakerequest.current_resource_name = resource_name
86 
87     obj_id = matchdict['id']
88 
89     # Fake context, required to instantiate a resource.
90     context = RouteFactory(fakerequest)
91     context.resource_name = resource_name
92     resource = resource_cls(fakerequest, context)
93 
94     # Check that provided id is valid for this resource.
95     if not resource.model.id_generator.match(obj_id):
96         error_details = {
97             'location': 'path',
98             'description': "Invalid {} id".format(resource_name)
99         }
100         raise_invalid(resource.request, **error_details)
101 
102     data = {'id': obj_id}
103     obj = resource.model.create_record(data, ignore_conflict=True)
104     # Since the current request is not a resource (but a straight Service),
105     # we simulate a request on a resource.
106     # This will be used in the resource event payload.
107     resource.postprocess(obj, action=ACTIONS.CREATE)
108     return obj
109 
110 
111 def default_bucket(request):
112     if request.method.lower() == 'options':
113         path = request.path.replace('default', 'unknown')
114         subrequest = build_request(request, {
115             'method': 'OPTIONS',
116             'path': path
117         })
118         return request.invoke_subrequest(subrequest)
119 
120     if Authenticated not in request.effective_principals:
121         # Pass through the forbidden_view_config
122         raise httpexceptions.HTTPForbidden()
123 
124     settings = request.registry.settings
125 
126     if asbool(settings['readonly']):
127         raise httpexceptions.HTTPMethodNotAllowed()
128 
129     bucket_id = request.default_bucket_id
130 
131     # Implicit object creations.
132     # Make sure bucket exists
133     create_bucket(request, bucket_id)
134     # Make sure the collection exists
135     create_collection(request, bucket_id)
136 
137     path = request.path.replace('/buckets/default', '/buckets/{}'.format(bucket_id))
138     querystring = request.url[(request.url.index(request.path) +
139                                len(request.path)):]
140     try:
141         # If 'id' is provided as 'default', replace with actual bucket id.
142         body = request.json
143         body['data']['id'] = body['data']['id'].replace('default', bucket_id)
144     except:
145         body = request.body or {"data": {}}
146     subrequest = build_request(request, {
147         'method': request.method,
148         'path': path + querystring,
149         'body': body,
150     })
151     subrequest.bound_data = request.bound_data
152 
153     try:
154         response = request.invoke_subrequest(subrequest)
155     except httpexceptions.HTTPException as error:
156         is_redirect = error.status_code < 400
157         if error.content_type == 'application/json' or is_redirect:
158             response = reapply_cors(subrequest, error)
159         else:
160             # Ask the upper level to format the error.
161             raise error
162     return response
163 
164 
165 def default_bucket_id(request):
166     settings = request.registry.settings
167     secret = settings['userid_hmac_secret']
168     # Build the user unguessable bucket_id UUID from its user_id
169     digest = hmac_digest(secret, request.prefixed_userid)
170     return str(uuid.UUID(digest[:32]))
171 
172 
173 def get_user_info(request):
174     user_info = {
175         'id': request.prefixed_userid,
176         'bucket': request.default_bucket_id
177     }
178     return user_info
179 
180 
181 def includeme(config):
182     # Redirect default to the right endpoint
183     config.add_view(default_bucket,
184                     route_name='default_bucket',
185                     permission=NO_PERMISSION_REQUIRED)
186     config.add_view(default_bucket,
187                     route_name='default_bucket_collection',
188                     permission=NO_PERMISSION_REQUIRED)
189 
190     config.add_route('default_bucket_collection',
191                      '/buckets/default/{subpath:.*}')
192     config.add_route('default_bucket', '/buckets/default')
193 
194     # Provide helpers
195     config.add_request_method(default_bucket_id, reify=True)
196     # Override kinto.core default user info
197     config.add_request_method(get_user_info)
198 
199     config.add_api_capability(
200         "default_bucket",
201         description="The default bucket is an alias for a personal"
202                     " bucket where collections are created implicitly.",
203         url="https://kinto.readthedocs.io/en/latest/api/1.x/"
204             "buckets.html#personal-bucket-default")
205
```
--- 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()

```

diff --git a/kinto/plugins/default_bucket/__init__.py b/kinto/plugins/default_bucket/__init__.py
--- a/kinto/plugins/default_bucket/__init__.py
+++ b/kinto/plugins/default_bucket/__init__.py
@@ -6,6 +6,7 @@
 
 from kinto.core.errors import raise_invalid
 from kinto.core.events import ACTIONS
+from kinto.core.storage.exceptions import UnicityError
 from kinto.core.utils import (
     build_request, reapply_cors, hmac_digest, instance_uri, view_lookup)
 
@@ -100,7 +101,12 @@
         raise_invalid(resource.request, **error_details)
 
     data = {'id': obj_id}
-    obj = resource.model.create_record(data, ignore_conflict=True)
+    try:
+        obj = resource.model.create_record(data)
+    except UnicityError as e:
+        # The record already exists; skip running events
+        return e.record
+
     # Since the current request is not a resource (but a straight Service),
     # we simulate a request on a resource.
     # This will be used in the resource event payload.

{"golden_diff": "diff --git a/kinto/plugins/default_bucket/__init__.py b/kinto/plugins/default_bucket/__init__.py\n--- a/kinto/plugins/default_bucket/__init__.py\n+++ b/kinto/plugins/default_bucket/__init__.py\n@@ -6,6 +6,7 @@\n \n from kinto.core.errors import raise_invalid\n from kinto.core.events import ACTIONS\n+from kinto.core.storage.exceptions import UnicityError\n from kinto.core.utils import (\n     build_request, reapply_cors, hmac_digest, instance_uri, view_lookup)\n \n@@ -100,7 +101,12 @@\n         raise_invalid(resource.request, **error_details)\n \n     data = {'id': obj_id}\n-    obj = resource.model.create_record(data, ignore_conflict=True)\n+    try:\n+        obj = resource.model.create_record(data)\n+    except UnicityError as e:\n+        # The record already exists; skip running events\n+        return e.record\n+\n     # Since the current request is not a resource (but a straight Service),\n     # we simulate a request on a resource.\n     # This will be used in the resource event payload.\n", "issue": "GET on default bucket increases quota usage\nWhile investigating #1225, I discovered that *every* GET request to e.g. `/buckets/default/collections/some-collection` causes quota usage to increase. For example,\r\n\r\n```\r\nselect * from records where collection_id='quota';\r\n       id        |                                    parent_id                 \r\n                   | collection_id |       last_modified        |               \r\n                data                                \r\n-----------------+--------------------------------------------------------------\r\n-------------------+---------------+----------------------------+---------------\r\n----------------------------------------------------\r\n bucket_info     | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5                \r\n                   | quota         | 2017-05-22 18:07:14.715782 | {\"record_count\r\n\": 0, \"storage_size\": 1745, \"collection_count\": 13}\r\n collection_info | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5/collections/a-n\r\newest-collection-3 | quota         | 2017-05-22 18:07:14.716923 | {\"record_count\r\n\": 0, \"storage_size\": 540}\r\n```\r\n\r\n```\r\n> http --auth 'user:pass6' 'localhost:8888/v1/buckets/default/collections/a-newest-collection-3'\r\nHTTP/1.1 200 OK\r\n..... more junk .....\r\n```\r\n\r\n```\r\nselect * from records where collection_id='quota';\r\n       id        |                                    parent_id                 \r\n                   | collection_id |       last_modified        |               \r\n                data                                \r\n-----------------+--------------------------------------------------------------\r\n-------------------+---------------+----------------------------+---------------\r\n----------------------------------------------------\r\n bucket_info     | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5                \r\n                   | quota         | 2017-05-22 18:56:52.448115 | {\"record_count\r\n\": 0, \"storage_size\": 1880, \"collection_count\": 14}\r\n collection_info | /buckets/74f86a68-a03c-a5f5-fb29-e421b362f5b5/collections/a-n\r\newest-collection-3 | quota         | 2017-05-22 18:56:52.4493   | {\"record_count\r\n\": 0, \"storage_size\": 600}\r\n```\r\n\r\nThis appears to be partly because every request that goes to the default bucket \"creates\" a bucket and collection.\n", "before_files": [{"content": "import uuid\n\nfrom pyramid import httpexceptions\nfrom pyramid.settings import asbool\nfrom pyramid.security import NO_PERMISSION_REQUIRED, Authenticated\n\nfrom kinto.core.errors import raise_invalid\nfrom kinto.core.events import ACTIONS\nfrom kinto.core.utils import (\n    build_request, reapply_cors, hmac_digest, instance_uri, view_lookup)\n\nfrom kinto.authorization import RouteFactory\nfrom kinto.views.buckets import Bucket\nfrom kinto.views.collections import Collection\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    # Do nothing if current request will already create the bucket.\n    if bucket_put:\n        return\n\n    # Do not intent to create multiple times per request (e.g. in batch).\n    already_created = request.bound_data.setdefault('buckets', {})\n    if bucket_id in already_created:\n        return\n\n    bucket_uri = instance_uri(request, 'bucket', id=bucket_id)\n    bucket = resource_create_object(request=request,\n                                    resource_cls=Bucket,\n                                    uri=bucket_uri)\n    already_created[bucket_id] = bucket\n\n\ndef create_collection(request, bucket_id):\n    # Do nothing if current request does not involve a collection.\n    subpath = request.matchdict.get('subpath')\n    if not (subpath and subpath.rstrip('/').startswith('collections/')):\n        return\n\n    collection_id = subpath.split('/')[1]\n    collection_uri = instance_uri(request, 'collection',\n                                  bucket_id=bucket_id,\n                                  id=collection_id)\n\n    # Do not intent to create multiple times per request (e.g. in batch).\n    already_created = request.bound_data.setdefault('collections', {})\n    if collection_uri in already_created:\n        return\n\n    # Do nothing if current request will already create the collection.\n    collection_put = (request.method.lower() == 'put' and\n                      request.path.endswith(collection_id))\n    if collection_put:\n        return\n\n    collection = resource_create_object(request=request,\n                                        resource_cls=Collection,\n                                        uri=collection_uri)\n    already_created[collection_uri] = collection\n\n\ndef resource_create_object(request, resource_cls, uri):\n    \"\"\"In the default bucket, the bucket and collection are implicitly\n    created. This helper instantiate the resource and simulate a request\n    with its RootFactory on the instantiated resource.\n    :returns: the created object\n    :rtype: dict\n    \"\"\"\n    resource_name, matchdict = view_lookup(request, uri)\n\n    # Build a fake request, mainly used to populate the create events that\n    # will be triggered by the resource.\n    fakerequest = build_request(request, {\n        'method': 'PUT',\n        'path': uri,\n    })\n    fakerequest.matchdict = matchdict\n    fakerequest.bound_data = request.bound_data\n    fakerequest.authn_type = request.authn_type\n    fakerequest.selected_userid = request.selected_userid\n    fakerequest.errors = request.errors\n    fakerequest.current_resource_name = resource_name\n\n    obj_id = matchdict['id']\n\n    # Fake context, required to instantiate a resource.\n    context = RouteFactory(fakerequest)\n    context.resource_name = resource_name\n    resource = resource_cls(fakerequest, context)\n\n    # Check that provided id is valid for this resource.\n    if not resource.model.id_generator.match(obj_id):\n        error_details = {\n            'location': 'path',\n            'description': \"Invalid {} id\".format(resource_name)\n        }\n        raise_invalid(resource.request, **error_details)\n\n    data = {'id': obj_id}\n    obj = resource.model.create_record(data, ignore_conflict=True)\n    # Since the current request is not a resource (but a straight Service),\n    # we simulate a request on a resource.\n    # This will be used in the resource event payload.\n    resource.postprocess(obj, action=ACTIONS.CREATE)\n    return obj\n\n\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 Authenticated not in request.effective_principals:\n        # Pass through the forbidden_view_config\n        raise httpexceptions.HTTPForbidden()\n\n    settings = request.registry.settings\n\n    if asbool(settings['readonly']):\n        raise httpexceptions.HTTPMethodNotAllowed()\n\n    bucket_id = request.default_bucket_id\n\n    # Implicit object creations.\n    # Make sure bucket exists\n    create_bucket(request, bucket_id)\n    # Make sure the collection exists\n    create_collection(request, bucket_id)\n\n    path = request.path.replace('/buckets/default', '/buckets/{}'.format(bucket_id))\n    querystring = request.url[(request.url.index(request.path) +\n                               len(request.path)):]\n    try:\n        # If 'id' is provided as 'default', replace with actual bucket id.\n        body = request.json\n        body['data']['id'] = body['data']['id'].replace('default', bucket_id)\n    except:\n        body = request.body or {\"data\": {}}\n    subrequest = build_request(request, {\n        'method': request.method,\n        'path': path + querystring,\n        'body': body,\n    })\n    subrequest.bound_data = request.bound_data\n\n    try:\n        response = request.invoke_subrequest(subrequest)\n    except httpexceptions.HTTPException as error:\n        is_redirect = error.status_code < 400\n        if error.content_type == 'application/json' or is_redirect:\n            response = reapply_cors(subrequest, error)\n        else:\n            # Ask the upper level to format the error.\n            raise error\n    return response\n\n\ndef default_bucket_id(request):\n    settings = request.registry.settings\n    secret = settings['userid_hmac_secret']\n    # Build the user unguessable bucket_id UUID from its user_id\n    digest = hmac_digest(secret, request.prefixed_userid)\n    return str(uuid.UUID(digest[:32]))\n\n\ndef get_user_info(request):\n    user_info = {\n        'id': request.prefixed_userid,\n        'bucket': request.default_bucket_id\n    }\n    return user_info\n\n\ndef includeme(config):\n    # Redirect default to the right endpoint\n    config.add_view(default_bucket,\n                    route_name='default_bucket',\n                    permission=NO_PERMISSION_REQUIRED)\n    config.add_view(default_bucket,\n                    route_name='default_bucket_collection',\n                    permission=NO_PERMISSION_REQUIRED)\n\n    config.add_route('default_bucket_collection',\n                     '/buckets/default/{subpath:.*}')\n    config.add_route('default_bucket', '/buckets/default')\n\n    # Provide helpers\n    config.add_request_method(default_bucket_id, reify=True)\n    # Override kinto.core default user info\n    config.add_request_method(get_user_info)\n\n    config.add_api_capability(\n        \"default_bucket\",\n        description=\"The default bucket is an alias for a personal\"\n                    \" bucket where collections are created implicitly.\",\n        url=\"https://kinto.readthedocs.io/en/latest/api/1.x/\"\n            \"buckets.html#personal-bucket-default\")\n", "path": "kinto/plugins/default_bucket/__init__.py"}], "after_files": [{"content": "import uuid\n\nfrom pyramid import httpexceptions\nfrom pyramid.settings import asbool\nfrom pyramid.security import NO_PERMISSION_REQUIRED, Authenticated\n\nfrom kinto.core.errors import raise_invalid\nfrom kinto.core.events import ACTIONS\nfrom kinto.core.storage.exceptions import UnicityError\nfrom kinto.core.utils import (\n    build_request, reapply_cors, hmac_digest, instance_uri, view_lookup)\n\nfrom kinto.authorization import RouteFactory\nfrom kinto.views.buckets import Bucket\nfrom kinto.views.collections import Collection\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    # Do nothing if current request will already create the bucket.\n    if bucket_put:\n        return\n\n    # Do not intent to create multiple times per request (e.g. in batch).\n    already_created = request.bound_data.setdefault('buckets', {})\n    if bucket_id in already_created:\n        return\n\n    bucket_uri = instance_uri(request, 'bucket', id=bucket_id)\n    bucket = resource_create_object(request=request,\n                                    resource_cls=Bucket,\n                                    uri=bucket_uri)\n    already_created[bucket_id] = bucket\n\n\ndef create_collection(request, bucket_id):\n    # Do nothing if current request does not involve a collection.\n    subpath = request.matchdict.get('subpath')\n    if not (subpath and subpath.rstrip('/').startswith('collections/')):\n        return\n\n    collection_id = subpath.split('/')[1]\n    collection_uri = instance_uri(request, 'collection',\n                                  bucket_id=bucket_id,\n                                  id=collection_id)\n\n    # Do not intent to create multiple times per request (e.g. in batch).\n    already_created = request.bound_data.setdefault('collections', {})\n    if collection_uri in already_created:\n        return\n\n    # Do nothing if current request will already create the collection.\n    collection_put = (request.method.lower() == 'put' and\n                      request.path.endswith(collection_id))\n    if collection_put:\n        return\n\n    collection = resource_create_object(request=request,\n                                        resource_cls=Collection,\n                                        uri=collection_uri)\n    already_created[collection_uri] = collection\n\n\ndef resource_create_object(request, resource_cls, uri):\n    \"\"\"In the default bucket, the bucket and collection are implicitly\n    created. This helper instantiate the resource and simulate a request\n    with its RootFactory on the instantiated resource.\n    :returns: the created object\n    :rtype: dict\n    \"\"\"\n    resource_name, matchdict = view_lookup(request, uri)\n\n    # Build a fake request, mainly used to populate the create events that\n    # will be triggered by the resource.\n    fakerequest = build_request(request, {\n        'method': 'PUT',\n        'path': uri,\n    })\n    fakerequest.matchdict = matchdict\n    fakerequest.bound_data = request.bound_data\n    fakerequest.authn_type = request.authn_type\n    fakerequest.selected_userid = request.selected_userid\n    fakerequest.errors = request.errors\n    fakerequest.current_resource_name = resource_name\n\n    obj_id = matchdict['id']\n\n    # Fake context, required to instantiate a resource.\n    context = RouteFactory(fakerequest)\n    context.resource_name = resource_name\n    resource = resource_cls(fakerequest, context)\n\n    # Check that provided id is valid for this resource.\n    if not resource.model.id_generator.match(obj_id):\n        error_details = {\n            'location': 'path',\n            'description': \"Invalid {} id\".format(resource_name)\n        }\n        raise_invalid(resource.request, **error_details)\n\n    data = {'id': obj_id}\n    try:\n        obj = resource.model.create_record(data)\n    except UnicityError as e:\n        # The record already exists; skip running events\n        return e.record\n\n    # Since the current request is not a resource (but a straight Service),\n    # we simulate a request on a resource.\n    # This will be used in the resource event payload.\n    resource.postprocess(obj, action=ACTIONS.CREATE)\n    return obj\n\n\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 Authenticated not in request.effective_principals:\n        # Pass through the forbidden_view_config\n        raise httpexceptions.HTTPForbidden()\n\n    settings = request.registry.settings\n\n    if asbool(settings['readonly']):\n        raise httpexceptions.HTTPMethodNotAllowed()\n\n    bucket_id = request.default_bucket_id\n\n    # Implicit object creations.\n    # Make sure bucket exists\n    create_bucket(request, bucket_id)\n    # Make sure the collection exists\n    create_collection(request, bucket_id)\n\n    path = request.path.replace('/buckets/default', '/buckets/{}'.format(bucket_id))\n    querystring = request.url[(request.url.index(request.path) +\n                               len(request.path)):]\n    try:\n        # If 'id' is provided as 'default', replace with actual bucket id.\n        body = request.json\n        body['data']['id'] = body['data']['id'].replace('default', bucket_id)\n    except:\n        body = request.body or {\"data\": {}}\n    subrequest = build_request(request, {\n        'method': request.method,\n        'path': path + querystring,\n        'body': body,\n    })\n    subrequest.bound_data = request.bound_data\n\n    try:\n        response = request.invoke_subrequest(subrequest)\n    except httpexceptions.HTTPException as error:\n        is_redirect = error.status_code < 400\n        if error.content_type == 'application/json' or is_redirect:\n            response = reapply_cors(subrequest, error)\n        else:\n            # Ask the upper level to format the error.\n            raise error\n    return response\n\n\ndef default_bucket_id(request):\n    settings = request.registry.settings\n    secret = settings['userid_hmac_secret']\n    # Build the user unguessable bucket_id UUID from its user_id\n    digest = hmac_digest(secret, request.prefixed_userid)\n    return str(uuid.UUID(digest[:32]))\n\n\ndef get_user_info(request):\n    user_info = {\n        'id': request.prefixed_userid,\n        'bucket': request.default_bucket_id\n    }\n    return user_info\n\n\ndef includeme(config):\n    # Redirect default to the right endpoint\n    config.add_view(default_bucket,\n                    route_name='default_bucket',\n                    permission=NO_PERMISSION_REQUIRED)\n    config.add_view(default_bucket,\n                    route_name='default_bucket_collection',\n                    permission=NO_PERMISSION_REQUIRED)\n\n    config.add_route('default_bucket_collection',\n                     '/buckets/default/{subpath:.*}')\n    config.add_route('default_bucket', '/buckets/default')\n\n    # Provide helpers\n    config.add_request_method(default_bucket_id, reify=True)\n    # Override kinto.core default user info\n    config.add_request_method(get_user_info)\n\n    config.add_api_capability(\n        \"default_bucket\",\n        description=\"The default bucket is an alias for a personal\"\n                    \" bucket where collections are created implicitly.\",\n        url=\"https://kinto.readthedocs.io/en/latest/api/1.x/\"\n            \"buckets.html#personal-bucket-default\")\n", "path": "kinto/plugins/default_bucket/__init__.py"}]}