We are currently solving the following issue within our repository. Here is the issue text:
--- BEGIN ISSUE ---
`aws sesv2 put-account-details --website-url https://example.com` shouldn't download the contents of example.com
Confirm by changing [ ] to [x] below to ensure that it's a bug:
- [x] I've gone though the [User Guide](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) and the [API reference](https://docs.aws.amazon.com/cli/latest/reference/)
- [x] I've searched for [previous similar issues](https://github.com/aws/aws-cli/issues) ~and didn't find any solution~ and found a similar problem from 2015.
  
**Describe the bug**

I'm trying to use the CLI to move my SES region out of the sandbox.

```sh
aws --debug sesv2 put-account-details --production-access-enabled --mail-type TRANSACTIONAL --website-url "https://example.com" --use-case-description "..." --contact-language EN
```

This produces a very odd message:
~~~~
An error occurred (BadRequestException) when calling the PutAccountDetails operation: 2 validation errors detected: Value at 'websiteURL' failed to satisfy constraint: Member must satisfy regular expression pattern: ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\?([^#]*))?(#(.*))?; Value at 'websiteURL' failed to satisfy constraint: Member must have length less than or equal to 1000
~~~~

Using `--debug` shows that it actually queryied my URL:
~~~~
2020-10-15 15:51:55,756 - MainThread - botocore.hooks - DEBUG - Changing event name from load-cli-arg.email.put-account-details.website-url to load-cli-arg.ses.put-account-details.website-url
2020-10-15 15:51:55,756 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ses.put-account-details.website-url: calling handler <awscli.paramfile.URIArgumentHandler object at 0x7f06e95e3940>
2020-10-15 15:51:55,757 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): example.com:443
2020-10-15 15:51:55,836 - MainThread - urllib3.connectionpool - DEBUG - https://example.com:443 "GET / HTTP/1.1" 200 1454225
[...]
~~~~

**SDK version number**
aws-cli/1.18.157 Python/3.8.6 Linux/5.8.11-200.fc32.x86_64 botocore/1.18.16

**Platform/OS/Hardware/Device**
Fedora 32, amd64

**Additional context**

This looks similar to https://github.com/aws/aws-cli/issues/1130, so I suspect the correct fix is to modify https://github.com/aws/aws-cli/blob/develop/awscli/paramfile.py accordingly for this parameter.

A work-around: I couldn't find a way to quote this in a way that would disable the downloading, BUT the regexp points to the solution: Remove the `https://` and use `--website-url example.com`. 




--- END ISSUE ---

Below are some code segments, each from a relevant file. One or more of these files may contain bugs.
--- BEGIN FILES ---
Path: `awscli/paramfile.py`
Content:
```
1 # Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2 #
3 # Licensed under the Apache License, Version 2.0 (the "License"). You
4 # may not use this file except in compliance with the License. A copy of
5 # the License is located at
6 #
7 #     http://aws.amazon.com/apache2.0/
8 #
9 # or in the "license" file accompanying this file. This file is
10 # distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF
11 # ANY KIND, either express or implied. See the License for the specific
12 # language governing permissions and limitations under the License.
13 import logging
14 import os
15 import copy
16 
17 from botocore.awsrequest import AWSRequest
18 from botocore.httpsession import URLLib3Session
19 from botocore.exceptions import ProfileNotFound
20 from awscli.compat import six
21 
22 from awscli.compat import compat_open
23 from awscli.argprocess import ParamError
24 
25 
26 logger = logging.getLogger(__name__)
27 
28 # These are special cased arguments that do _not_ get the
29 # special param file processing.  This is typically because it
30 # refers to an actual URI of some sort and we don't want to actually
31 # download the content (i.e TemplateURL in cloudformation).
32 PARAMFILE_DISABLED = set([
33     'api-gateway.put-integration.uri',
34     'api-gateway.create-integration.integration-uri',
35     'api-gateway.update-integration.integration-uri',
36     'api-gateway.create-api.target',
37     'api-gateway.update-api.target',
38     'appstream.create-stack.redirect-url',
39     'appstream.create-stack.feedback-url',
40     'appstream.update-stack.redirect-url',
41     'appstream.update-stack.feedback-url',
42     'cloudformation.create-stack.template-url',
43     'cloudformation.update-stack.template-url',
44     'cloudformation.create-stack-set.template-url',
45     'cloudformation.update-stack-set.template-url',
46     'cloudformation.create-change-set.template-url',
47     'cloudformation.validate-template.template-url',
48     'cloudformation.estimate-template-cost.template-url',
49     'cloudformation.get-template-summary.template-url',
50 
51     'cloudformation.create-stack.stack-policy-url',
52     'cloudformation.update-stack.stack-policy-url',
53     'cloudformation.set-stack-policy.stack-policy-url',
54     # aws cloudformation package --template-file
55     'custom.package.template-file',
56     # aws cloudformation deploy --template-file
57     'custom.deploy.template-file',
58 
59     'cloudformation.update-stack.stack-policy-during-update-url',
60     # We will want to change the event name to ``s3`` as opposed to
61     # custom in the near future along with ``s3`` to ``s3api``.
62     'custom.cp.website-redirect',
63     'custom.mv.website-redirect',
64     'custom.sync.website-redirect',
65 
66     'guardduty.create-ip-set.location',
67     'guardduty.update-ip-set.location',
68     'guardduty.create-threat-intel-set.location',
69     'guardduty.update-threat-intel-set.location',
70     'comprehend.detect-dominant-language.text',
71     'comprehend.batch-detect-dominant-language.text-list',
72     'comprehend.detect-entities.text',
73     'comprehend.batch-detect-entities.text-list',
74     'comprehend.detect-key-phrases.text',
75     'comprehend.batch-detect-key-phrases.text-list',
76     'comprehend.detect-sentiment.text',
77     'comprehend.batch-detect-sentiment.text-list',
78 
79     'iam.create-open-id-connect-provider.url',
80 
81     'machine-learning.predict.predict-endpoint',
82 
83     'mediatailor.put-playback-configuration.ad-decision-server-url',
84     'mediatailor.put-playback-configuration.slate-ad-url',
85     'mediatailor.put-playback-configuration.video-content-source-url',
86 
87     'rds.copy-db-cluster-snapshot.pre-signed-url',
88     'rds.create-db-cluster.pre-signed-url',
89     'rds.copy-db-snapshot.pre-signed-url',
90     'rds.create-db-instance-read-replica.pre-signed-url',
91 
92     'sagemaker.create-notebook-instance.default-code-repository',
93     'sagemaker.create-notebook-instance.additional-code-repositories',
94     'sagemaker.update-notebook-instance.default-code-repository',
95     'sagemaker.update-notebook-instance.additional-code-repositories',
96 
97     'serverlessapplicationrepository.create-application.home-page-url',
98     'serverlessapplicationrepository.create-application.license-url',
99     'serverlessapplicationrepository.create-application.readme-url',
100     'serverlessapplicationrepository.create-application.source-code-url',
101     'serverlessapplicationrepository.create-application.template-url',
102     'serverlessapplicationrepository.create-application-version.source-code-url',
103     'serverlessapplicationrepository.create-application-version.template-url',
104     'serverlessapplicationrepository.update-application.home-page-url',
105     'serverlessapplicationrepository.update-application.readme-url',
106 
107     'service-catalog.create-product.support-url',
108     'service-catalog.update-product.support-url',
109 
110     'sqs.add-permission.queue-url',
111     'sqs.change-message-visibility.queue-url',
112     'sqs.change-message-visibility-batch.queue-url',
113     'sqs.delete-message.queue-url',
114     'sqs.delete-message-batch.queue-url',
115     'sqs.delete-queue.queue-url',
116     'sqs.get-queue-attributes.queue-url',
117     'sqs.list-dead-letter-source-queues.queue-url',
118     'sqs.receive-message.queue-url',
119     'sqs.remove-permission.queue-url',
120     'sqs.send-message.queue-url',
121     'sqs.send-message-batch.queue-url',
122     'sqs.set-queue-attributes.queue-url',
123     'sqs.purge-queue.queue-url',
124     'sqs.list-queue-tags.queue-url',
125     'sqs.tag-queue.queue-url',
126     'sqs.untag-queue.queue-url',
127 
128     's3.copy-object.website-redirect-location',
129     's3.create-multipart-upload.website-redirect-location',
130     's3.put-object.website-redirect-location',
131 
132     # Double check that this has been renamed!
133     'sns.subscribe.notification-endpoint',
134 
135     'iot.create-job.document-source',
136     'translate.translate-text.text',
137 
138     'workdocs.create-notification-subscription.notification-endpoint'
139 ])
140 
141 
142 class ResourceLoadingError(Exception):
143     pass
144 
145 
146 def register_uri_param_handler(session, **kwargs):
147     prefix_map = copy.deepcopy(LOCAL_PREFIX_MAP)
148     try:
149         fetch_url = session.get_scoped_config().get(
150             'cli_follow_urlparam', 'true') == 'true'
151     except ProfileNotFound:
152         # If a --profile is provided that does not exist, loading
153         # a value from get_scoped_config will crash the CLI.
154         # This function can be called as the first handler for
155         # the session-initialized event, which happens before a
156         # profile can be created, even if the command would have
157         # successfully created a profile. Instead of crashing here
158         # on a ProfileNotFound the CLI should just use 'none'.
159         fetch_url = True
160 
161     if fetch_url:
162         prefix_map.update(REMOTE_PREFIX_MAP)
163 
164     handler = URIArgumentHandler(prefix_map)
165     session.register('load-cli-arg', handler)
166 
167 
168 class URIArgumentHandler(object):
169     def __init__(self, prefixes=None):
170         if prefixes is None:
171             prefixes = copy.deepcopy(LOCAL_PREFIX_MAP)
172             prefixes.update(REMOTE_PREFIX_MAP)
173         self._prefixes = prefixes
174 
175     def __call__(self, event_name, param, value, **kwargs):
176         """Handler that supports param values from URIs."""
177         cli_argument = param
178         qualified_param_name = '.'.join(event_name.split('.')[1:])
179         if qualified_param_name in PARAMFILE_DISABLED or \
180                 getattr(cli_argument, 'no_paramfile', None):
181             return
182         else:
183             return self._check_for_uri_param(cli_argument, value)
184 
185     def _check_for_uri_param(self, param, value):
186         if isinstance(value, list) and len(value) == 1:
187             value = value[0]
188         try:
189             return get_paramfile(value, self._prefixes)
190         except ResourceLoadingError as e:
191             raise ParamError(param.cli_name, six.text_type(e))
192 
193 
194 def get_paramfile(path, cases):
195     """Load parameter based on a resource URI.
196 
197     It is possible to pass parameters to operations by referring
198     to files or URI's.  If such a reference is detected, this
199     function attempts to retrieve the data from the file or URI
200     and returns it.  If there are any errors or if the ``path``
201     does not appear to refer to a file or URI, a ``None`` is
202     returned.
203 
204     :type path: str
205     :param path: The resource URI, e.g. file://foo.txt.  This value
206         may also be a non resource URI, in which case ``None`` is returned.
207 
208     :type cases: dict
209     :param cases: A dictionary of URI prefixes to function mappings
210         that a parameter is checked against.
211 
212     :return: The loaded value associated with the resource URI.
213         If the provided ``path`` is not a resource URI, then a
214         value of ``None`` is returned.
215 
216     """
217     data = None
218     if isinstance(path, six.string_types):
219         for prefix, function_spec in cases.items():
220             if path.startswith(prefix):
221                 function, kwargs = function_spec
222                 data = function(prefix, path, **kwargs)
223     return data
224 
225 
226 def get_file(prefix, path, mode):
227     file_path = os.path.expandvars(os.path.expanduser(path[len(prefix):]))
228     try:
229         with compat_open(file_path, mode) as f:
230             return f.read()
231     except UnicodeDecodeError:
232         raise ResourceLoadingError(
233             'Unable to load paramfile (%s), text contents could '
234             'not be decoded.  If this is a binary file, please use the '
235             'fileb:// prefix instead of the file:// prefix.' % file_path)
236     except (OSError, IOError) as e:
237         raise ResourceLoadingError('Unable to load paramfile %s: %s' % (
238             path, e))
239 
240 
241 def get_uri(prefix, uri):
242     try:
243         session = URLLib3Session()
244         r = session.send(AWSRequest('GET', uri).prepare())
245         if r.status_code == 200:
246             return r.text
247         else:
248             raise ResourceLoadingError(
249                 "received non 200 status code of %s" % (
250                     r.status_code))
251     except Exception as e:
252         raise ResourceLoadingError('Unable to retrieve %s: %s' % (uri, e))
253 
254 
255 LOCAL_PREFIX_MAP = {
256     'file://': (get_file, {'mode': 'r'}),
257     'fileb://': (get_file, {'mode': 'rb'}),
258 }
259 
260 
261 REMOTE_PREFIX_MAP = {
262     'http://': (get_uri, {}),
263     'https://': (get_uri, {}),
264 }
265
```
--- 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/awscli/paramfile.py b/awscli/paramfile.py
--- a/awscli/paramfile.py
+++ b/awscli/paramfile.py
@@ -107,6 +107,8 @@
     'service-catalog.create-product.support-url',
     'service-catalog.update-product.support-url',
 
+    'ses.put-account-details.website-url',
+
     'sqs.add-permission.queue-url',
     'sqs.change-message-visibility.queue-url',
     'sqs.change-message-visibility-batch.queue-url',

{"golden_diff": "diff --git a/awscli/paramfile.py b/awscli/paramfile.py\n--- a/awscli/paramfile.py\n+++ b/awscli/paramfile.py\n@@ -107,6 +107,8 @@\n     'service-catalog.create-product.support-url',\n     'service-catalog.update-product.support-url',\n \n+    'ses.put-account-details.website-url',\n+\n     'sqs.add-permission.queue-url',\n     'sqs.change-message-visibility.queue-url',\n     'sqs.change-message-visibility-batch.queue-url',\n", "issue": "`aws sesv2 put-account-details --website-url https://example.com` shouldn't download the contents of example.com\nConfirm by changing [ ] to [x] below to ensure that it's a bug:\r\n- [x] I've gone though the [User Guide](https://docs.aws.amazon.com/cli/latest/userguide/cli-chap-welcome.html) and the [API reference](https://docs.aws.amazon.com/cli/latest/reference/)\r\n- [x] I've searched for [previous similar issues](https://github.com/aws/aws-cli/issues) ~and didn't find any solution~ and found a similar problem from 2015.\r\n  \r\n**Describe the bug**\r\n\r\nI'm trying to use the CLI to move my SES region out of the sandbox.\r\n\r\n```sh\r\naws --debug sesv2 put-account-details --production-access-enabled --mail-type TRANSACTIONAL --website-url \"https://example.com\" --use-case-description \"...\" --contact-language EN\r\n```\r\n\r\nThis produces a very odd message:\r\n~~~~\r\nAn error occurred (BadRequestException) when calling the PutAccountDetails operation: 2 validation errors detected: Value at 'websiteURL' failed to satisfy constraint: Member must satisfy regular expression pattern: ^(([^:/?#]+):)?(//([^/?#]*))?([^?#]*)(\\?([^#]*))?(#(.*))?; Value at 'websiteURL' failed to satisfy constraint: Member must have length less than or equal to 1000\r\n~~~~\r\n\r\nUsing `--debug` shows that it actually queryied my URL:\r\n~~~~\r\n2020-10-15 15:51:55,756 - MainThread - botocore.hooks - DEBUG - Changing event name from load-cli-arg.email.put-account-details.website-url to load-cli-arg.ses.put-account-details.website-url\r\n2020-10-15 15:51:55,756 - MainThread - botocore.hooks - DEBUG - Event load-cli-arg.ses.put-account-details.website-url: calling handler <awscli.paramfile.URIArgumentHandler object at 0x7f06e95e3940>\r\n2020-10-15 15:51:55,757 - MainThread - urllib3.connectionpool - DEBUG - Starting new HTTPS connection (1): example.com:443\r\n2020-10-15 15:51:55,836 - MainThread - urllib3.connectionpool - DEBUG - https://example.com:443 \"GET / HTTP/1.1\" 200 1454225\r\n[...]\r\n~~~~\r\n\r\n**SDK version number**\r\naws-cli/1.18.157 Python/3.8.6 Linux/5.8.11-200.fc32.x86_64 botocore/1.18.16\r\n\r\n**Platform/OS/Hardware/Device**\r\nFedora 32, amd64\r\n\r\n**Additional context**\r\n\r\nThis looks similar to https://github.com/aws/aws-cli/issues/1130, so I suspect the correct fix is to modify https://github.com/aws/aws-cli/blob/develop/awscli/paramfile.py accordingly for this parameter.\r\n\r\nA work-around: I couldn't find a way to quote this in a way that would disable the downloading, BUT the regexp points to the solution: Remove the `https://` and use `--website-url example.com`. \r\n\r\n\r\n\n", "before_files": [{"content": "# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nimport logging\nimport os\nimport copy\n\nfrom botocore.awsrequest import AWSRequest\nfrom botocore.httpsession import URLLib3Session\nfrom botocore.exceptions import ProfileNotFound\nfrom awscli.compat import six\n\nfrom awscli.compat import compat_open\nfrom awscli.argprocess import ParamError\n\n\nlogger = logging.getLogger(__name__)\n\n# These are special cased arguments that do _not_ get the\n# special param file processing.  This is typically because it\n# refers to an actual URI of some sort and we don't want to actually\n# download the content (i.e TemplateURL in cloudformation).\nPARAMFILE_DISABLED = set([\n    'api-gateway.put-integration.uri',\n    'api-gateway.create-integration.integration-uri',\n    'api-gateway.update-integration.integration-uri',\n    'api-gateway.create-api.target',\n    'api-gateway.update-api.target',\n    'appstream.create-stack.redirect-url',\n    'appstream.create-stack.feedback-url',\n    'appstream.update-stack.redirect-url',\n    'appstream.update-stack.feedback-url',\n    'cloudformation.create-stack.template-url',\n    'cloudformation.update-stack.template-url',\n    'cloudformation.create-stack-set.template-url',\n    'cloudformation.update-stack-set.template-url',\n    'cloudformation.create-change-set.template-url',\n    'cloudformation.validate-template.template-url',\n    'cloudformation.estimate-template-cost.template-url',\n    'cloudformation.get-template-summary.template-url',\n\n    'cloudformation.create-stack.stack-policy-url',\n    'cloudformation.update-stack.stack-policy-url',\n    'cloudformation.set-stack-policy.stack-policy-url',\n    # aws cloudformation package --template-file\n    'custom.package.template-file',\n    # aws cloudformation deploy --template-file\n    'custom.deploy.template-file',\n\n    'cloudformation.update-stack.stack-policy-during-update-url',\n    # We will want to change the event name to ``s3`` as opposed to\n    # custom in the near future along with ``s3`` to ``s3api``.\n    'custom.cp.website-redirect',\n    'custom.mv.website-redirect',\n    'custom.sync.website-redirect',\n\n    'guardduty.create-ip-set.location',\n    'guardduty.update-ip-set.location',\n    'guardduty.create-threat-intel-set.location',\n    'guardduty.update-threat-intel-set.location',\n    'comprehend.detect-dominant-language.text',\n    'comprehend.batch-detect-dominant-language.text-list',\n    'comprehend.detect-entities.text',\n    'comprehend.batch-detect-entities.text-list',\n    'comprehend.detect-key-phrases.text',\n    'comprehend.batch-detect-key-phrases.text-list',\n    'comprehend.detect-sentiment.text',\n    'comprehend.batch-detect-sentiment.text-list',\n\n    'iam.create-open-id-connect-provider.url',\n\n    'machine-learning.predict.predict-endpoint',\n\n    'mediatailor.put-playback-configuration.ad-decision-server-url',\n    'mediatailor.put-playback-configuration.slate-ad-url',\n    'mediatailor.put-playback-configuration.video-content-source-url',\n\n    'rds.copy-db-cluster-snapshot.pre-signed-url',\n    'rds.create-db-cluster.pre-signed-url',\n    'rds.copy-db-snapshot.pre-signed-url',\n    'rds.create-db-instance-read-replica.pre-signed-url',\n\n    'sagemaker.create-notebook-instance.default-code-repository',\n    'sagemaker.create-notebook-instance.additional-code-repositories',\n    'sagemaker.update-notebook-instance.default-code-repository',\n    'sagemaker.update-notebook-instance.additional-code-repositories',\n\n    'serverlessapplicationrepository.create-application.home-page-url',\n    'serverlessapplicationrepository.create-application.license-url',\n    'serverlessapplicationrepository.create-application.readme-url',\n    'serverlessapplicationrepository.create-application.source-code-url',\n    'serverlessapplicationrepository.create-application.template-url',\n    'serverlessapplicationrepository.create-application-version.source-code-url',\n    'serverlessapplicationrepository.create-application-version.template-url',\n    'serverlessapplicationrepository.update-application.home-page-url',\n    'serverlessapplicationrepository.update-application.readme-url',\n\n    'service-catalog.create-product.support-url',\n    'service-catalog.update-product.support-url',\n\n    'sqs.add-permission.queue-url',\n    'sqs.change-message-visibility.queue-url',\n    'sqs.change-message-visibility-batch.queue-url',\n    'sqs.delete-message.queue-url',\n    'sqs.delete-message-batch.queue-url',\n    'sqs.delete-queue.queue-url',\n    'sqs.get-queue-attributes.queue-url',\n    'sqs.list-dead-letter-source-queues.queue-url',\n    'sqs.receive-message.queue-url',\n    'sqs.remove-permission.queue-url',\n    'sqs.send-message.queue-url',\n    'sqs.send-message-batch.queue-url',\n    'sqs.set-queue-attributes.queue-url',\n    'sqs.purge-queue.queue-url',\n    'sqs.list-queue-tags.queue-url',\n    'sqs.tag-queue.queue-url',\n    'sqs.untag-queue.queue-url',\n\n    's3.copy-object.website-redirect-location',\n    's3.create-multipart-upload.website-redirect-location',\n    's3.put-object.website-redirect-location',\n\n    # Double check that this has been renamed!\n    'sns.subscribe.notification-endpoint',\n\n    'iot.create-job.document-source',\n    'translate.translate-text.text',\n\n    'workdocs.create-notification-subscription.notification-endpoint'\n])\n\n\nclass ResourceLoadingError(Exception):\n    pass\n\n\ndef register_uri_param_handler(session, **kwargs):\n    prefix_map = copy.deepcopy(LOCAL_PREFIX_MAP)\n    try:\n        fetch_url = session.get_scoped_config().get(\n            'cli_follow_urlparam', 'true') == 'true'\n    except ProfileNotFound:\n        # If a --profile is provided that does not exist, loading\n        # a value from get_scoped_config will crash the CLI.\n        # This function can be called as the first handler for\n        # the session-initialized event, which happens before a\n        # profile can be created, even if the command would have\n        # successfully created a profile. Instead of crashing here\n        # on a ProfileNotFound the CLI should just use 'none'.\n        fetch_url = True\n\n    if fetch_url:\n        prefix_map.update(REMOTE_PREFIX_MAP)\n\n    handler = URIArgumentHandler(prefix_map)\n    session.register('load-cli-arg', handler)\n\n\nclass URIArgumentHandler(object):\n    def __init__(self, prefixes=None):\n        if prefixes is None:\n            prefixes = copy.deepcopy(LOCAL_PREFIX_MAP)\n            prefixes.update(REMOTE_PREFIX_MAP)\n        self._prefixes = prefixes\n\n    def __call__(self, event_name, param, value, **kwargs):\n        \"\"\"Handler that supports param values from URIs.\"\"\"\n        cli_argument = param\n        qualified_param_name = '.'.join(event_name.split('.')[1:])\n        if qualified_param_name in PARAMFILE_DISABLED or \\\n                getattr(cli_argument, 'no_paramfile', None):\n            return\n        else:\n            return self._check_for_uri_param(cli_argument, value)\n\n    def _check_for_uri_param(self, param, value):\n        if isinstance(value, list) and len(value) == 1:\n            value = value[0]\n        try:\n            return get_paramfile(value, self._prefixes)\n        except ResourceLoadingError as e:\n            raise ParamError(param.cli_name, six.text_type(e))\n\n\ndef get_paramfile(path, cases):\n    \"\"\"Load parameter based on a resource URI.\n\n    It is possible to pass parameters to operations by referring\n    to files or URI's.  If such a reference is detected, this\n    function attempts to retrieve the data from the file or URI\n    and returns it.  If there are any errors or if the ``path``\n    does not appear to refer to a file or URI, a ``None`` is\n    returned.\n\n    :type path: str\n    :param path: The resource URI, e.g. file://foo.txt.  This value\n        may also be a non resource URI, in which case ``None`` is returned.\n\n    :type cases: dict\n    :param cases: A dictionary of URI prefixes to function mappings\n        that a parameter is checked against.\n\n    :return: The loaded value associated with the resource URI.\n        If the provided ``path`` is not a resource URI, then a\n        value of ``None`` is returned.\n\n    \"\"\"\n    data = None\n    if isinstance(path, six.string_types):\n        for prefix, function_spec in cases.items():\n            if path.startswith(prefix):\n                function, kwargs = function_spec\n                data = function(prefix, path, **kwargs)\n    return data\n\n\ndef get_file(prefix, path, mode):\n    file_path = os.path.expandvars(os.path.expanduser(path[len(prefix):]))\n    try:\n        with compat_open(file_path, mode) as f:\n            return f.read()\n    except UnicodeDecodeError:\n        raise ResourceLoadingError(\n            'Unable to load paramfile (%s), text contents could '\n            'not be decoded.  If this is a binary file, please use the '\n            'fileb:// prefix instead of the file:// prefix.' % file_path)\n    except (OSError, IOError) as e:\n        raise ResourceLoadingError('Unable to load paramfile %s: %s' % (\n            path, e))\n\n\ndef get_uri(prefix, uri):\n    try:\n        session = URLLib3Session()\n        r = session.send(AWSRequest('GET', uri).prepare())\n        if r.status_code == 200:\n            return r.text\n        else:\n            raise ResourceLoadingError(\n                \"received non 200 status code of %s\" % (\n                    r.status_code))\n    except Exception as e:\n        raise ResourceLoadingError('Unable to retrieve %s: %s' % (uri, e))\n\n\nLOCAL_PREFIX_MAP = {\n    'file://': (get_file, {'mode': 'r'}),\n    'fileb://': (get_file, {'mode': 'rb'}),\n}\n\n\nREMOTE_PREFIX_MAP = {\n    'http://': (get_uri, {}),\n    'https://': (get_uri, {}),\n}\n", "path": "awscli/paramfile.py"}], "after_files": [{"content": "# Copyright 2012-2013 Amazon.com, Inc. or its affiliates. All Rights Reserved.\n#\n# Licensed under the Apache License, Version 2.0 (the \"License\"). You\n# may not use this file except in compliance with the License. A copy of\n# the License is located at\n#\n#     http://aws.amazon.com/apache2.0/\n#\n# or in the \"license\" file accompanying this file. This file is\n# distributed on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF\n# ANY KIND, either express or implied. See the License for the specific\n# language governing permissions and limitations under the License.\nimport logging\nimport os\nimport copy\n\nfrom botocore.awsrequest import AWSRequest\nfrom botocore.httpsession import URLLib3Session\nfrom botocore.exceptions import ProfileNotFound\nfrom awscli.compat import six\n\nfrom awscli.compat import compat_open\nfrom awscli.argprocess import ParamError\n\n\nlogger = logging.getLogger(__name__)\n\n# These are special cased arguments that do _not_ get the\n# special param file processing.  This is typically because it\n# refers to an actual URI of some sort and we don't want to actually\n# download the content (i.e TemplateURL in cloudformation).\nPARAMFILE_DISABLED = set([\n    'api-gateway.put-integration.uri',\n    'api-gateway.create-integration.integration-uri',\n    'api-gateway.update-integration.integration-uri',\n    'api-gateway.create-api.target',\n    'api-gateway.update-api.target',\n    'appstream.create-stack.redirect-url',\n    'appstream.create-stack.feedback-url',\n    'appstream.update-stack.redirect-url',\n    'appstream.update-stack.feedback-url',\n    'cloudformation.create-stack.template-url',\n    'cloudformation.update-stack.template-url',\n    'cloudformation.create-stack-set.template-url',\n    'cloudformation.update-stack-set.template-url',\n    'cloudformation.create-change-set.template-url',\n    'cloudformation.validate-template.template-url',\n    'cloudformation.estimate-template-cost.template-url',\n    'cloudformation.get-template-summary.template-url',\n\n    'cloudformation.create-stack.stack-policy-url',\n    'cloudformation.update-stack.stack-policy-url',\n    'cloudformation.set-stack-policy.stack-policy-url',\n    # aws cloudformation package --template-file\n    'custom.package.template-file',\n    # aws cloudformation deploy --template-file\n    'custom.deploy.template-file',\n\n    'cloudformation.update-stack.stack-policy-during-update-url',\n    # We will want to change the event name to ``s3`` as opposed to\n    # custom in the near future along with ``s3`` to ``s3api``.\n    'custom.cp.website-redirect',\n    'custom.mv.website-redirect',\n    'custom.sync.website-redirect',\n\n    'guardduty.create-ip-set.location',\n    'guardduty.update-ip-set.location',\n    'guardduty.create-threat-intel-set.location',\n    'guardduty.update-threat-intel-set.location',\n    'comprehend.detect-dominant-language.text',\n    'comprehend.batch-detect-dominant-language.text-list',\n    'comprehend.detect-entities.text',\n    'comprehend.batch-detect-entities.text-list',\n    'comprehend.detect-key-phrases.text',\n    'comprehend.batch-detect-key-phrases.text-list',\n    'comprehend.detect-sentiment.text',\n    'comprehend.batch-detect-sentiment.text-list',\n\n    'iam.create-open-id-connect-provider.url',\n\n    'machine-learning.predict.predict-endpoint',\n\n    'mediatailor.put-playback-configuration.ad-decision-server-url',\n    'mediatailor.put-playback-configuration.slate-ad-url',\n    'mediatailor.put-playback-configuration.video-content-source-url',\n\n    'rds.copy-db-cluster-snapshot.pre-signed-url',\n    'rds.create-db-cluster.pre-signed-url',\n    'rds.copy-db-snapshot.pre-signed-url',\n    'rds.create-db-instance-read-replica.pre-signed-url',\n\n    'sagemaker.create-notebook-instance.default-code-repository',\n    'sagemaker.create-notebook-instance.additional-code-repositories',\n    'sagemaker.update-notebook-instance.default-code-repository',\n    'sagemaker.update-notebook-instance.additional-code-repositories',\n\n    'serverlessapplicationrepository.create-application.home-page-url',\n    'serverlessapplicationrepository.create-application.license-url',\n    'serverlessapplicationrepository.create-application.readme-url',\n    'serverlessapplicationrepository.create-application.source-code-url',\n    'serverlessapplicationrepository.create-application.template-url',\n    'serverlessapplicationrepository.create-application-version.source-code-url',\n    'serverlessapplicationrepository.create-application-version.template-url',\n    'serverlessapplicationrepository.update-application.home-page-url',\n    'serverlessapplicationrepository.update-application.readme-url',\n\n    'service-catalog.create-product.support-url',\n    'service-catalog.update-product.support-url',\n\n    'ses.put-account-details.website-url',\n\n    'sqs.add-permission.queue-url',\n    'sqs.change-message-visibility.queue-url',\n    'sqs.change-message-visibility-batch.queue-url',\n    'sqs.delete-message.queue-url',\n    'sqs.delete-message-batch.queue-url',\n    'sqs.delete-queue.queue-url',\n    'sqs.get-queue-attributes.queue-url',\n    'sqs.list-dead-letter-source-queues.queue-url',\n    'sqs.receive-message.queue-url',\n    'sqs.remove-permission.queue-url',\n    'sqs.send-message.queue-url',\n    'sqs.send-message-batch.queue-url',\n    'sqs.set-queue-attributes.queue-url',\n    'sqs.purge-queue.queue-url',\n    'sqs.list-queue-tags.queue-url',\n    'sqs.tag-queue.queue-url',\n    'sqs.untag-queue.queue-url',\n\n    's3.copy-object.website-redirect-location',\n    's3.create-multipart-upload.website-redirect-location',\n    's3.put-object.website-redirect-location',\n\n    # Double check that this has been renamed!\n    'sns.subscribe.notification-endpoint',\n\n    'iot.create-job.document-source',\n    'translate.translate-text.text',\n\n    'workdocs.create-notification-subscription.notification-endpoint'\n])\n\n\nclass ResourceLoadingError(Exception):\n    pass\n\n\ndef register_uri_param_handler(session, **kwargs):\n    prefix_map = copy.deepcopy(LOCAL_PREFIX_MAP)\n    try:\n        fetch_url = session.get_scoped_config().get(\n            'cli_follow_urlparam', 'true') == 'true'\n    except ProfileNotFound:\n        # If a --profile is provided that does not exist, loading\n        # a value from get_scoped_config will crash the CLI.\n        # This function can be called as the first handler for\n        # the session-initialized event, which happens before a\n        # profile can be created, even if the command would have\n        # successfully created a profile. Instead of crashing here\n        # on a ProfileNotFound the CLI should just use 'none'.\n        fetch_url = True\n\n    if fetch_url:\n        prefix_map.update(REMOTE_PREFIX_MAP)\n\n    handler = URIArgumentHandler(prefix_map)\n    session.register('load-cli-arg', handler)\n\n\nclass URIArgumentHandler(object):\n    def __init__(self, prefixes=None):\n        if prefixes is None:\n            prefixes = copy.deepcopy(LOCAL_PREFIX_MAP)\n            prefixes.update(REMOTE_PREFIX_MAP)\n        self._prefixes = prefixes\n\n    def __call__(self, event_name, param, value, **kwargs):\n        \"\"\"Handler that supports param values from URIs.\"\"\"\n        cli_argument = param\n        qualified_param_name = '.'.join(event_name.split('.')[1:])\n        if qualified_param_name in PARAMFILE_DISABLED or \\\n                getattr(cli_argument, 'no_paramfile', None):\n            return\n        else:\n            return self._check_for_uri_param(cli_argument, value)\n\n    def _check_for_uri_param(self, param, value):\n        if isinstance(value, list) and len(value) == 1:\n            value = value[0]\n        try:\n            return get_paramfile(value, self._prefixes)\n        except ResourceLoadingError as e:\n            raise ParamError(param.cli_name, six.text_type(e))\n\n\ndef get_paramfile(path, cases):\n    \"\"\"Load parameter based on a resource URI.\n\n    It is possible to pass parameters to operations by referring\n    to files or URI's.  If such a reference is detected, this\n    function attempts to retrieve the data from the file or URI\n    and returns it.  If there are any errors or if the ``path``\n    does not appear to refer to a file or URI, a ``None`` is\n    returned.\n\n    :type path: str\n    :param path: The resource URI, e.g. file://foo.txt.  This value\n        may also be a non resource URI, in which case ``None`` is returned.\n\n    :type cases: dict\n    :param cases: A dictionary of URI prefixes to function mappings\n        that a parameter is checked against.\n\n    :return: The loaded value associated with the resource URI.\n        If the provided ``path`` is not a resource URI, then a\n        value of ``None`` is returned.\n\n    \"\"\"\n    data = None\n    if isinstance(path, six.string_types):\n        for prefix, function_spec in cases.items():\n            if path.startswith(prefix):\n                function, kwargs = function_spec\n                data = function(prefix, path, **kwargs)\n    return data\n\n\ndef get_file(prefix, path, mode):\n    file_path = os.path.expandvars(os.path.expanduser(path[len(prefix):]))\n    try:\n        with compat_open(file_path, mode) as f:\n            return f.read()\n    except UnicodeDecodeError:\n        raise ResourceLoadingError(\n            'Unable to load paramfile (%s), text contents could '\n            'not be decoded.  If this is a binary file, please use the '\n            'fileb:// prefix instead of the file:// prefix.' % file_path)\n    except (OSError, IOError) as e:\n        raise ResourceLoadingError('Unable to load paramfile %s: %s' % (\n            path, e))\n\n\ndef get_uri(prefix, uri):\n    try:\n        session = URLLib3Session()\n        r = session.send(AWSRequest('GET', uri).prepare())\n        if r.status_code == 200:\n            return r.text\n        else:\n            raise ResourceLoadingError(\n                \"received non 200 status code of %s\" % (\n                    r.status_code))\n    except Exception as e:\n        raise ResourceLoadingError('Unable to retrieve %s: %s' % (uri, e))\n\n\nLOCAL_PREFIX_MAP = {\n    'file://': (get_file, {'mode': 'r'}),\n    'fileb://': (get_file, {'mode': 'rb'}),\n}\n\n\nREMOTE_PREFIX_MAP = {\n    'http://': (get_uri, {}),\n    'https://': (get_uri, {}),\n}\n", "path": "awscli/paramfile.py"}]}