• 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 org.chromium.net.apihelpers;
6 
7 import androidx.annotation.Nullable;
8 
9 import org.chromium.net.CallbackException;
10 import org.chromium.net.CronetException;
11 import org.chromium.net.UrlRequest;
12 import org.chromium.net.UrlResponseInfo;
13 
14 import java.nio.ByteBuffer;
15 
16 /**
17  * An implementation of {@link UrlRequest.Callback} that takes away the difficulty of managing the
18  * request lifecycle away, and automatically proceeds to read the response entirely.
19  */
20 public abstract class ImplicitFlowControlCallback extends UrlRequest.Callback {
21     private static final int BYTE_BUFFER_CAPACITY = 32 * 1024;
22 
23     /**
24      * Invoked whenever a redirect is encountered. This will only be invoked between the call to
25      * {@link UrlRequest#start} and {@link UrlRequest.Callback#onResponseStarted
26      * onResponseStarted()}. The body of the redirect response, if it has one, will be ignored.
27      *
28      * @param info Response information.
29      * @param newLocationUrl Location where request is redirected.
30      * @return true if the redirect should be followed, false if the request should be canceled.
31      * @throws Exception if an error occurs while processing a redirect. {@link #onFailed} will be
32      * called with the thrown exception set as the cause of the {@link CallbackException}.
33      */
shouldFollowRedirect(UrlResponseInfo info, String newLocationUrl)34     protected abstract boolean shouldFollowRedirect(UrlResponseInfo info, String newLocationUrl)
35             throws Exception;
36 
37     /**
38      * Invoked when the final set of headers, after all redirects, is received. Will only be invoked
39      * once for each request. It's guaranteed that Cronet doesn't start reading the body until this
40      * method returns.
41      *
42      * @param info Response information.
43      * @throws Exception if an error occurs while processing response start. {@link #onFailed} will
44      *         be
45      * called with the thrown exception set as the cause of the {@link CallbackException}.
46      */
onResponseStarted(UrlResponseInfo info)47     protected abstract void onResponseStarted(UrlResponseInfo info) throws Exception;
48 
49     /**
50      * Invoked whenever part of the response body has been read. Only part of the buffer may be
51      * populated, even if the entire response body has not yet been consumed. The buffer is ready
52      * for reading. Buffers are reused internally so the implementing class shouldn't store the
53      * buffer or use it anywhere else than in the implementation of this method.
54      *
55      * @param info Response information.
56      * @param bodyChunk The buffer that contains the received data, flipped for reading.
57      * @throws Exception if an error occurs while processing a read completion. {@link #onFailed}
58      *         will
59      * be called with the thrown exception set as the cause of the {@link CallbackException}.
60      */
onBodyChunkRead(UrlResponseInfo info, ByteBuffer bodyChunk)61     protected abstract void onBodyChunkRead(UrlResponseInfo info, ByteBuffer bodyChunk)
62             throws Exception;
63 
64     /**
65      * Invoked when request is completed successfully. Once invoked, no other {@link
66      * UrlRequest.Callback} methods will be invoked.
67      *
68      * @param info Response information.
69      */
onSucceeded(UrlResponseInfo info)70     protected abstract void onSucceeded(UrlResponseInfo info);
71 
72     /**
73      * Invoked if request failed for any reason after {@link UrlRequest#start}. Once invoked, no
74      * other
75      * {@link UrlRequest.Callback} methods will be invoked. {@code error} provides information about
76      * the failure.
77      *
78      * @param info Response information. May be {@code null} if no response was received.
79      * @param exception information about error.
80      */
onFailed(@ullable UrlResponseInfo info, CronetException exception)81     protected abstract void onFailed(@Nullable UrlResponseInfo info, CronetException exception);
82 
83     /**
84      * Invoked if request was canceled via {@link UrlRequest#cancel}. Once invoked, no other {@link
85      * UrlRequest.Callback} methods will be invoked.
86      *
87      * @param info Response information. May be {@code null} if no response was received.
88      */
onCanceled(@ullable UrlResponseInfo info)89     protected abstract void onCanceled(@Nullable UrlResponseInfo info);
90 
91     @Override
onResponseStarted(UrlRequest request, UrlResponseInfo info)92     public final void onResponseStarted(UrlRequest request, UrlResponseInfo info) throws Exception {
93         onResponseStarted(info);
94         request.read(ByteBuffer.allocateDirect(BYTE_BUFFER_CAPACITY));
95     }
96 
97     @Override
onRedirectReceived( UrlRequest request, UrlResponseInfo info, String newLocationUrl)98     public final void onRedirectReceived(
99             UrlRequest request, UrlResponseInfo info, String newLocationUrl) throws Exception {
100         if (shouldFollowRedirect(info, newLocationUrl)) {
101             request.followRedirect();
102         } else {
103             request.cancel();
104         }
105     }
106 
107     @Override
onReadCompleted( UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer)108     public final void onReadCompleted(
109             UrlRequest request, UrlResponseInfo info, ByteBuffer byteBuffer) throws Exception {
110         byteBuffer.flip();
111         onBodyChunkRead(info, byteBuffer);
112         byteBuffer.clear();
113         request.read(byteBuffer);
114     }
115 
116     @Override
onSucceeded(UrlRequest request, UrlResponseInfo info)117     public final void onSucceeded(UrlRequest request, UrlResponseInfo info) {
118         onSucceeded(info);
119     }
120 
121     @Override
onFailed(UrlRequest request, UrlResponseInfo info, CronetException error)122     public final void onFailed(UrlRequest request, UrlResponseInfo info, CronetException error) {
123         onFailed(info, error);
124     }
125 
126     @Override
onCanceled(UrlRequest request, UrlResponseInfo info)127     public final void onCanceled(UrlRequest request, UrlResponseInfo info) {
128         onCanceled(info);
129     }
130 }
131