File size: 6,839 Bytes
a06facb
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
import copy

import botocore.parsers
import botocore.serialize
from botocore.args import ClientArgsCreator

from .config import AioConfig
from .endpoint import AioEndpointCreator
from .regions import AioEndpointRulesetResolver
from .signers import AioRequestSigner


class AioClientArgsCreator(ClientArgsCreator):
    # NOTE: we override this so we can pull out the custom AioConfig params and
    #       use an AioEndpointCreator
    def get_client_args(
        self,
        service_model,
        region_name,
        is_secure,
        endpoint_url,
        verify,
        credentials,
        scoped_config,
        client_config,
        endpoint_bridge,
        auth_token=None,
        endpoints_ruleset_data=None,
        partition_data=None,
    ):
        final_args = self.compute_client_args(
            service_model,
            client_config,
            endpoint_bridge,
            region_name,
            endpoint_url,
            is_secure,
            scoped_config,
        )

        service_name = final_args['service_name']  # noqa
        parameter_validation = final_args['parameter_validation']
        endpoint_config = final_args['endpoint_config']
        protocol = final_args['protocol']
        config_kwargs = final_args['config_kwargs']
        s3_config = final_args['s3_config']
        partition = endpoint_config['metadata'].get('partition', None)
        socket_options = final_args['socket_options']
        configured_endpoint_url = final_args['configured_endpoint_url']

        signing_region = endpoint_config['signing_region']
        endpoint_region_name = endpoint_config['region_name']

        event_emitter = copy.copy(self._event_emitter)
        signer = AioRequestSigner(
            service_model.service_id,
            signing_region,
            endpoint_config['signing_name'],
            endpoint_config['signature_version'],
            credentials,
            event_emitter,
            auth_token,
        )

        config_kwargs['s3'] = s3_config

        # aiobotocore addition
        if isinstance(client_config, AioConfig):
            connector_args = client_config.connector_args
        else:
            connector_args = None

        new_config = AioConfig(connector_args, **config_kwargs)
        endpoint_creator = AioEndpointCreator(event_emitter)

        endpoint = endpoint_creator.create_endpoint(
            service_model,
            region_name=endpoint_region_name,
            endpoint_url=endpoint_config['endpoint_url'],
            verify=verify,
            response_parser_factory=self._response_parser_factory,
            max_pool_connections=new_config.max_pool_connections,
            proxies=new_config.proxies,
            timeout=(new_config.connect_timeout, new_config.read_timeout),
            socket_options=socket_options,
            client_cert=new_config.client_cert,
            proxies_config=new_config.proxies_config,
            connector_args=new_config.connector_args,
        )

        serializer = botocore.serialize.create_serializer(
            protocol, parameter_validation
        )
        response_parser = botocore.parsers.create_parser(protocol)

        ruleset_resolver = self._build_endpoint_resolver(
            endpoints_ruleset_data,
            partition_data,
            client_config,
            service_model,
            endpoint_region_name,
            region_name,
            configured_endpoint_url,
            endpoint,
            is_secure,
            endpoint_bridge,
            event_emitter,
        )

        # Copy the session's user agent factory and adds client configuration.
        client_ua_creator = self._session_ua_creator.with_client_config(
            new_config
        )
        supplied_ua = client_config.user_agent if client_config else None
        new_config._supplied_user_agent = supplied_ua

        return {
            'serializer': serializer,
            'endpoint': endpoint,
            'response_parser': response_parser,
            'event_emitter': event_emitter,
            'request_signer': signer,
            'service_model': service_model,
            'loader': self._loader,
            'client_config': new_config,
            'partition': partition,
            'exceptions_factory': self._exceptions_factory,
            'endpoint_ruleset_resolver': ruleset_resolver,
            'user_agent_creator': client_ua_creator,
        }

    def _build_endpoint_resolver(
        self,
        endpoints_ruleset_data,
        partition_data,
        client_config,
        service_model,
        endpoint_region_name,
        region_name,
        endpoint_url,
        endpoint,
        is_secure,
        endpoint_bridge,
        event_emitter,
    ):
        if endpoints_ruleset_data is None:
            return None

        # The legacy EndpointResolver is global to the session, but
        # EndpointRulesetResolver is service-specific. Builtins for
        # EndpointRulesetResolver must not be derived from the legacy
        # endpoint resolver's output, including final_args, s3_config,
        # etc.
        s3_config_raw = self.compute_s3_config(client_config) or {}
        service_name_raw = service_model.endpoint_prefix
        # Maintain complex logic for s3 and sts endpoints for backwards
        # compatibility.
        if service_name_raw in ['s3', 'sts'] or region_name is None:
            eprv2_region_name = endpoint_region_name
        else:
            eprv2_region_name = region_name
        resolver_builtins = self.compute_endpoint_resolver_builtin_defaults(
            region_name=eprv2_region_name,
            service_name=service_name_raw,
            s3_config=s3_config_raw,
            endpoint_bridge=endpoint_bridge,
            client_endpoint_url=endpoint_url,
            legacy_endpoint_url=endpoint.host,
        )
        # botocore does not support client context parameters generically
        # for every service. Instead, the s3 config section entries are
        # available as client context parameters. In the future, endpoint
        # rulesets of services other than s3/s3control may require client
        # context parameters.
        client_context = (
            s3_config_raw if self._is_s3_service(service_name_raw) else {}
        )
        sig_version = (
            client_config.signature_version
            if client_config is not None
            else None
        )
        return AioEndpointRulesetResolver(
            endpoint_ruleset_data=endpoints_ruleset_data,
            partition_data=partition_data,
            service_model=service_model,
            builtins=resolver_builtins,
            client_context=client_context,
            event_emitter=event_emitter,
            use_ssl=is_secure,
            requested_auth_scheme=sig_version,
        )