tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

WebRequest.java (8154B)


      1 /* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*-
      2 * vim: ts=4 sw=4 expandtab:
      3 * This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 package org.mozilla.geckoview;
      8 
      9 import androidx.annotation.AnyThread;
     10 import androidx.annotation.IntDef;
     11 import androidx.annotation.NonNull;
     12 import androidx.annotation.Nullable;
     13 import java.lang.annotation.Retention;
     14 import java.lang.annotation.RetentionPolicy;
     15 import java.nio.ByteBuffer;
     16 import java.nio.CharBuffer;
     17 import java.nio.charset.Charset;
     18 import org.mozilla.gecko.annotation.WrapForJNI;
     19 
     20 /**
     21 * WebRequest represents an HTTP[S] request. The typical pattern is to create instances of this
     22 * class via {@link WebRequest.Builder}, and fetch responses via {@link
     23 * GeckoWebExecutor#fetch(WebRequest)}.
     24 */
     25 @WrapForJNI
     26 @AnyThread
     27 public class WebRequest extends WebMessage {
     28  /** The HTTP method for the request. Defaults to "GET". */
     29  public final @NonNull String method;
     30 
     31  /** The body of the request. Must be a directly-allocated ByteBuffer. May be null. */
     32  public final @Nullable ByteBuffer body;
     33 
     34  /**
     35   * The cache mode for the request. See {@link #CACHE_MODE_DEFAULT}. These modes match those from
     36   * the DOM Fetch API.
     37   *
     38   * @see <a href="https://developer.mozilla.org/en-US/docs/Web/API/Request/cache">DOM Fetch API
     39   *     cache modes</a>
     40   */
     41  public final @CacheMode int cacheMode;
     42 
     43  /**
     44   * If true, do not use newer protocol features that might have interop problems on the Internet.
     45   * Intended only for use with critical infrastructure.
     46   */
     47  public final boolean beConservative;
     48 
     49  /** The value of the Referer header for this request. */
     50  public final @Nullable String referrer;
     51 
     52  /** The value of the origin of this request. */
     53  public final @Nullable String origin;
     54 
     55  /** Cache mode definitions for web requests. */
     56  @Retention(RetentionPolicy.SOURCE)
     57  @IntDef({
     58    CACHE_MODE_DEFAULT,
     59    CACHE_MODE_NO_STORE,
     60    CACHE_MODE_RELOAD,
     61    CACHE_MODE_NO_CACHE,
     62    CACHE_MODE_FORCE_CACHE,
     63    CACHE_MODE_ONLY_IF_CACHED
     64  })
     65  public @interface CacheMode {};
     66 
     67  /** Default cache mode. Normal caching rules apply. */
     68  public static final int CACHE_MODE_DEFAULT = 1;
     69 
     70  /**
     71   * The response will be fetched from the server without looking in the cache, and will not update
     72   * the cache with the downloaded response.
     73   */
     74  public static final int CACHE_MODE_NO_STORE = 2;
     75 
     76  /**
     77   * The response will be fetched from the server without looking in the cache. The cache will be
     78   * updated with the downloaded response.
     79   */
     80  public static final int CACHE_MODE_RELOAD = 3;
     81 
     82  /** Forces a conditional request to the server if there is a cache match. */
     83  public static final int CACHE_MODE_NO_CACHE = 4;
     84 
     85  /**
     86   * If a response is found in the cache, it will be returned, whether it's fresh or not. If there
     87   * is no match, a normal request will be made and the cache will be updated with the downloaded
     88   * response.
     89   */
     90  public static final int CACHE_MODE_FORCE_CACHE = 5;
     91 
     92  /**
     93   * If a response is found in the cache, it will be returned, whether it's fresh or not. If there
     94   * is no match from the cache, 504 Gateway Timeout will be returned.
     95   */
     96  public static final int CACHE_MODE_ONLY_IF_CACHED = 6;
     97 
     98  /* package */ static final int CACHE_MODE_FIRST = CACHE_MODE_DEFAULT;
     99  /* package */ static final int CACHE_MODE_LAST = CACHE_MODE_ONLY_IF_CACHED;
    100 
    101  /**
    102   * Constructs a WebRequest with the specified URI.
    103   *
    104   * @param uri A URI String, e.g. https://mozilla.org
    105   */
    106  public WebRequest(final @NonNull String uri) {
    107    this(new Builder(uri));
    108  }
    109 
    110  /** Constructs a new WebRequest from a {@link WebRequest.Builder}. */
    111  /* package */ WebRequest(final @NonNull Builder builder) {
    112    super(builder);
    113    method = builder.mMethod;
    114    cacheMode = builder.mCacheMode;
    115    referrer = builder.mReferrer;
    116    beConservative = builder.mBeConservative;
    117    origin = builder.mOrigin;
    118 
    119    if (builder.mBody != null) {
    120      body = builder.mBody.asReadOnlyBuffer();
    121    } else {
    122      body = null;
    123    }
    124  }
    125 
    126  /** Builder offers a convenient way for constructing {@link WebRequest} instances. */
    127  @WrapForJNI
    128  @AnyThread
    129  public static class Builder extends WebMessage.Builder {
    130    /* package */ String mMethod = "GET";
    131    /* package */ int mCacheMode = CACHE_MODE_DEFAULT;
    132    /* package */ String mReferrer;
    133    /* package */ boolean mBeConservative;
    134    /* package */ String mOrigin;
    135 
    136    /**
    137     * Construct a Builder instance with the specified URI.
    138     *
    139     * @param uri A URI String.
    140     */
    141    public Builder(final @NonNull String uri) {
    142      super(uri);
    143    }
    144 
    145    @Override
    146    public @NonNull Builder uri(final @NonNull String uri) {
    147      super.uri(uri);
    148      return this;
    149    }
    150 
    151    @Override
    152    public @NonNull Builder header(final @NonNull String key, final @NonNull String value) {
    153      super.header(key, value);
    154      return this;
    155    }
    156 
    157    @Override
    158    public @NonNull Builder addHeader(final @NonNull String key, final @NonNull String value) {
    159      super.addHeader(key, value);
    160      return this;
    161    }
    162 
    163    /**
    164     * Set the body.
    165     *
    166     * @param buffer A {@link ByteBuffer} with the data. Must be allocated directly via {@link
    167     *     ByteBuffer#allocateDirect(int)}.
    168     * @return This Builder instance.
    169     */
    170    public @NonNull Builder body(final @Nullable ByteBuffer buffer) {
    171      if (buffer != null && !buffer.isDirect()) {
    172        throw new IllegalArgumentException("body must be directly allocated");
    173      }
    174      mBody = buffer;
    175      return this;
    176    }
    177 
    178    /**
    179     * Set the body.
    180     *
    181     * @param bodyString A {@link String} with the data.
    182     * @return This Builder instance.
    183     */
    184    public @NonNull Builder body(final @Nullable String bodyString) {
    185      if (bodyString == null) {
    186        mBody = null;
    187        return this;
    188      }
    189      final CharBuffer chars = CharBuffer.wrap(bodyString);
    190      final ByteBuffer buffer = ByteBuffer.allocateDirect(bodyString.length());
    191      Charset.forName("UTF-8").newEncoder().encode(chars, buffer, true);
    192 
    193      mBody = buffer;
    194      return this;
    195    }
    196 
    197    /**
    198     * Set the HTTP method.
    199     *
    200     * @param method The HTTP method String.
    201     * @return This Builder instance.
    202     */
    203    public @NonNull Builder method(final @NonNull String method) {
    204      mMethod = method;
    205      return this;
    206    }
    207 
    208    /**
    209     * Set the cache mode.
    210     *
    211     * @param mode One of the {@link #CACHE_MODE_DEFAULT CACHE_*} flags.
    212     * @return This Builder instance.
    213     */
    214    public @NonNull Builder cacheMode(final @CacheMode int mode) {
    215      if (mode < CACHE_MODE_FIRST || mode > CACHE_MODE_LAST) {
    216        throw new IllegalArgumentException("Unknown cache mode");
    217      }
    218      mCacheMode = mode;
    219      return this;
    220    }
    221 
    222    /**
    223     * Set the HTTP Referer header.
    224     *
    225     * @param referrer A URI String
    226     * @return This Builder instance.
    227     */
    228    public @NonNull Builder referrer(final @Nullable String referrer) {
    229      mReferrer = referrer;
    230      return this;
    231    }
    232 
    233    /**
    234     * Set the beConservative property.
    235     *
    236     * @param beConservative If true, do not use newer protocol features that might have interop
    237     *     problems on the Internet. Intended only for use with critical infrastructure.
    238     * @return This Builder instance.
    239     */
    240    public @NonNull Builder beConservative(final boolean beConservative) {
    241      mBeConservative = beConservative;
    242      return this;
    243    }
    244 
    245    /**
    246     * Set the origin URI.
    247     *
    248     * @param origin A URI String
    249     * @return This Builder instance.
    250     */
    251    public @NonNull Builder origin(final @Nullable String origin) {
    252      mOrigin = origin;
    253      return this;
    254    }
    255 
    256    /**
    257     * @return A {@link WebRequest} constructed with the values from this Builder instance.
    258     */
    259    public @NonNull WebRequest build() {
    260      if (mUri == null) {
    261        throw new IllegalStateException("Must set URI");
    262      }
    263      return new WebRequest(this);
    264    }
    265  }
    266 }