• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License").
5  * You may not use this file except in compliance with the License.
6  * A copy of the License is located at
7  *
8  *  http://aws.amazon.com/apache2.0
9  *
10  * or in the "license" file accompanying this file. This file is distributed
11  * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
12  * express or implied. See the License for the specific language governing
13  * permissions and limitations under the License.
14  */
15 
16 package software.amazon.awssdk.http;
17 
18 import static java.util.Collections.singletonList;
19 
20 import java.net.URI;
21 import java.util.List;
22 import java.util.Map;
23 import java.util.Optional;
24 import java.util.function.Consumer;
25 import software.amazon.awssdk.annotations.Immutable;
26 import software.amazon.awssdk.annotations.SdkPublicApi;
27 import software.amazon.awssdk.utils.http.SdkHttpUtils;
28 
29 /**
30  * An immutable HTTP request with a possible HTTP body.
31  *
32  * <p>All implementations of this interface MUST be immutable. Instead of implementing this interface, consider using
33  * {@link #builder()} to create an instance.</p>
34  */
35 @SdkPublicApi
36 @Immutable
37 public interface SdkHttpFullRequest
38     extends SdkHttpRequest {
39     /**
40      * @return Builder instance to construct a {@link DefaultSdkHttpFullRequest}.
41      */
builder()42     static SdkHttpFullRequest.Builder builder() {
43         return new DefaultSdkHttpFullRequest.Builder();
44     }
45 
46     @Override
toBuilder()47     SdkHttpFullRequest.Builder toBuilder();
48 
49     /**
50      * @return The optional {@link ContentStreamProvider} for this request.
51      */
contentStreamProvider()52     Optional<ContentStreamProvider> contentStreamProvider();
53 
54     /**
55      * A mutable builder for {@link SdkHttpFullRequest}. An instance of this can be created using
56      * {@link SdkHttpFullRequest#builder()}.
57      */
58     interface Builder extends SdkHttpRequest.Builder {
59         /**
60          * Convenience method to set the {@link #protocol()}, {@link #host()}, {@link #port()},
61          * {@link #encodedPath()} and extracts query parameters from a {@link URI} object.
62          *
63          * @param uri URI containing protocol, host, port and path.
64          * @return This builder for method chaining.
65          */
66         @Override
uri(URI uri)67         default Builder uri(URI uri) {
68             Builder builder =  this.protocol(uri.getScheme())
69                        .host(uri.getHost())
70                        .port(uri.getPort())
71                        .encodedPath(SdkHttpUtils.appendUri(uri.getRawPath(), encodedPath()));
72             if (uri.getRawQuery() != null) {
73                 builder.clearQueryParameters();
74                 SdkHttpUtils.uriParams(uri)
75                             .forEach(this::putRawQueryParameter);
76             }
77             return builder;
78         }
79 
80         /**
81          * The protocol, exactly as it was configured with {@link #protocol(String)}.
82          */
83         @Override
protocol()84         String protocol();
85 
86         /**
87          * Configure a {@link SdkHttpRequest#protocol()} to be used in the created HTTP request. This is not validated until the
88          * http request is created.
89          */
90         @Override
protocol(String protocol)91         Builder protocol(String protocol);
92 
93         /**
94          * The host, exactly as it was configured with {@link #host(String)}.
95          */
96         @Override
host()97         String host();
98 
99         /**
100          * Configure a {@link SdkHttpRequest#host()} to be used in the created HTTP request. This is not validated until the
101          * http request is created.
102          */
103         @Override
host(String host)104         Builder host(String host);
105 
106         /**
107          * The port, exactly as it was configured with {@link #port(Integer)}.
108          */
109         @Override
port()110         Integer port();
111 
112         /**
113          * Configure a {@link SdkHttpRequest#port()} to be used in the created HTTP request. This is not validated until the
114          * http request is created. In order to simplify mapping from a {@link URI}, "-1" will be treated as "null" when the http
115          * request is created.
116          */
117         @Override
port(Integer port)118         Builder port(Integer port);
119 
120         /**
121          * The path, exactly as it was configured with {@link #encodedPath(String)}.
122          */
123         @Override
encodedPath()124         String encodedPath();
125 
126         /**
127          * Configure an {@link SdkHttpRequest#encodedPath()} to be used in the created HTTP request. This is not validated
128          * until the http request is created. This path MUST be URL encoded.
129          *
130          * <p>Justification of requirements: The path must be encoded when it is configured, because there is no way for the HTTP
131          * implementation to distinguish a "/" that is part of a resource name that should be encoded as "%2F" from a "/" that is
132          * part of the actual path.</p>
133          */
134         @Override
encodedPath(String path)135         Builder encodedPath(String path);
136 
137         /**
138          * The query parameters, exactly as they were configured with {@link #rawQueryParameters(Map)},
139          * {@link #putRawQueryParameter(String, String)} and {@link #putRawQueryParameter(String, List)}.
140          */
141         @Override
rawQueryParameters()142         Map<String, List<String>> rawQueryParameters();
143 
144         /**
145          * Add a single un-encoded query parameter to be included in the created HTTP request.
146          *
147          * <p>This completely <b>OVERRIDES</b> any values already configured with this parameter name in the builder.</p>
148          *
149          * @param paramName The name of the query parameter to add
150          * @param paramValue The un-encoded value for the query parameter.
151          */
152         @Override
putRawQueryParameter(String paramName, String paramValue)153         default Builder putRawQueryParameter(String paramName, String paramValue) {
154             return putRawQueryParameter(paramName, singletonList(paramValue));
155         }
156 
157         /**
158          * Add a single un-encoded query parameter to be included in the created HTTP request.
159          *
160          * <p>This will <b>ADD</b> the value to any existing values already configured with this parameter name in
161          * the builder.</p>
162          *
163          * @param paramName The name of the query parameter to add
164          * @param paramValue The un-encoded value for the query parameter.
165          */
166         @Override
appendRawQueryParameter(String paramName, String paramValue)167         Builder appendRawQueryParameter(String paramName, String paramValue);
168 
169         /**
170          * Add a single un-encoded query parameter with multiple values to be included in the created HTTP request.
171          *
172          * <p>This completely <b>OVERRIDES</b> any values already configured with this parameter name in the builder.</p>
173          *
174          * @param paramName The name of the query parameter to add
175          * @param paramValues The un-encoded values for the query parameter.
176          */
177         @Override
putRawQueryParameter(String paramName, List<String> paramValues)178         Builder putRawQueryParameter(String paramName, List<String> paramValues);
179 
180         /**
181          * Configure an {@link SdkHttpRequest#rawQueryParameters()} to be used in the created HTTP request. This is not validated
182          * until the http request is created. This overrides any values currently configured in the builder. The query parameters
183          * MUST NOT be URL encoded.
184          *
185          * <p>Justification of requirements: The query parameters must not be encoded when they are configured because some HTTP
186          * implementations perform this encoding automatically.</p>
187          */
188         @Override
rawQueryParameters(Map<String, List<String>> queryParameters)189         Builder rawQueryParameters(Map<String, List<String>> queryParameters);
190 
191         /**
192          * Remove all values for the requested query parameter from this builder.
193          */
194         @Override
removeQueryParameter(String paramName)195         Builder removeQueryParameter(String paramName);
196 
197         /**
198          * Removes all query parameters from this builder.
199          */
200         @Override
clearQueryParameters()201         Builder clearQueryParameters();
202 
203         /**
204          * The path, exactly as it was configured with {@link #method(SdkHttpMethod)}.
205          */
206         @Override
method()207         SdkHttpMethod method();
208 
209         /**
210          * Configure an {@link SdkHttpRequest#method()} to be used in the created HTTP request. This is not validated
211          * until the http request is created.
212          */
213         @Override
method(SdkHttpMethod httpMethod)214         Builder method(SdkHttpMethod httpMethod);
215 
216         /**
217          * The query parameters, exactly as they were configured with {@link #headers(Map)},
218          * {@link #putHeader(String, String)} and {@link #putHeader(String, List)}.
219          */
220         @Override
headers()221         Map<String, List<String>> headers();
222 
223         /**
224          * Add a single header to be included in the created HTTP request.
225          *
226          * <p>This completely <b>OVERRIDES</b> any values already configured with this header name in the builder.</p>
227          *
228          * @param headerName The name of the header to add (eg. "Host")
229          * @param headerValue The value for the header
230          */
231         @Override
putHeader(String headerName, String headerValue)232         default Builder putHeader(String headerName, String headerValue) {
233             return putHeader(headerName, singletonList(headerValue));
234         }
235 
236         /**
237          * Add a single header with multiple values to be included in the created HTTP request.
238          *
239          * <p>This completely <b>OVERRIDES</b> any values already configured with this header name in the builder.</p>
240          *
241          * @param headerName The name of the header to add
242          * @param headerValues The values for the header
243          */
244         @Override
putHeader(String headerName, List<String> headerValues)245         Builder putHeader(String headerName, List<String> headerValues);
246 
247         /**
248          * Add a single header to be included in the created HTTP request.
249          *
250          * <p>This will <b>ADD</b> the value to any existing values already configured with this header name in
251          * the builder.</p>
252          *
253          * @param headerName The name of the header to add
254          * @param headerValue The value for the header
255          */
256         @Override
appendHeader(String headerName, String headerValue)257         Builder appendHeader(String headerName, String headerValue);
258 
259         /**
260          * Configure an {@link SdkHttpRequest#headers()} to be used in the created HTTP request. This is not validated
261          * until the http request is created. This overrides any values currently configured in the builder.
262          */
263         @Override
headers(Map<String, List<String>> headers)264         Builder headers(Map<String, List<String>> headers);
265 
266         /**
267          * Remove all values for the requested header from this builder.
268          */
269         @Override
removeHeader(String headerName)270         Builder removeHeader(String headerName);
271 
272         /**
273          * Removes all headers from this builder.
274          */
275         @Override
clearHeaders()276         Builder clearHeaders();
277 
278         /**
279          * Set the {@link ContentStreamProvider} for this request.
280          *
281          * @param contentStreamProvider The ContentStreamProvider.
282          * @return This object for method chaining.
283          */
contentStreamProvider(ContentStreamProvider contentStreamProvider)284         Builder contentStreamProvider(ContentStreamProvider contentStreamProvider);
285 
286         /**
287          * @return The {@link ContentStreamProvider} for this request.
288          */
contentStreamProvider()289         ContentStreamProvider contentStreamProvider();
290 
291         @Override
copy()292         SdkHttpFullRequest.Builder copy();
293 
294         @Override
applyMutation(Consumer<SdkHttpRequest.Builder> mutator)295         SdkHttpFullRequest.Builder applyMutation(Consumer<SdkHttpRequest.Builder> mutator);
296 
297         @Override
build()298         SdkHttpFullRequest build();
299     }
300 
301 }
302