// Copyright Vespa.ai. Licensed under the terms of the Apache 2.0 license. See LICENSE in the project root. package com.yahoo.jdisc.http.server.jetty; import com.yahoo.jdisc.application.BindingRepository; import com.yahoo.jdisc.application.BindingSet; import com.yahoo.jdisc.http.filter.RequestFilter; import com.yahoo.jdisc.http.filter.ResponseFilter; import java.net.URI; import java.util.Collection; import java.util.Collections; import java.util.Map; import java.util.Optional; import java.util.TreeMap; /** * Resolves request/response filter (chain) from a {@link URI} instance. * * @author Oyvind Bakksjo * @author bjorncs */ public class FilterBindings { private final Map requestFilters; private final Map responseFilters; private final Map defaultRequestFilters; private final Map defaultResponseFilters; private final BindingSet requestFilterBindings; private final BindingSet responseFilterBindings; private final boolean strictFiltering; private FilterBindings( Map requestFilters, Map responseFilters, Map defaultRequestFilters, Map defaultResponseFilters, BindingSet requestFilterBindings, BindingSet responseFilterBindings, boolean strictFiltering) { this.requestFilters = requestFilters; this.responseFilters = responseFilters; this.defaultRequestFilters = defaultRequestFilters; this.defaultResponseFilters = defaultResponseFilters; this.requestFilterBindings = requestFilterBindings; this.responseFilterBindings = responseFilterBindings; this.strictFiltering = strictFiltering; } public Optional resolveRequestFilter(URI uri, int localPort) { String filterId = requestFilterBindings.resolve(uri); if (filterId != null) return Optional.of(filterId); return Optional.ofNullable(defaultRequestFilters.get(localPort)); } public Optional resolveResponseFilter(URI uri, int localPort) { String filterId = responseFilterBindings.resolve(uri); if (filterId != null) return Optional.of(filterId); return Optional.ofNullable(defaultResponseFilters.get(localPort)); } public RequestFilter getRequestFilter(String filterId) { return requestFilters.get(filterId); } public ResponseFilter getResponseFilter(String filterId) { return responseFilters.get(filterId); } public Collection requestFilterIds() { return requestFilters.keySet(); } public Collection responseFilterIds() { return responseFilters.keySet(); } public Collection requestFilters() { return requestFilters.values(); } public Collection responseFilters() { return responseFilters.values(); } public boolean strictFiltering() { return strictFiltering; } public static class Builder { private final Map requestFilters = new TreeMap<>(); private final Map responseFilters = new TreeMap<>(); private final Map defaultRequestFilters = new TreeMap<>(); private final Map defaultResponseFilters = new TreeMap<>(); private final BindingRepository requestFilterBindings = new BindingRepository<>(); private final BindingRepository responseFilterBindings = new BindingRepository<>(); private boolean strictFiltering = false; public Builder() {} public Builder addRequestFilter(String id, RequestFilter filter) { requestFilters.put(id, filter); return this; } public Builder addResponseFilter(String id, ResponseFilter filter) { responseFilters.put(id, filter); return this; } public Builder addRequestFilterBinding(String id, String binding) { requestFilterBindings.bind(binding, id); return this; } public Builder addResponseFilterBinding(String id, String binding) { responseFilterBindings.bind(binding, id); return this; } public Builder setRequestFilterDefaultForPort(String id, int port) { defaultRequestFilters.put(port, id); return this; } public Builder setResponseFilterDefaultForPort(String id, int port) { defaultResponseFilters.put(port, id); return this; } public Builder setStrictFiltering(boolean strictFiltering) { this.strictFiltering = strictFiltering; return this; } public FilterBindings build() { return new FilterBindings( Collections.unmodifiableMap(requestFilters), Collections.unmodifiableMap(responseFilters), Collections.unmodifiableMap(defaultRequestFilters), Collections.unmodifiableMap(defaultResponseFilters), requestFilterBindings.activate(), responseFilterBindings.activate(), strictFiltering); } } }