• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2022 The Chromium Authors
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4 
5 package android.net.http;
6 
7 import android.annotation.SuppressLint;
8 
9 import androidx.annotation.NonNull;
10 import androidx.annotation.Nullable;
11 
12 import java.time.Duration;
13 import java.util.Collections;
14 import java.util.LinkedHashSet;
15 import java.util.Set;
16 
17 /**
18  * Configuration options for QUIC.
19  *
20  * <p>The settings in this class are only relevant if QUIC is enabled. Use
21  * {@link HttpEngine.Builder#setEnableQuic(boolean)} to enable / disable QUIC for
22  * the HTTP engine.
23  */
24 // SuppressLint to be consistent with other cronet code
25 @SuppressLint("UserHandleName")
26 public class QuicOptions {
27     private final Set<String> mQuicHostAllowlist;
28     private final Set<String> mEnabledQuicVersions;
29 
30     private final Set<String> mConnectionOptions;
31     private final Set<String> mClientConnectionOptions;
32     @Nullable
33     private final Integer mInMemoryServerConfigsCacheSize;
34     @Nullable
35     private final String mHandshakeUserAgent;
36     @Nullable
37     private final Boolean mRetryWithoutAltSvcOnQuicErrors;
38     @Nullable
39     private final Boolean mEnableTlsZeroRtt;
40 
41     @Nullable
42     private final Duration mPreCryptoHandshakeIdleTimeout;
43     @Nullable
44     private final Duration mCryptoHandshakeTimeout;
45 
46     @Nullable
47     private final Duration mIdleConnectionTimeout;
48     @Nullable
49     private final Duration mRetransmittableOnWireTimeout;
50 
51     @Nullable
52     private final Boolean mCloseSessionsOnIpChange;
53     @Nullable
54     private final Boolean mGoawaySessionsOnIpChange;
55 
56     @Nullable
57     private final Duration mInitialBrokenServicePeriod;
58     @Nullable
59     private final Boolean mIncreaseBrokenServicePeriodExponentially;
60     @Nullable
61     private final Boolean mDelayJobsWithAvailableSpdySession;
62 
63     private final Set<String> mExtraQuicheFlags;
64 
QuicOptions(Builder builder)65     QuicOptions(Builder builder) {
66         this.mQuicHostAllowlist =
67                 Collections.unmodifiableSet(new LinkedHashSet<>(builder.mQuicHostAllowlist));
68         this.mEnabledQuicVersions =
69                 Collections.unmodifiableSet(new LinkedHashSet<>(builder.mEnabledQuicVersions));
70         this.mConnectionOptions =
71                 Collections.unmodifiableSet(new LinkedHashSet<>(builder.mConnectionOptions));
72         this.mClientConnectionOptions =
73                 Collections.unmodifiableSet(new LinkedHashSet<>(builder.mClientConnectionOptions));
74         this.mInMemoryServerConfigsCacheSize = builder.mInMemoryServerConfigsCacheSize;
75         this.mHandshakeUserAgent = builder.mHandshakeUserAgent;
76         this.mRetryWithoutAltSvcOnQuicErrors = builder.mRetryWithoutAltSvcOnQuicErrors;
77         this.mEnableTlsZeroRtt = builder.mEnableTlsZeroRtt;
78         this.mPreCryptoHandshakeIdleTimeout = builder.mPreCryptoHandshakeIdleTimeout;
79         this.mCryptoHandshakeTimeout = builder.mCryptoHandshakeTimeout;
80         this.mIdleConnectionTimeout = builder.mIdleConnectionTimeout;
81         this.mRetransmittableOnWireTimeout = builder.mRetransmittableOnWireTimeout;
82         this.mCloseSessionsOnIpChange = builder.mCloseSessionsOnIpChange;
83         this.mGoawaySessionsOnIpChange = builder.mGoawaySessionsOnIpChange;
84         this.mInitialBrokenServicePeriod = builder.mInitialBrokenServicePeriod;
85         this.mIncreaseBrokenServicePeriodExponentially =
86                 builder.mIncreaseBrokenServicePeriodExponentially;
87         this.mDelayJobsWithAvailableSpdySession = builder.mDelayJobsWithAvailableSpdySession;
88         this.mExtraQuicheFlags =
89                 Collections.unmodifiableSet(new LinkedHashSet<>(builder.mExtraQuicheFlags));
90     }
91 
92     /**
93      * See {@link Builder#addAllowedQuicHost}
94      */
95     @NonNull
getAllowedQuicHosts()96     public Set<String> getAllowedQuicHosts() {
97         return mQuicHostAllowlist;
98     }
99 
100 
101     /**
102      * See {@link Builder#setInMemoryServerConfigsCacheSize}
103      */
hasInMemoryServerConfigsCacheSize()104      public boolean hasInMemoryServerConfigsCacheSize() {
105         return mInMemoryServerConfigsCacheSize != null;
106      }
107 
108     /**
109      * See {@link Builder#setInMemoryServerConfigsCacheSize}
110      */
getInMemoryServerConfigsCacheSize()111     public int getInMemoryServerConfigsCacheSize() {
112         if (!hasInMemoryServerConfigsCacheSize()) {
113             throw new IllegalStateException("InMemoryServerConfigsCacheSize is not set");
114         }
115         return mInMemoryServerConfigsCacheSize;
116     }
117 
118     /**
119      * See {@link Builder#setHandshakeUserAgent}
120      */
121     @Nullable
getHandshakeUserAgent()122     public String getHandshakeUserAgent() {
123         return mHandshakeUserAgent;
124     }
125 
126     /**
127      * See {@link Builder#setIdleConnectionTimeout}
128      */
129     @Nullable
getIdleConnectionTimeout()130     public Duration getIdleConnectionTimeout() {
131         return mIdleConnectionTimeout;
132     }
133 
134     /**
135      * Create a new {@code QuicOptions} builder.
136      *
137      * {@hide}
138      */
builder()139     public static Builder builder() {
140         return new Builder();
141     }
142 
143     /**
144      * Builder for {@link QuicOptions}.
145      */
146     public static final class Builder {
147         private final Set<String> mQuicHostAllowlist = new LinkedHashSet<>();
148         private final Set<String> mEnabledQuicVersions = new LinkedHashSet<>();
149         private final Set<String> mConnectionOptions = new LinkedHashSet<>();
150         private final Set<String> mClientConnectionOptions = new LinkedHashSet<>();
151         @Nullable
152         private Integer mInMemoryServerConfigsCacheSize;
153         @Nullable
154         private String mHandshakeUserAgent;
155         @Nullable
156         private Boolean mRetryWithoutAltSvcOnQuicErrors;
157         @Nullable
158         private Boolean mEnableTlsZeroRtt;
159         @Nullable
160         private Duration mPreCryptoHandshakeIdleTimeout;
161         @Nullable
162         private Duration mCryptoHandshakeTimeout;
163         @Nullable
164         private Duration mIdleConnectionTimeout;
165         @Nullable
166         private Duration mRetransmittableOnWireTimeout;
167         @Nullable
168         private Boolean mCloseSessionsOnIpChange;
169         @Nullable
170         private Boolean mGoawaySessionsOnIpChange;
171         @Nullable
172         private Duration mInitialBrokenServicePeriod;
173         @Nullable
174         private Boolean mIncreaseBrokenServicePeriodExponentially;
175         @Nullable
176         private Boolean mDelayJobsWithAvailableSpdySession;
177         private final Set<String> mExtraQuicheFlags = new LinkedHashSet<>();
178 
Builder()179         public Builder() {}
180 
181         /**
182          * Adds a host to the QUIC allowlist.
183          *
184          * <p>If no hosts are specified, the per-host allowlist functionality is disabled.
185          * Otherwise, the HTTP stack will only use QUIC when talking to hosts on the allowlist.
186          *
187          * @return the builder for chaining
188          */
189         @NonNull
addAllowedQuicHost(@onNull String quicHost)190         public Builder addAllowedQuicHost(@NonNull String quicHost) {
191             mQuicHostAllowlist.add(quicHost);
192             return this;
193         }
194 
195         /**
196          * Sets how many server configurations (metadata like list of alt svc, whether QUIC is
197          * supported, etc.) should be held in memory.
198          *
199          * <p>If the storage path is set ({@link HttpEngine.Builder#setStoragePath(String)},
200          * the HTTP stack will also persist the server configurations on disk.
201          *
202          * @return the builder for chaining
203          */
204         @NonNull
setInMemoryServerConfigsCacheSize(int inMemoryServerConfigsCacheSize)205         public Builder setInMemoryServerConfigsCacheSize(int inMemoryServerConfigsCacheSize) {
206             this.mInMemoryServerConfigsCacheSize = inMemoryServerConfigsCacheSize;
207             return this;
208         }
209 
210         /**
211          * Sets the user agent to be used outside of HTTP requests (for example for QUIC
212          * handshakes).
213          *
214          * <p>To set the default user agent for HTTP requests, use
215          * {@link HttpEngine.Builder#setUserAgent(String)} instead.
216          *
217          * @return the builder for chaining
218          */
219         @NonNull
setHandshakeUserAgent(@onNull String handshakeUserAgent)220         public Builder setHandshakeUserAgent(@NonNull String handshakeUserAgent) {
221             this.mHandshakeUserAgent = handshakeUserAgent;
222             return this;
223         }
224 
225         /**
226          * Sets the maximum idle time for a connection. The actual value for the idle timeout is
227          * the minimum of this value and the server's and is negotiated during the handshake. Thus,
228          * it only applies after the handshake has completed. If no activity is detected
229          * on the connection for the set duration, the connection is closed.
230          *
231          * <p>See <a href="https://www.rfc-editor.org/rfc/rfc9114.html#name-idle-connections">RFC
232          * 9114, section 5.1 </a> for more details.
233          *
234          * @return the builder for chaining
235          */
236         @NonNull
setIdleConnectionTimeout(@onNull Duration idleConnectionTimeout)237         public Builder setIdleConnectionTimeout(@NonNull Duration idleConnectionTimeout) {
238             this.mIdleConnectionTimeout = idleConnectionTimeout;
239             return this;
240         }
241 
242         /**
243          * Creates and returns the final {@link QuicOptions} instance, based on the values
244          * in this builder.
245          */
246         @NonNull
build()247         public QuicOptions build() {
248             return new QuicOptions(this);
249         }
250     }
251 
252     /**
253      * An annotation for APIs which are not considered stable yet.
254      *
255      * <p>Applications using experimental APIs must acknowledge that they're aware of using APIs
256      * that are not considered stable. The APIs might change functionality, break or cease to exist
257      * without notice.
258      *
259      * <p>It's highly recommended to reach out to Cronet maintainers ({@code net-dev@chromium.org})
260      * before using one of the APIs annotated as experimental outside of debugging
261      * and proof-of-concept code. Be ready to help to help polishing the API, or for a "sorry,
262      * really not production ready yet".
263      *
264      * <p>If you still want to use an experimental API in production, you're doing so at your
265      * own risk. You have been warned.
266      *
267      * {@hide}
268      */
269     public @interface Experimental {}
270 }
271