package io.dropwizard.client.proxy;

import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import org.apache.http.HttpException;
import org.apache.http.HttpHost;
import org.apache.http.HttpRequest;
import org.apache.http.conn.SchemePortResolver;
import org.apache.http.impl.conn.DefaultProxyRoutePlanner;
import org.apache.http.protocol.HttpContext;

import javax.annotation.Nullable;
import java.util.List;
import java.util.regex.Pattern;

Implementation of HttpRoutePlanner that routes requests through proxy and takes into account list of hosts that should not be proxied
/** * Implementation of {@link org.apache.http.conn.routing.HttpRoutePlanner} * that routes requests through proxy and takes into account list of hosts that should not be proxied */
public class NonProxyListProxyRoutePlanner extends DefaultProxyRoutePlanner { private static final Pattern WILDCARD = Pattern.compile("\\*"); private static final String REGEX_WILDCARD = ".*"; private List<Pattern> nonProxyHostPatterns; public NonProxyListProxyRoutePlanner(HttpHost proxy, @Nullable List<String> nonProxyHosts) { super(proxy, null); nonProxyHostPatterns = getNonProxyHostPatterns(nonProxyHosts); } public NonProxyListProxyRoutePlanner(HttpHost proxy, SchemePortResolver schemePortResolver, @Nullable List<String> nonProxyHosts) { super(proxy, schemePortResolver); this.nonProxyHostPatterns = getNonProxyHostPatterns(nonProxyHosts); } private List<Pattern> getNonProxyHostPatterns(@Nullable List<String> nonProxyHosts) { if (nonProxyHosts == null) { return ImmutableList.of(); } final ImmutableList.Builder<Pattern> patterns = ImmutableList.builder(); for (String nonProxyHost : nonProxyHosts) { // Replaces a wildcard to a regular expression patterns.add(Pattern.compile(WILDCARD.matcher(nonProxyHost).replaceAll(REGEX_WILDCARD))); } return patterns.build(); } @VisibleForTesting protected List<Pattern> getNonProxyHostPatterns() { return nonProxyHostPatterns; } @Override @Nullable protected HttpHost determineProxy(HttpHost target, HttpRequest request, HttpContext context) throws HttpException { for (Pattern nonProxyHostPattern : nonProxyHostPatterns) { if (nonProxyHostPattern.matcher(target.getHostName()).matches()) { return null; } } return super.determineProxy(target, request, context); } }