1 /*
2 * Copyright 2011-2020 Amazon Technologies, Inc.
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 * You may obtain a copy of the License at:
7 *
8 * http://aws.amazon.com/apache2.0
9 *
10 * This file is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
11 * OR CONDITIONS OF ANY KIND, either express or implied. See the
12 * License for the specific language governing permissions and
13 * limitations under the License.
14 */
15 package com.amazonaws;
16
17 import com.amazonaws.annotation.NotThreadSafe;
18
19 import com.amazonaws.http.apache.request.impl.ApacheHttpRequestFactory;
20 import com.amazonaws.http.settings.HttpClientSettings;
21 import java.io.InputStream;
22 import java.util.EnumMap;
23
24 /**
25 * Client request options such as client markers for individual
26 * {@link AmazonWebServiceRequest}s.
27 */
28 @NotThreadSafe
29 public final class RequestClientOptions {
30 /**
31 * Used to enable mark-and-reset for
32 * non-mark-and-resettable non-file input stream for up to 128K memory
33 * buffering by default. Add 1 to get around an implementation quirk of
34 * BufferedInputStream.
35 *
36 * Retries after reading {@link #DEFAULT_STREAM_BUFFER_SIZE} bytes would
37 * fail to reset the underlying input stream as the mark position would
38 * have been invalidated.
39 *
40 */
41 public static final int DEFAULT_STREAM_BUFFER_SIZE = (1 << 17)+1;
42 public static enum Marker {
43 /**
44 * Used to specify the http user_agent value.
45 * This marker is intended only for internal use by the AWS SDK.
46 */
47 USER_AGENT,
48 ;
49 }
50
51 private final EnumMap<Marker,String> markers = new EnumMap<Marker,String>(Marker.class);
52 /**
53 * Used for mark-and-reset purposes during retry.
54 */
55 private int readLimit = DEFAULT_STREAM_BUFFER_SIZE;
56
57 /**
58 * Used to skip the appendUri call in {@link ApacheHttpRequestFactory#create(Request, HttpClientSettings)} method.
59 *
60 * This options is used in APIs that directly execute given presigned urls. For these requests, the extra slash
61 * should not be included.
62 */
63 private boolean skipAppendUriPath = false;
64
65 /**
66 * Returns the value of the specified marker; or null if there is no such
67 * value.
68 */
69 public String getClientMarker(Marker marker) {
70 return markers.get(marker);
71 }
72
73 /**
74 * Associates the given value with the given marker.
75 * Note the {@link Marker#USER_AGENT} is only intended for internal use
76 * by the AWS SDK.
77 */
78 public void putClientMarker(Marker marker, String value) {
79 markers.put(marker, value);
80 }
81
82 /**
83 * Appends a user agent to the USER_AGENT client marker.
84 * This method is intended only for internal use by the AWS SDK.
85 */
86 public void appendUserAgent(String userAgent) {
87 String marker = markers.get(Marker.USER_AGENT);
88 if (marker == null)
89 marker = "";
90 marker = createUserAgentMarkerString(marker, userAgent);
91 putClientMarker(Marker.USER_AGENT, marker);
92 }
93
94 /**
95 * Appends the given client marker string to the existing one and returns it.
96 */
97 private String createUserAgentMarkerString(final String marker, String userAgent) {
98 return marker.contains(userAgent) ? marker : marker + " " + userAgent;
99 }
100
101 /**
102 * Returns the mark-and-reset read limit; defaults to
103 * {@value #DEFAULT_STREAM_BUFFER_SIZE}.
104 *
105 * @see InputStream#mark(int)
106 */
107 public final int getReadLimit() {
108 return readLimit;
109 }
110
111 /**
112 * Sets the optional mark-and-reset read limit used for signing and retry
113 * purposes.
114 *
115 * @see InputStream#mark(int)
116 */
117 public final void setReadLimit(int readLimit) {
118 this.readLimit = readLimit;
119 }
120
121
122 /**
123 * Gets the boolean value to skip the appendUri call in {@link ApacheHttpRequestFactory#create(Request, HttpClientSettings)}
124 * method. The default value is false, which means the appendUri call is not skipped.
125 *
126 * This options is used in APIs that directly execute given presigned urls. For these requests, the extra slash
127 * should not be included.
128 */
129 public boolean isSkipAppendUriPath() {
130 return skipAppendUriPath;
131 }
132
133 /**
134 * Sets the boolean value to skip the appendUri call in {@link ApacheHttpRequestFactory#create(Request, HttpClientSettings)}
135 * method. The default value is false, which means the appendUri call is not skipped.
136 *
137 * This options is used in APIs that directly execute given presigned urls. For these requests, the extra slash
138 * should not be included.
139 */
140 public void setSkipAppendUriPath(boolean skipAppendUriPath) {
141 this.skipAppendUriPath = skipAppendUriPath;
142 }
143
144
145 /**
146 * Copy the internal states of this <code>RequestClientOptions</code> to the
147 * target <code>RequestClientOptions</code>.
148 */
149 void copyTo(RequestClientOptions target) {
150 target.setReadLimit(getReadLimit());
151 target.setSkipAppendUriPath(isSkipAppendUriPath());
152 for (Marker marker: Marker.values())
153 target.putClientMarker(marker, getClientMarker(marker));
154 }
155 }
156