diff options
Diffstat (limited to 'mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebMessage.java')
-rw-r--r-- | mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebMessage.java | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebMessage.java b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebMessage.java new file mode 100644 index 0000000000..520cb9faa0 --- /dev/null +++ b/mobile/android/geckoview/src/main/java/org/mozilla/geckoview/WebMessage.java @@ -0,0 +1,117 @@ +/* -*- Mode: Java; c-basic-offset: 4; tab-width: 20; indent-tabs-mode: nil; -*- + * vim: ts=4 sw=4 expandtab: + * This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +package org.mozilla.geckoview; + +import androidx.annotation.AnyThread; +import androidx.annotation.NonNull; +import java.nio.ByteBuffer; +import java.util.Collections; +import java.util.Map; +import java.util.TreeMap; +import org.mozilla.gecko.annotation.WrapForJNI; + +/** This is an abstract base class for HTTP request and response types. */ +@WrapForJNI +@AnyThread +public abstract class WebMessage { + + /** The URI for the request or response. */ + public final @NonNull String uri; + + /** An unmodifiable Map of headers. Defaults to an empty instance. */ + public final @NonNull Map<String, String> headers; + + protected WebMessage(final @NonNull Builder builder) { + uri = builder.mUri; + headers = Collections.unmodifiableMap(builder.mHeaders); + } + + // This is only used via JNI. + private String[] getHeaderKeys() { + final String[] keys = new String[headers.size()]; + headers.keySet().toArray(keys); + return keys; + } + + // This is only used via JNI. + private String[] getHeaderValues() { + final String[] values = new String[headers.size()]; + headers.values().toArray(values); + return values; + } + + /** This is a Builder used by subclasses of {@link WebMessage}. */ + @AnyThread + public abstract static class Builder { + /* package */ String mUri; + /* package */ Map<String, String> mHeaders = new TreeMap<>(String.CASE_INSENSITIVE_ORDER); + /* package */ ByteBuffer mBody; + + /** + * Construct a Builder instance with the specified URI. + * + * @param uri A URI String. + */ + /* package */ Builder(final @NonNull String uri) { + uri(uri); + } + + /** + * Set the URI + * + * @param uri A URI String + * @return This Builder instance. + */ + public @NonNull Builder uri(final @NonNull String uri) { + mUri = uri; + return this; + } + + /** + * Set a HTTP header. This may be called multiple times for additional headers. If an existing + * header of the same name exists, it will be replaced by this value. + * + * <p>Please note that the HTTP header keys are case-insensitive. It means you can retrieve + * "Content-Type" with map.get("content-type"), and value for "Content-Type" will be overwritten + * by map.put("cONTENt-TYpe", value); The keys are also sorted in natural order. + * + * @param key The key for the HTTP header, e.g. "content-type". + * @param value The value for the HTTP header, e.g. "application/json". + * @return This Builder instance. + */ + public @NonNull Builder header(final @NonNull String key, final @NonNull String value) { + mHeaders.put(key, value); + return this; + } + + /** + * Add a HTTP header. This may be called multiple times for additional headers. If an existing + * header of the same name exists, the values will be merged. + * + * <p>Please note that the HTTP header keys are case-insensitive. It means you can retrieve + * "Content-Type" with map.get("content-type"), and value for "Content-Type" will be overwritten + * by map.put("cONTENt-TYpe", value); The keys are also sorted in natural order. + * + * @param key The key for the HTTP header, e.g. "content-type". + * @param value The value for the HTTP header, e.g. "application/json". + * @return This Builder instance. + */ + public @NonNull Builder addHeader(final @NonNull String key, final @NonNull String value) { + final String existingValue = mHeaders.get(key); + if (existingValue != null) { + final StringBuilder builder = new StringBuilder(existingValue); + builder.append(", "); + builder.append(value); + mHeaders.put(key, builder.toString()); + } else { + mHeaders.put(key, value); + } + + return this; + } + } +} |