1 /* 2 * Copyright 2024 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package androidx.webkit; 18 19 import org.jspecify.annotations.NonNull; 20 21 import java.util.ArrayList; 22 import java.util.List; 23 24 /** 25 * The No-Vary-Search header specifies a set of rules that define how a URL's 26 * query parameters will affect cache matching. These rules dictate whether 27 * the same URL with different URL parameters should be saved as separate 28 * browser cache entries. 29 * <p> 30 * See 31 * <a href="https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/No-Vary-Search">Doc here</a> 32 * to learn more about No-Vary-Search. 33 */ 34 @Profile.ExperimentalUrlPrefetch 35 public class NoVarySearchHeader { 36 37 /** 38 * If {@code true} this indicates that differences in the order of 39 * parameters between otherwise identical URLs will cause them to 40 * be cached as separate entries. 41 * <p> 42 * However, differences in the parameters present will cause them to 43 * be cached separately regardless of this flag's value. 44 * <p> 45 * To ignore any differences in parameters present for caching 46 * see {@link #ignoreDifferencesInParameters} 47 * and {@link #ignoredQueryParameters}. {@code false} otherwise. 48 */ 49 public final boolean varyOnKeyOrder; 50 51 /** 52 * A {@code true} to indicate the differences in parameters present 53 * between otherwise identical URLs will not cause them to be cached as 54 * separate entries. {@code false} otherwise. 55 */ 56 public final boolean ignoreDifferencesInParameters; 57 58 /** 59 * A {@link List} of parameters that if present, 60 * will not cause otherwise identical URLs to be cached as separate 61 * entries. Any parameters present in the URLs that are not included in 62 * this list will affect cache matching. 63 * <p> 64 * This list is irrelevant and not used if 65 * {@link #ignoreDifferencesInParameters} is {@code true}. 66 */ 67 public final @NonNull List<String> ignoredQueryParameters; 68 69 /** 70 * A {@link List} of parameters that if present, will cause otherwise 71 * identical URLs to be cached as separate entries. Any parameters present 72 * in the URLs that are not included in this list will not affect cache 73 * matching. 74 * <p> 75 * This list is irrelevant and not used if 76 * {@link #ignoreDifferencesInParameters} is {@code false}. 77 */ 78 public final @NonNull List<String> consideredQueryParameters; 79 80 /** 81 * Private constructor to prevent constructing invalid No-Vary-Search 82 * header. Static methods should be used instead e.g. {@link #neverVaryHeader}. 83 */ NoVarySearchHeader(boolean varyOnKeyOrder, boolean ignoreDifferencesInParameters, @NonNull List<String> ignoredQueryParameters, @NonNull List<String> consideredQueryParameters)84 private NoVarySearchHeader(boolean varyOnKeyOrder, 85 boolean ignoreDifferencesInParameters, 86 @NonNull List<String> ignoredQueryParameters, 87 @NonNull List<String> consideredQueryParameters) { 88 this.varyOnKeyOrder = varyOnKeyOrder; 89 this.ignoreDifferencesInParameters = ignoreDifferencesInParameters; 90 this.ignoredQueryParameters = ignoredQueryParameters; 91 this.consideredQueryParameters = consideredQueryParameters; 92 } 93 94 95 /** 96 * Returns No-Vary-Search header that doesn't consider any differences in 97 * query parameters (i.e. presence or ordering) between otherwise 98 * identical URLs in cache matching. 99 */ 100 @Profile.ExperimentalUrlPrefetch neverVaryHeader()101 public static @NonNull NoVarySearchHeader neverVaryHeader() { 102 return new NoVarySearchHeader(false, true, new ArrayList<>(), new ArrayList<>()); 103 } 104 105 /** 106 * Returns No-Vary-Search header that considers all differences in 107 * query parameters (i.e. presence and ordering) between otherwise 108 * identical URLs in cache matching. 109 */ 110 @Profile.ExperimentalUrlPrefetch alwaysVaryHeader()111 public static @NonNull NoVarySearchHeader alwaysVaryHeader() { 112 return new NoVarySearchHeader(true, false, new ArrayList<>(), new ArrayList<>()); 113 } 114 115 /** 116 * Returns No-Vary-Search header that doesn't consider differences in 117 * in query parameters present between otherwise identical URLs 118 * in cache matching with the exception of the ones provided 119 * in {@link #consideredQueryParameters}. 120 * <p> 121 * 122 * @param varyOnOrdering true if the ordering of query parameters should be 123 * considered in cache matching, false otherwise. 124 * @param consideredQueryParameters the query parameters to consider 125 * in cache matching. 126 */ 127 @Profile.ExperimentalUrlPrefetch neverVaryExcept( boolean varyOnOrdering, @NonNull List<String> consideredQueryParameters)128 public static @NonNull NoVarySearchHeader neverVaryExcept( 129 boolean varyOnOrdering, 130 @NonNull List<String> consideredQueryParameters) { 131 return new NoVarySearchHeader(varyOnOrdering, true, new ArrayList<>(), 132 consideredQueryParameters); 133 } 134 135 /** 136 * Returns No-Vary-Search header that considers differences in 137 * in query parameters present between otherwise identical URLs 138 * in cache matching with the exception of the ones provided 139 * in {@link #ignoredQueryParameters}. 140 * <p> 141 * 142 * @param varyOnOrdering true if the ordering of query parameters should be 143 * considered in cache matching, false otherwise. 144 * @param ignoredQueryParameters the query parameters to ignore 145 * in cache matching. 146 */ 147 @Profile.ExperimentalUrlPrefetch varyExcept( boolean varyOnOrdering, @NonNull List<String> ignoredQueryParameters)148 public static @NonNull NoVarySearchHeader varyExcept( 149 boolean varyOnOrdering, 150 @NonNull List<String> ignoredQueryParameters) { 151 return new NoVarySearchHeader(varyOnOrdering, false, 152 ignoredQueryParameters, new ArrayList<>()); 153 } 154 155 } 156