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.io.InputStream; 21 import java.util.List; 22 import java.util.Map; 23 import java.util.Optional; 24 import software.amazon.awssdk.annotations.Immutable; 25 import software.amazon.awssdk.annotations.SdkProtectedApi; 26 27 /** 28 * An immutable HTTP response with a possible HTTP body. 29 * 30 * <p>All implementations of this interface MUST be immutable. Instead of implementing this interface, consider using 31 * {@link #builder()} to create an instance.</p> 32 */ 33 @SdkProtectedApi 34 @Immutable 35 public interface SdkHttpFullResponse 36 extends SdkHttpResponse { 37 /** 38 * @return Builder instance to construct a {@link DefaultSdkHttpFullResponse}. 39 */ builder()40 static Builder builder() { 41 return new DefaultSdkHttpFullResponse.Builder(); 42 } 43 44 @Override toBuilder()45 Builder toBuilder(); 46 47 /** 48 * Returns the optional stream containing the payload data returned by the service. Note: an {@link AbortableInputStream} 49 * is returned instead of an {@link InputStream}. This allows the stream to be aborted before all content is read, which 50 * usually means destroying the underlying HTTP connection. This may be implemented differently in other HTTP implementations. 51 * 52 * <p>When the response does not include payload data, this will return {@link Optional#empty()}.</p> 53 * 54 * @return The optional stream containing the payload data included in this response, or empty if there is no payload. 55 */ content()56 Optional<AbortableInputStream> content(); 57 58 /** 59 * Builder for a {@link DefaultSdkHttpFullResponse}. 60 */ 61 interface Builder extends SdkHttpResponse.Builder { 62 /** 63 * The status text, exactly as it was configured with {@link #statusText(String)}. 64 */ 65 @Override statusText()66 String statusText(); 67 68 /** 69 * Configure an {@link SdkHttpResponse#statusText()} to be used in the created HTTP response. This is not validated 70 * until the http response is created. 71 */ 72 @Override statusText(String statusText)73 Builder statusText(String statusText); 74 75 /** 76 * The status text, exactly as it was configured with {@link #statusCode(int)}. 77 */ 78 @Override statusCode()79 int statusCode(); 80 81 /** 82 * Configure an {@link SdkHttpResponse#statusCode()} to be used in the created HTTP response. This is not validated 83 * until the http response is created. 84 */ 85 @Override statusCode(int statusCode)86 Builder statusCode(int statusCode); 87 88 /** 89 * The query parameters, exactly as they were configured with {@link #headers(Map)}, 90 * {@link #putHeader(String, String)} and {@link #putHeader(String, List)}. 91 */ 92 @Override headers()93 Map<String, List<String>> headers(); 94 95 /** 96 * Add a single header to be included in the created HTTP response. 97 * 98 * <p>This completely <b>OVERRIDES</b> any values already configured with this header name in the builder.</p> 99 * 100 * @param headerName The name of the header to add (eg. "Host") 101 * @param headerValue The value for the header 102 */ 103 @Override putHeader(String headerName, String headerValue)104 default Builder putHeader(String headerName, String headerValue) { 105 return putHeader(headerName, singletonList(headerValue)); 106 } 107 108 /** 109 * Add a single header with multiple values to be included in the created HTTP response. 110 * 111 * <p>This completely <b>OVERRIDES</b> any values already configured with this header name in the builder.</p> 112 * 113 * @param headerName The name of the header to add 114 * @param headerValues The values for the header 115 */ 116 @Override putHeader(String headerName, List<String> headerValues)117 Builder putHeader(String headerName, List<String> headerValues); 118 119 120 /** 121 * Add a single header to be included in the created HTTP request. 122 * 123 * <p>This will <b>ADD</b> the value to any existing values already configured with this header name in 124 * the builder.</p> 125 * 126 * @param headerName The name of the header to add 127 * @param headerValue The value for the header 128 */ 129 @Override appendHeader(String headerName, String headerValue)130 Builder appendHeader(String headerName, String headerValue); 131 132 /** 133 * Configure an {@link SdkHttpResponse#headers()} to be used in the created HTTP response. This is not validated 134 * until the http response is created. This overrides any values currently configured in the builder. 135 */ 136 @Override headers(Map<String, List<String>> headers)137 Builder headers(Map<String, List<String>> headers); 138 139 /** 140 * Remove all values for the requested header from this builder. 141 */ 142 @Override removeHeader(String headerName)143 Builder removeHeader(String headerName); 144 145 /** 146 * Removes all headers from this builder. 147 */ 148 @Override clearHeaders()149 Builder clearHeaders(); 150 151 /** 152 * The content, exactly as it was configured with {@link #content(AbortableInputStream)}. 153 */ content()154 AbortableInputStream content(); 155 156 /** 157 * Configure an {@link SdkHttpFullResponse#content()} to be used in the HTTP response. This is not validated until 158 * the http response is created. 159 * 160 * <p>Implementers should implement the abort method on the input stream to drop all remaining content with the service. 161 * This is usually done by closing the service connection.</p> 162 */ content(AbortableInputStream content)163 Builder content(AbortableInputStream content); 164 165 @Override build()166 SdkHttpFullResponse build(); 167 } 168 } 169