1 // Copyright 2014 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 org.chromium.net; 6 7 import java.nio.ByteBuffer; 8 import java.util.concurrent.Executor; 9 10 import androidx.annotation.NonNull; 11 import androidx.annotation.Nullable; 12 13 /** 14 * Controls an HTTP request (GET, PUT, POST etc). Created by {@link UrlRequest.Builder}, which can 15 * be obtained by calling {@link CronetEngine#newUrlRequestBuilder}. Note: All methods must be 16 * called on the {@link Executor} passed to {@link CronetEngine#newUrlRequestBuilder}. 17 */ 18 public abstract class UrlRequest { 19 /** 20 * Builder for {@link UrlRequest}s. Allows configuring requests before constructing them with 21 * {@link Builder#build}. The builder can be created by calling {@link 22 * CronetEngine#newUrlRequestBuilder}. 23 */ 24 public abstract static class Builder { 25 /** 26 * Sets the HTTP method verb to use for this request. 27 * 28 * <p>The default when this method is not called is "GET" if the request has 29 * no body or "POST" if it does. 30 * 31 * @param method "GET", "HEAD", "DELETE", "POST" or "PUT". 32 * @return the builder to facilitate chaining. 33 */ setHttpMethod(String method)34 public abstract Builder setHttpMethod(String method); 35 36 /** 37 * Adds a request header. 38 * 39 * @param header header name. 40 * @param value header value. 41 * @return the builder to facilitate chaining. 42 */ addHeader(String header, String value)43 public abstract Builder addHeader(String header, String value); 44 45 /** 46 * Disables cache for the request. If context is not set up to use cache, this call has no 47 * effect. 48 * 49 * @return the builder to facilitate chaining. 50 */ disableCache()51 public abstract Builder disableCache(); 52 53 /** Lowest request priority. Passed to {@link #setPriority}. */ 54 public static final int REQUEST_PRIORITY_IDLE = 0; 55 56 /** Very low request priority. Passed to {@link #setPriority}. */ 57 public static final int REQUEST_PRIORITY_LOWEST = 1; 58 59 /** Low request priority. Passed to {@link #setPriority}. */ 60 public static final int REQUEST_PRIORITY_LOW = 2; 61 62 /** 63 * Medium request priority. Passed to {@link #setPriority}. This is the default priority 64 * given to the request. 65 */ 66 public static final int REQUEST_PRIORITY_MEDIUM = 3; 67 68 /** Highest request priority. Passed to {@link #setPriority}. */ 69 public static final int REQUEST_PRIORITY_HIGHEST = 4; 70 71 /** 72 * Sets priority of the request which should be one of the {@link #REQUEST_PRIORITY_IDLE 73 * REQUEST_PRIORITY_*} values. The request is given {@link #REQUEST_PRIORITY_MEDIUM} 74 * priority if this method is not called. 75 * 76 * @param priority priority of the request which should be one of the {@link 77 * #REQUEST_PRIORITY_IDLE REQUEST_PRIORITY_*} values. 78 * @return the builder to facilitate chaining. 79 */ setPriority(int priority)80 public abstract Builder setPriority(int priority); 81 82 /** 83 * Sets upload data provider. Switches method to "POST" if not explicitly set. Starting the 84 * request will throw an exception if a Content-Type header is not set. 85 * 86 * @param uploadDataProvider responsible for providing the upload data. 87 * @param executor All {@code uploadDataProvider} methods will be invoked using this {@code 88 * Executor}. May optionally be the same {@code Executor} the request itself is using. 89 * @return the builder to facilitate chaining. 90 */ setUploadDataProvider( UploadDataProvider uploadDataProvider, Executor executor)91 public abstract Builder setUploadDataProvider( 92 UploadDataProvider uploadDataProvider, Executor executor); 93 94 /** 95 * Marks that the executors this request will use to notify callbacks (for {@code 96 * UploadDataProvider}s and {@code UrlRequest.Callback}s) is intentionally performing inline 97 * execution, like Guava's directExecutor or {@link 98 * java.util.concurrent.ThreadPoolExecutor.CallerRunsPolicy}. 99 * 100 * <p><b>Warning:</b> This option makes it easy to accidentally block the network thread. 101 * It should not be used if your callbacks perform disk I/O, acquire locks, or call into 102 * other code you don't carefully control and audit. 103 */ allowDirectExecutor()104 public abstract Builder allowDirectExecutor(); 105 106 /** 107 * Associates the annotation object with this request. May add more than one. Passed through 108 * to a {@link RequestFinishedInfo.Listener}, see {@link 109 * RequestFinishedInfo#getAnnotations}. 110 * 111 * @param annotation an object to pass on to the {@link RequestFinishedInfo.Listener} with a 112 * {@link RequestFinishedInfo}. 113 * @return the builder to facilitate chaining. 114 */ addRequestAnnotation(Object annotation)115 public Builder addRequestAnnotation(Object annotation) { 116 return this; 117 } 118 119 /** 120 * Binds the request to the specified network handle. Cronet will send this request only 121 * using the network associated to this handle. If this network disconnects the request will 122 * fail, the exact error will depend on the stage of request processing when the network 123 * disconnects. Network handles can be obtained through {@code Network#getNetworkHandle}. 124 * Only available starting from Android Marshmallow. 125 * 126 * @param networkHandle the network handle to bind the request to. Specify {@link 127 * CronetEngine#UNBIND_NETWORK_HANDLE} to unbind. 128 * @return the builder to facilitate chaining. 129 */ bindToNetwork(long networkHandle)130 public Builder bindToNetwork(long networkHandle) { 131 return this; 132 } 133 134 /** 135 * Sets {@link android.net.TrafficStats} tag to use when accounting socket traffic caused by 136 * this request. See {@link android.net.TrafficStats} for more information. If no tag is set 137 * (e.g. this method isn't called), then Android accounts for the socket traffic caused by 138 * this request as if the tag value were set to 0. <p> <b>NOTE:</b>Setting a tag disallows 139 * sharing of sockets with requests with other tags, which may adversely effect performance 140 * by prohibiting connection sharing. In other words use of multiplexed sockets (e.g. HTTP/2 141 * and QUIC) will only be allowed if all requests have the same socket tag. 142 * 143 * @param tag the tag value used to when accounting for socket traffic caused by this 144 * request. 145 * Tags between 0xFFFFFF00 and 0xFFFFFFFF are reserved and used internally by system 146 * services like {@link android.app.DownloadManager} when performing traffic on behalf of an 147 * application. 148 * @return the builder to facilitate chaining. 149 */ setTrafficStatsTag(int tag)150 public Builder setTrafficStatsTag(int tag) { 151 return this; 152 } 153 154 /** 155 * Sets specific UID to use when accounting socket traffic caused by this request. See 156 * {@link android.net.TrafficStats} for more information. Designed for use when performing 157 * an operation on behalf of another application. Caller must hold {@code 158 * MODIFY_NETWORK_ACCOUNTING} permission. By default traffic is attributed to UID of caller. 159 * 160 * <p><b>NOTE:</b>Setting a UID disallows sharing of sockets with requests with other UIDs, 161 * which may adversely effect performance by prohibiting connection sharing. In other words 162 * use of multiplexed sockets (e.g. HTTP/2 and QUIC) will only be allowed if all requests 163 * have the same UID set. 164 * 165 * @param uid the UID to attribute socket traffic caused by this request. 166 * @return the builder to facilitate chaining. 167 */ setTrafficStatsUid(int uid)168 public Builder setTrafficStatsUid(int uid) { 169 return this; 170 } 171 172 /** 173 * Sets a listener that gets invoked after {@link Callback#onCanceled onCanceled()}, {@link 174 * Callback#onFailed onFailed()} or {@link Callback#onSucceeded onSucceeded()} return. 175 * 176 * <p>The listener is invoked with the request finished info on an 177 * {@link java.util.concurrent.Executor} provided by {@link 178 * RequestFinishedInfo.Listener#getExecutor getExecutor()}. 179 * 180 * @param listener the listener for finished requests. 181 * @return the builder to facilitate chaining. 182 */ setRequestFinishedListener(RequestFinishedInfo.Listener listener)183 public Builder setRequestFinishedListener(RequestFinishedInfo.Listener listener) { 184 return this; 185 } 186 187 /** 188 * Creates a {@link UrlRequest} using configuration within this {@link Builder}. The 189 * returned 190 * {@code UrlRequest} can then be started by calling {@link UrlRequest#start}. 191 * 192 * @return constructed {@link UrlRequest} using configuration within this {@link Builder}. 193 */ build()194 public abstract UrlRequest build(); 195 } 196 197 /** 198 * Users of Cronet extend this class to receive callbacks indicating the progress of a {@link 199 * UrlRequest} being processed. An instance of this class is passed in to {@link 200 * UrlRequest.Builder}'s constructor when constructing the {@code UrlRequest}. 201 * <p> 202 * Note: All methods will be invoked on the thread of the {@link java.util.concurrent.Executor} 203 * used during construction of the {@code UrlRequest}. 204 */ 205 public abstract static class Callback { 206 /** 207 * Invoked whenever a redirect is encountered. This will only be invoked between the call to 208 * {@link UrlRequest#start} and {@link Callback#onResponseStarted onResponseStarted()}. The 209 * body of the redirect response, if it has one, will be ignored. 210 * 211 * The redirect will not be followed until the URLRequest's {@link 212 * UrlRequest#followRedirect} method is called, either synchronously or asynchronously. 213 * 214 * @param request Request being redirected. 215 * @param info Response information. 216 * @param newLocationUrl Location where request is redirected. 217 * @throws Exception if an error occurs while processing a redirect. {@link #onFailed} will 218 * be 219 * called with the thrown exception set as the cause of the {@link CallbackException}. 220 */ onRedirectReceived( UrlRequest request, UrlResponseInfo info, String newLocationUrl)221 public abstract void onRedirectReceived( 222 UrlRequest request, UrlResponseInfo info, String newLocationUrl) throws Exception; 223 224 /** 225 * Invoked when the final set of headers, after all redirects, is received. Will only be 226 * invoked once for each request. 227 * 228 * With the exception of {@link Callback#onCanceled onCanceled()}, no other {@link Callback} 229 * method will be invoked for the request, including {@link Callback#onSucceeded 230 * onSucceeded()} and {@link Callback#onFailed onFailed()}, until {@link UrlRequest#read 231 * UrlRequest.read()} is called to attempt to start reading the response body. 232 * 233 * @param request Request that started to get response. 234 * @param info Response information. 235 * @throws Exception if an error occurs while processing response start. {@link #onFailed} 236 * will 237 * be called with the thrown exception set as the cause of the {@link CallbackException}. 238 */ onResponseStarted(UrlRequest request, UrlResponseInfo info)239 public abstract void onResponseStarted(UrlRequest request, UrlResponseInfo info) 240 throws Exception; 241 242 /** 243 * Invoked whenever part of the response body has been read. Only part of the buffer may be 244 * populated, even if the entire response body has not yet been consumed. 245 * 246 * With the exception of {@link Callback#onCanceled onCanceled()}, no other {@link Callback} 247 * method will be invoked for the request, including {@link Callback#onSucceeded 248 * onSucceeded()} and {@link Callback#onFailed onFailed()}, until {@link UrlRequest#read 249 * UrlRequest.read()} is called to attempt to continue reading the response body. 250 * 251 * @param request Request that received data. 252 * @param info Response information. 253 * @param byteBuffer The buffer that was passed in to {@link UrlRequest#read 254 * UrlRequest.read()}, 255 * now containing the received data. The buffer's position is updated to the end of the 256 * received data. The buffer's limit is not changed. 257 * @throws Exception if an error occurs while processing a read completion. {@link 258 * #onFailed} 259 * will be called with the thrown exception set as the cause of the {@link 260 * CallbackException}. 261 */ onReadCompleted( UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer)262 public abstract void onReadCompleted( 263 UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) throws Exception; 264 265 /** 266 * Invoked when request is completed successfully. Once invoked, no other {@link Callback} 267 * methods will be invoked. 268 * 269 * @param request Request that succeeded. 270 * @param info Response information. 271 */ onSucceeded(UrlRequest request, UrlResponseInfo info)272 public abstract void onSucceeded(UrlRequest request, UrlResponseInfo info); 273 274 /** 275 * Invoked if request failed for any reason after {@link UrlRequest#start}. Once invoked, no 276 * other {@link Callback} methods will be invoked. {@code error} provides information about 277 * the failure. 278 * 279 * @param request Request that failed. 280 * @param info Response information. May be {@code null} if no response was received. 281 * @param error information about error. 282 */ onFailed( UrlRequest request, UrlResponseInfo info, CronetException error)283 public abstract void onFailed( 284 UrlRequest request, UrlResponseInfo info, CronetException error); 285 286 /** 287 * Invoked if request was canceled via {@link UrlRequest#cancel}. Once invoked, no other 288 * {@link Callback} methods will be invoked. Default implementation takes no action. 289 * 290 * @param request Request that was canceled. 291 * @param info Response information. May be {@code null} if no response was received. 292 */ onCanceled(UrlRequest request, UrlResponseInfo info)293 public void onCanceled(UrlRequest request, UrlResponseInfo info) {} 294 } 295 296 /** Request status values returned by {@link #getStatus}. */ 297 public static class Status { 298 /** This state indicates that the request is completed, canceled, or is not started. */ 299 public static final int INVALID = -1; 300 301 /** 302 * This state corresponds to a resource load that has either not yet begun or is idle 303 * waiting for the consumer to do something to move things along (e.g. when the consumer of 304 * a {@link UrlRequest} has not called {@link UrlRequest#read read()} yet). 305 */ 306 public static final int IDLE = 0; 307 308 /** 309 * When a socket pool group is below the maximum number of sockets allowed per group, but a 310 * new socket cannot be created due to the per-pool socket limit, this state is returned by 311 * all requests for the group waiting on an idle connection, except those that may be 312 * serviced by a pending new connection. 313 */ 314 public static final int WAITING_FOR_STALLED_SOCKET_POOL = 1; 315 316 /** 317 * When a socket pool group has reached the maximum number of sockets allowed per group, 318 * this state is returned for all requests that don't have a socket, except those that 319 * correspond to a pending new connection. 320 */ 321 public static final int WAITING_FOR_AVAILABLE_SOCKET = 2; 322 323 /** 324 * This state indicates that the URLRequest delegate has chosen to block this request before 325 * it was sent over the network. 326 */ 327 public static final int WAITING_FOR_DELEGATE = 3; 328 329 /** 330 * This state corresponds to a resource load that is blocked waiting for access to a 331 * resource in the cache. If multiple requests are made for the same resource, the first 332 * request will be responsible for writing (or updating) the cache entry and the second 333 * request will be deferred until the first completes. This may be done to optimize for 334 * cache reuse. 335 */ 336 public static final int WAITING_FOR_CACHE = 4; 337 338 /** 339 * This state corresponds to a resource being blocked waiting for the PAC script to be 340 * downloaded. 341 */ 342 public static final int DOWNLOADING_PAC_FILE = 5; 343 344 /** 345 * This state corresponds to a resource load that is blocked waiting for a proxy autoconfig 346 * script to return a proxy server to use. 347 */ 348 public static final int RESOLVING_PROXY_FOR_URL = 6; 349 350 /** 351 * This state corresponds to a resource load that is blocked waiting for a proxy autoconfig 352 * script to return a proxy server to use, but that proxy script is busy resolving the IP 353 * address of a host. 354 */ 355 public static final int RESOLVING_HOST_IN_PAC_FILE = 7; 356 357 /** 358 * This state indicates that we're in the process of establishing a tunnel through the proxy 359 * server. 360 */ 361 public static final int ESTABLISHING_PROXY_TUNNEL = 8; 362 363 /** 364 * This state corresponds to a resource load that is blocked waiting for a host name to be 365 * resolved. This could either indicate resolution of the origin server corresponding to the 366 * resource or to the host name of a proxy server used to fetch the resource. 367 */ 368 public static final int RESOLVING_HOST = 9; 369 370 /** 371 * This state corresponds to a resource load that is blocked waiting for a TCP connection 372 * (or other network connection) to be established. HTTP requests that reuse a keep-alive 373 * connection skip this state. 374 */ 375 public static final int CONNECTING = 10; 376 377 /** 378 * This state corresponds to a resource load that is blocked waiting for the SSL handshake 379 * to complete. 380 */ 381 public static final int SSL_HANDSHAKE = 11; 382 383 /** 384 * This state corresponds to a resource load that is blocked waiting to completely upload a 385 * request to a server. In the case of a HTTP POST request, this state includes the period 386 * of time during which the message body is being uploaded. 387 */ 388 public static final int SENDING_REQUEST = 12; 389 390 /** 391 * This state corresponds to a resource load that is blocked waiting for the response to a 392 * network request. In the case of a HTTP transaction, this corresponds to the period after 393 * the request is sent and before all of the response headers have been received. 394 */ 395 public static final int WAITING_FOR_RESPONSE = 13; 396 397 /** 398 * This state corresponds to a resource load that is blocked waiting for a read to complete. 399 * In the case of a HTTP transaction, this corresponds to the period after the response 400 * headers have been received and before all of the response body has been downloaded. 401 * (NOTE: This state only applies for an {@link UrlRequest} while there is an outstanding 402 * {@link UrlRequest#read read()} operation.) 403 */ 404 public static final int READING_RESPONSE = 14; 405 Status()406 private Status() {} 407 } 408 409 /** Listener class used with {@link #getStatus} to receive the status of a {@link UrlRequest}. */ 410 public abstract static class StatusListener { 411 /** 412 * Invoked on {@link UrlRequest}'s {@link Executor}'s thread when request status is 413 * obtained. 414 * 415 * @param status integer representing the status of the request. It is one of the values 416 * defined 417 * in {@link Status}. 418 */ onStatus(int status)419 public abstract void onStatus(int status); 420 } 421 422 /** 423 * See {@link UrlRequest.Builder#setHttpMethod(String)}. 424 */ 425 @Nullable getHttpMethod()426 public abstract String getHttpMethod(); 427 428 /** 429 * See {@link UrlRequest.Builder#addHeader(String, String)} 430 */ 431 @NonNull getHeaders()432 public abstract UrlResponseInfo.HeaderBlock getHeaders(); 433 434 /** 435 * See {@link Builder#setCacheDisabled(boolean)} 436 */ isCacheDisabled()437 public abstract boolean isCacheDisabled(); 438 439 /** 440 * See {@link UrlRequest.Builder#setDirectExecutorAllowed(boolean)} 441 */ isDirectExecutorAllowed()442 public abstract boolean isDirectExecutorAllowed(); 443 444 /** 445 * See {@link Builder#setPriority(int)} 446 */ getPriority()447 public abstract int getPriority(); 448 449 /** 450 * See {@link Builder#setTrafficStatsTag(int)} 451 */ hasTrafficStatsTag()452 public abstract boolean hasTrafficStatsTag(); 453 454 /** 455 * See {@link Builder#setTrafficStatsTag(int)} 456 */ getTrafficStatsTag()457 public abstract int getTrafficStatsTag(); 458 459 /** 460 * See {@link Builder#setTrafficStatsUid(int)} 461 */ hasTrafficStatsUid()462 public abstract boolean hasTrafficStatsUid(); 463 464 /** 465 * See {@link Builder#setTrafficStatsUid(int)} 466 */ getTrafficStatsUid()467 public abstract int getTrafficStatsUid(); 468 469 /** 470 * Starts the request, all callbacks go to {@link Callback}. May only be called once. May not be 471 * called if {@link #cancel} has been called. 472 */ start()473 public abstract void start(); 474 475 /** 476 * Follows a pending redirect. Must only be called at most once for each invocation of {@link 477 * Callback#onRedirectReceived onRedirectReceived()}. 478 */ followRedirect()479 public abstract void followRedirect(); 480 481 /** 482 * Attempts to read part of the response body into the provided buffer. Must only be called at 483 * most once in response to each invocation of the {@link Callback#onResponseStarted 484 * onResponseStarted()} and {@link Callback#onReadCompleted onReadCompleted()} methods of the 485 * {@link Callback}. Each call will result in an asynchronous call to either the {@link Callback 486 * Callback's} {@link Callback#onReadCompleted onReadCompleted()} method if data is read, its 487 * {@link Callback#onSucceeded onSucceeded()} method if there's no more data to read, or its 488 * {@link Callback#onFailed onFailed()} method if there's an error. 489 * 490 * @param buffer {@link ByteBuffer} to write response body to. Must be a direct ByteBuffer. The 491 * embedder must not read or modify buffer's position, limit, or data between its position and 492 * limit until the request calls back into the {@link Callback}. 493 */ read(ByteBuffer buffer)494 public abstract void read(ByteBuffer buffer); 495 496 /** 497 * Cancels the request. Can be called at any time. {@link Callback#onCanceled onCanceled()} will 498 * be invoked when cancellation is complete and no further callback methods will be invoked. If 499 * the request has completed or has not started, calling {@code cancel()} has no effect and 500 * {@code onCanceled()} will not be invoked. If the {@link Executor} passed in during {@code 501 * UrlRequest} construction runs tasks on a single thread, and {@code cancel()} is called on 502 * that thread, no callback methods (besides {@code onCanceled()}) will be invoked after {@code 503 * cancel()} is called. Otherwise, at most one callback method may be invoked after {@code 504 * cancel()} has completed. 505 */ cancel()506 public abstract void cancel(); 507 508 /** 509 * Returns {@code true} if the request was successfully started and is now finished (completed, 510 * canceled, or failed). 511 * 512 * @return {@code true} if the request was successfully started and is now finished (completed, 513 * canceled, or failed). 514 */ isDone()515 public abstract boolean isDone(); 516 517 /** 518 * Queries the status of the request. 519 * 520 * @param listener a {@link StatusListener} that will be invoked with the request's current 521 * status. {@code listener} will be invoked back on the {@link Executor} passed in when the 522 * request was created. 523 */ getStatus(final StatusListener listener)524 public abstract void getStatus(final StatusListener listener); 525 526 // Note: There are deliberately no accessors for the results of the request 527 // here. Having none removes any ambiguity over when they are populated, 528 // particularly in the redirect case. 529 } 530