aws_smithy_http/
endpoint.rs

1/*
2 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3 * SPDX-License-Identifier: Apache-2.0
4 */
5
6//! Code for resolving an endpoint (URI) that a request should be sent to
7
8#![allow(deprecated)]
9
10use crate::endpoint::error::InvalidEndpointError;
11use http_02x::uri::{Authority, Uri};
12use std::borrow::Cow;
13use std::result::Result as StdResult;
14use std::str::FromStr;
15
16pub mod error;
17pub use error::ResolveEndpointError;
18
19/// An endpoint-resolution-specific Result. Contains either an [`Endpoint`](aws_smithy_types::endpoint::Endpoint) or a [`ResolveEndpointError`].
20#[deprecated(since = "0.60.1", note = "Was never used.")]
21pub type Result = std::result::Result<aws_smithy_types::endpoint::Endpoint, ResolveEndpointError>;
22
23/// A special type that adds support for services that have special URL-prefixing rules.
24#[deprecated(
25    since = "0.60.1",
26    note = "Use aws_smithy_runtime_api::client::endpoint::EndpointPrefix instead."
27)]
28pub type EndpointPrefix = aws_smithy_runtime_api::client::endpoint::EndpointPrefix;
29
30/// Apply `endpoint` to `uri`
31///
32/// This method mutates `uri` by setting the `endpoint` on it
33#[deprecated(
34    since = "0.60.1",
35    note = "Use aws_smithy_runtime::client::endpoint::apply_endpoint instead."
36)]
37pub fn apply_endpoint(
38    uri: &mut Uri,
39    endpoint: &Uri,
40    prefix: Option<&EndpointPrefix>,
41) -> StdResult<(), InvalidEndpointError> {
42    let prefix = prefix.map(EndpointPrefix::as_str).unwrap_or("");
43    let authority = endpoint
44        .authority()
45        .as_ref()
46        .map(|auth| auth.as_str())
47        .unwrap_or("");
48    let authority = if !prefix.is_empty() {
49        Cow::Owned(format!("{}{}", prefix, authority))
50    } else {
51        Cow::Borrowed(authority)
52    };
53    let authority = Authority::from_str(&authority).map_err(|err| {
54        InvalidEndpointError::failed_to_construct_authority(authority.into_owned(), err)
55    })?;
56    let scheme = *endpoint
57        .scheme()
58        .as_ref()
59        .ok_or_else(InvalidEndpointError::endpoint_must_have_scheme)?;
60    let new_uri = Uri::builder()
61        .authority(authority)
62        .scheme(scheme.clone())
63        .path_and_query(merge_paths(endpoint, uri).as_ref())
64        .build()
65        .map_err(InvalidEndpointError::failed_to_construct_uri)?;
66    *uri = new_uri;
67    Ok(())
68}
69
70fn merge_paths<'a>(endpoint: &'a Uri, uri: &'a Uri) -> Cow<'a, str> {
71    if let Some(query) = endpoint.path_and_query().and_then(|pq| pq.query()) {
72        tracing::warn!(query = %query, "query specified in endpoint will be ignored during endpoint resolution");
73    }
74    let endpoint_path = endpoint.path();
75    let uri_path_and_query = uri.path_and_query().map(|pq| pq.as_str()).unwrap_or("");
76    if endpoint_path.is_empty() {
77        Cow::Borrowed(uri_path_and_query)
78    } else {
79        let ep_no_slash = endpoint_path.strip_suffix('/').unwrap_or(endpoint_path);
80        let uri_path_no_slash = uri_path_and_query
81            .strip_prefix('/')
82            .unwrap_or(uri_path_and_query);
83        Cow::Owned(format!("{}/{}", ep_no_slash, uri_path_no_slash))
84    }
85}