We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
switch to unquote_plus in bucketlistresultset
Resubmitting #2654, rebased off current develop branch. Original description follows:

There is a bug in PR #2562, which I submitted. The URL quoting that S3 performs with `encoding_type="url"` necessitates the use of `unquote_plus` because they replace spaces with plus signs. This didn't break bucket listing completely, and in my case it only led to some keys missing from the listing, something that I didn't notice in my original testing. Sorry for this!


--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `boto/s3/bucketlistresultset.py`
Content:
```
1 # Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/
2 #
3 # Permission is hereby granted, free of charge, to any person obtaining a
4 # copy of this software and associated documentation files (the
5 # "Software"), to deal in the Software without restriction, including
6 # without limitation the rights to use, copy, modify, merge, publish, dis-
7 # tribute, sublicense, and/or sell copies of the Software, and to permit
8 # persons to whom the Software is furnished to do so, subject to the fol-
9 # lowing conditions:
10 #
11 # The above copyright notice and this permission notice shall be included
12 # in all copies or substantial portions of the Software.
13 #
14 # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15 # OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
16 # ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
17 # SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
18 # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
20 # IN THE SOFTWARE.
21 
22 from boto.compat import unquote_str
23 
24 def bucket_lister(bucket, prefix='', delimiter='', marker='', headers=None,
25                   encoding_type=None):
26     """
27     A generator function for listing keys in a bucket.
28     """
29     more_results = True
30     k = None
31     while more_results:
32         rs = bucket.get_all_keys(prefix=prefix, marker=marker,
33                                  delimiter=delimiter, headers=headers,
34                                  encoding_type=encoding_type)
35         for k in rs:
36             yield k
37         if k:
38             marker = rs.next_marker or k.name
39         if marker and encoding_type == "url":
40             marker = unquote_str(marker)
41         more_results= rs.is_truncated
42 
43 class BucketListResultSet(object):
44     """
45     A resultset for listing keys within a bucket.  Uses the bucket_lister
46     generator function and implements the iterator interface.  This
47     transparently handles the results paging from S3 so even if you have
48     many thousands of keys within the bucket you can iterate over all
49     keys in a reasonably efficient manner.
50     """
51 
52     def __init__(self, bucket=None, prefix='', delimiter='', marker='',
53                  headers=None, encoding_type=None):
54         self.bucket = bucket
55         self.prefix = prefix
56         self.delimiter = delimiter
57         self.marker = marker
58         self.headers = headers
59         self.encoding_type = encoding_type
60 
61     def __iter__(self):
62         return bucket_lister(self.bucket, prefix=self.prefix,
63                              delimiter=self.delimiter, marker=self.marker,
64                              headers=self.headers,
65                              encoding_type=self.encoding_type)
66 
67 def versioned_bucket_lister(bucket, prefix='', delimiter='',
68                             key_marker='', version_id_marker='', headers=None,
69                             encoding_type=None):
70     """
71     A generator function for listing versions in a bucket.
72     """
73     more_results = True
74     k = None
75     while more_results:
76         rs = bucket.get_all_versions(prefix=prefix, key_marker=key_marker,
77                                      version_id_marker=version_id_marker,
78                                      delimiter=delimiter, headers=headers,
79                                      max_keys=999, encoding_type=encoding_type)
80         for k in rs:
81             yield k
82         key_marker = rs.next_key_marker
83         version_id_marker = rs.next_version_id_marker
84         more_results= rs.is_truncated
85 
86 class VersionedBucketListResultSet(object):
87     """
88     A resultset for listing versions within a bucket.  Uses the bucket_lister
89     generator function and implements the iterator interface.  This
90     transparently handles the results paging from S3 so even if you have
91     many thousands of keys within the bucket you can iterate over all
92     keys in a reasonably efficient manner.
93     """
94 
95     def __init__(self, bucket=None, prefix='', delimiter='', key_marker='',
96                  version_id_marker='', headers=None, encoding_type=None):
97         self.bucket = bucket
98         self.prefix = prefix
99         self.delimiter = delimiter
100         self.key_marker = key_marker
101         self.version_id_marker = version_id_marker
102         self.headers = headers
103         self.encoding_type = encoding_type
104 
105     def __iter__(self):
106         return versioned_bucket_lister(self.bucket, prefix=self.prefix,
107                                        delimiter=self.delimiter,
108                                        key_marker=self.key_marker,
109                                        version_id_marker=self.version_id_marker,
110                                        headers=self.headers,
111                                        encoding_type=self.encoding_type)
112 
113 def multipart_upload_lister(bucket, key_marker='',
114                             upload_id_marker='',
115                             headers=None, encoding_type=None):
116     """
117     A generator function for listing multipart uploads in a bucket.
118     """
119     more_results = True
120     k = None
121     while more_results:
122         rs = bucket.get_all_multipart_uploads(key_marker=key_marker,
123                                               upload_id_marker=upload_id_marker,
124                                               headers=headers,
125                                               encoding_type=encoding_type)
126         for k in rs:
127             yield k
128         key_marker = rs.next_key_marker
129         upload_id_marker = rs.next_upload_id_marker
130         more_results= rs.is_truncated
131 
132 class MultiPartUploadListResultSet(object):
133     """
134     A resultset for listing multipart uploads within a bucket.
135     Uses the multipart_upload_lister generator function and
136     implements the iterator interface.  This
137     transparently handles the results paging from S3 so even if you have
138     many thousands of uploads within the bucket you can iterate over all
139     keys in a reasonably efficient manner.
140     """
141     def __init__(self, bucket=None, key_marker='',
142                  upload_id_marker='', headers=None, encoding_type=None):
143         self.bucket = bucket
144         self.key_marker = key_marker
145         self.upload_id_marker = upload_id_marker
146         self.headers = headers
147         self.encoding_type = encoding_type
148 
149     def __iter__(self):
150         return multipart_upload_lister(self.bucket,
151                                        key_marker=self.key_marker,
152                                        upload_id_marker=self.upload_id_marker,
153                                        headers=self.headers,
154                                        encoding_type=self.encoding_type)
155
```
--- 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/boto/s3/bucketlistresultset.py b/boto/s3/bucketlistresultset.py
--- a/boto/s3/bucketlistresultset.py
+++ b/boto/s3/bucketlistresultset.py
@@ -80,6 +80,8 @@
         for k in rs:
             yield k
         key_marker = rs.next_key_marker
+        if key_marker and encoding_type == "url":
+            key_marker = unquote_str(key_marker)
         version_id_marker = rs.next_version_id_marker
         more_results= rs.is_truncated
 
@@ -126,6 +128,8 @@
         for k in rs:
             yield k
         key_marker = rs.next_key_marker
+        if key_marker and encoding_type == "url":
+            key_marker = unquote_str(key_marker)
         upload_id_marker = rs.next_upload_id_marker
         more_results= rs.is_truncated

{"golden_diff": "diff --git a/boto/s3/bucketlistresultset.py b/boto/s3/bucketlistresultset.py\n--- a/boto/s3/bucketlistresultset.py\n+++ b/boto/s3/bucketlistresultset.py\n@@ -80,6 +80,8 @@\n         for k in rs:\n             yield k\n         key_marker = rs.next_key_marker\n+        if key_marker and encoding_type == \"url\":\n+            key_marker = unquote_str(key_marker)\n         version_id_marker = rs.next_version_id_marker\n         more_results= rs.is_truncated\n \n@@ -126,6 +128,8 @@\n         for k in rs:\n             yield k\n         key_marker = rs.next_key_marker\n+        if key_marker and encoding_type == \"url\":\n+            key_marker = unquote_str(key_marker)\n         upload_id_marker = rs.next_upload_id_marker\n         more_results= rs.is_truncated\n", "issue": "switch to unquote_plus in bucketlistresultset\nResubmitting #2654, rebased off current develop branch. Original description follows:\n\nThere is a bug in PR #2562, which I submitted. The URL quoting that S3 performs with `encoding_type=\"url\"` necessitates the use of `unquote_plus` because they replace spaces with plus signs. This didn't break bucket listing completely, and in my case it only led to some keys missing from the listing, something that I didn't notice in my original testing. Sorry for this!\n\n", "before_files": [{"content": "# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish, dis-\n# tribute, sublicense, and/or sell copies of the Software, and to permit\n# persons to whom the Software is furnished to do so, subject to the fol-\n# lowing conditions:\n#\n# The above copyright notice and this permission notice shall be included\n# in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-\n# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\n# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n# IN THE SOFTWARE.\n\nfrom boto.compat import unquote_str\n\ndef bucket_lister(bucket, prefix='', delimiter='', marker='', headers=None,\n                  encoding_type=None):\n    \"\"\"\n    A generator function for listing keys in a bucket.\n    \"\"\"\n    more_results = True\n    k = None\n    while more_results:\n        rs = bucket.get_all_keys(prefix=prefix, marker=marker,\n                                 delimiter=delimiter, headers=headers,\n                                 encoding_type=encoding_type)\n        for k in rs:\n            yield k\n        if k:\n            marker = rs.next_marker or k.name\n        if marker and encoding_type == \"url\":\n            marker = unquote_str(marker)\n        more_results= rs.is_truncated\n\nclass BucketListResultSet(object):\n    \"\"\"\n    A resultset for listing keys within a bucket.  Uses the bucket_lister\n    generator function and implements the iterator interface.  This\n    transparently handles the results paging from S3 so even if you have\n    many thousands of keys within the bucket you can iterate over all\n    keys in a reasonably efficient manner.\n    \"\"\"\n\n    def __init__(self, bucket=None, prefix='', delimiter='', marker='',\n                 headers=None, encoding_type=None):\n        self.bucket = bucket\n        self.prefix = prefix\n        self.delimiter = delimiter\n        self.marker = marker\n        self.headers = headers\n        self.encoding_type = encoding_type\n\n    def __iter__(self):\n        return bucket_lister(self.bucket, prefix=self.prefix,\n                             delimiter=self.delimiter, marker=self.marker,\n                             headers=self.headers,\n                             encoding_type=self.encoding_type)\n\ndef versioned_bucket_lister(bucket, prefix='', delimiter='',\n                            key_marker='', version_id_marker='', headers=None,\n                            encoding_type=None):\n    \"\"\"\n    A generator function for listing versions in a bucket.\n    \"\"\"\n    more_results = True\n    k = None\n    while more_results:\n        rs = bucket.get_all_versions(prefix=prefix, key_marker=key_marker,\n                                     version_id_marker=version_id_marker,\n                                     delimiter=delimiter, headers=headers,\n                                     max_keys=999, encoding_type=encoding_type)\n        for k in rs:\n            yield k\n        key_marker = rs.next_key_marker\n        version_id_marker = rs.next_version_id_marker\n        more_results= rs.is_truncated\n\nclass VersionedBucketListResultSet(object):\n    \"\"\"\n    A resultset for listing versions within a bucket.  Uses the bucket_lister\n    generator function and implements the iterator interface.  This\n    transparently handles the results paging from S3 so even if you have\n    many thousands of keys within the bucket you can iterate over all\n    keys in a reasonably efficient manner.\n    \"\"\"\n\n    def __init__(self, bucket=None, prefix='', delimiter='', key_marker='',\n                 version_id_marker='', headers=None, encoding_type=None):\n        self.bucket = bucket\n        self.prefix = prefix\n        self.delimiter = delimiter\n        self.key_marker = key_marker\n        self.version_id_marker = version_id_marker\n        self.headers = headers\n        self.encoding_type = encoding_type\n\n    def __iter__(self):\n        return versioned_bucket_lister(self.bucket, prefix=self.prefix,\n                                       delimiter=self.delimiter,\n                                       key_marker=self.key_marker,\n                                       version_id_marker=self.version_id_marker,\n                                       headers=self.headers,\n                                       encoding_type=self.encoding_type)\n\ndef multipart_upload_lister(bucket, key_marker='',\n                            upload_id_marker='',\n                            headers=None, encoding_type=None):\n    \"\"\"\n    A generator function for listing multipart uploads in a bucket.\n    \"\"\"\n    more_results = True\n    k = None\n    while more_results:\n        rs = bucket.get_all_multipart_uploads(key_marker=key_marker,\n                                              upload_id_marker=upload_id_marker,\n                                              headers=headers,\n                                              encoding_type=encoding_type)\n        for k in rs:\n            yield k\n        key_marker = rs.next_key_marker\n        upload_id_marker = rs.next_upload_id_marker\n        more_results= rs.is_truncated\n\nclass MultiPartUploadListResultSet(object):\n    \"\"\"\n    A resultset for listing multipart uploads within a bucket.\n    Uses the multipart_upload_lister generator function and\n    implements the iterator interface.  This\n    transparently handles the results paging from S3 so even if you have\n    many thousands of uploads within the bucket you can iterate over all\n    keys in a reasonably efficient manner.\n    \"\"\"\n    def __init__(self, bucket=None, key_marker='',\n                 upload_id_marker='', headers=None, encoding_type=None):\n        self.bucket = bucket\n        self.key_marker = key_marker\n        self.upload_id_marker = upload_id_marker\n        self.headers = headers\n        self.encoding_type = encoding_type\n\n    def __iter__(self):\n        return multipart_upload_lister(self.bucket,\n                                       key_marker=self.key_marker,\n                                       upload_id_marker=self.upload_id_marker,\n                                       headers=self.headers,\n                                       encoding_type=self.encoding_type)\n", "path": "boto/s3/bucketlistresultset.py"}], "after_files": [{"content": "# Copyright (c) 2006,2007 Mitch Garnaat http://garnaat.org/\n#\n# Permission is hereby granted, free of charge, to any person obtaining a\n# copy of this software and associated documentation files (the\n# \"Software\"), to deal in the Software without restriction, including\n# without limitation the rights to use, copy, modify, merge, publish, dis-\n# tribute, sublicense, and/or sell copies of the Software, and to permit\n# persons to whom the Software is furnished to do so, subject to the fol-\n# lowing conditions:\n#\n# The above copyright notice and this permission notice shall be included\n# in all copies or substantial portions of the Software.\n#\n# THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-\n# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT\n# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,\n# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\n# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS\n# IN THE SOFTWARE.\n\nfrom boto.compat import unquote_str\n\ndef bucket_lister(bucket, prefix='', delimiter='', marker='', headers=None,\n                  encoding_type=None):\n    \"\"\"\n    A generator function for listing keys in a bucket.\n    \"\"\"\n    more_results = True\n    k = None\n    while more_results:\n        rs = bucket.get_all_keys(prefix=prefix, marker=marker,\n                                 delimiter=delimiter, headers=headers,\n                                 encoding_type=encoding_type)\n        for k in rs:\n            yield k\n        if k:\n            marker = rs.next_marker or k.name\n        if marker and encoding_type == \"url\":\n            marker = unquote_str(marker)\n        more_results= rs.is_truncated\n\nclass BucketListResultSet(object):\n    \"\"\"\n    A resultset for listing keys within a bucket.  Uses the bucket_lister\n    generator function and implements the iterator interface.  This\n    transparently handles the results paging from S3 so even if you have\n    many thousands of keys within the bucket you can iterate over all\n    keys in a reasonably efficient manner.\n    \"\"\"\n\n    def __init__(self, bucket=None, prefix='', delimiter='', marker='',\n                 headers=None, encoding_type=None):\n        self.bucket = bucket\n        self.prefix = prefix\n        self.delimiter = delimiter\n        self.marker = marker\n        self.headers = headers\n        self.encoding_type = encoding_type\n\n    def __iter__(self):\n        return bucket_lister(self.bucket, prefix=self.prefix,\n                             delimiter=self.delimiter, marker=self.marker,\n                             headers=self.headers,\n                             encoding_type=self.encoding_type)\n\ndef versioned_bucket_lister(bucket, prefix='', delimiter='',\n                            key_marker='', version_id_marker='', headers=None,\n                            encoding_type=None):\n    \"\"\"\n    A generator function for listing versions in a bucket.\n    \"\"\"\n    more_results = True\n    k = None\n    while more_results:\n        rs = bucket.get_all_versions(prefix=prefix, key_marker=key_marker,\n                                     version_id_marker=version_id_marker,\n                                     delimiter=delimiter, headers=headers,\n                                     max_keys=999, encoding_type=encoding_type)\n        for k in rs:\n            yield k\n        key_marker = rs.next_key_marker\n        if key_marker and encoding_type == \"url\":\n            key_marker = unquote_str(key_marker)\n        version_id_marker = rs.next_version_id_marker\n        more_results= rs.is_truncated\n\nclass VersionedBucketListResultSet(object):\n    \"\"\"\n    A resultset for listing versions within a bucket.  Uses the bucket_lister\n    generator function and implements the iterator interface.  This\n    transparently handles the results paging from S3 so even if you have\n    many thousands of keys within the bucket you can iterate over all\n    keys in a reasonably efficient manner.\n    \"\"\"\n\n    def __init__(self, bucket=None, prefix='', delimiter='', key_marker='',\n                 version_id_marker='', headers=None, encoding_type=None):\n        self.bucket = bucket\n        self.prefix = prefix\n        self.delimiter = delimiter\n        self.key_marker = key_marker\n        self.version_id_marker = version_id_marker\n        self.headers = headers\n        self.encoding_type = encoding_type\n\n    def __iter__(self):\n        return versioned_bucket_lister(self.bucket, prefix=self.prefix,\n                                       delimiter=self.delimiter,\n                                       key_marker=self.key_marker,\n                                       version_id_marker=self.version_id_marker,\n                                       headers=self.headers,\n                                       encoding_type=self.encoding_type)\n\ndef multipart_upload_lister(bucket, key_marker='',\n                            upload_id_marker='',\n                            headers=None, encoding_type=None):\n    \"\"\"\n    A generator function for listing multipart uploads in a bucket.\n    \"\"\"\n    more_results = True\n    k = None\n    while more_results:\n        rs = bucket.get_all_multipart_uploads(key_marker=key_marker,\n                                              upload_id_marker=upload_id_marker,\n                                              headers=headers,\n                                              encoding_type=encoding_type)\n        for k in rs:\n            yield k\n        key_marker = rs.next_key_marker\n        if key_marker and encoding_type == \"url\":\n            key_marker = unquote_str(key_marker)\n        upload_id_marker = rs.next_upload_id_marker\n        more_results= rs.is_truncated\n\nclass MultiPartUploadListResultSet(object):\n    \"\"\"\n    A resultset for listing multipart uploads within a bucket.\n    Uses the multipart_upload_lister generator function and\n    implements the iterator interface.  This\n    transparently handles the results paging from S3 so even if you have\n    many thousands of uploads within the bucket you can iterate over all\n    keys in a reasonably efficient manner.\n    \"\"\"\n    def __init__(self, bucket=None, key_marker='',\n                 upload_id_marker='', headers=None, encoding_type=None):\n        self.bucket = bucket\n        self.key_marker = key_marker\n        self.upload_id_marker = upload_id_marker\n        self.headers = headers\n        self.encoding_type = encoding_type\n\n    def __iter__(self):\n        return multipart_upload_lister(self.bucket,\n                                       key_marker=self.key_marker,\n                                       upload_id_marker=self.upload_id_marker,\n                                       headers=self.headers,\n                                       encoding_type=self.encoding_type)\n", "path": "boto/s3/bucketlistresultset.py"}]}