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