1   
2   
3   
4   
5   
6   
7   
8   
9   
10  
11  
12  
13  
14  
15  
16  
17  
18  
19  package org.eclipse.aether.util.repository;
20  
21  import java.util.ArrayList;
22  import java.util.HashMap;
23  import java.util.List;
24  import java.util.Locale;
25  import java.util.Map;
26  import java.util.StringTokenizer;
27  import java.util.regex.Pattern;
28  
29  import org.eclipse.aether.repository.Proxy;
30  import org.eclipse.aether.repository.ProxySelector;
31  import org.eclipse.aether.repository.RemoteRepository;
32  
33  import static java.util.Objects.requireNonNull;
34  
35  
36  
37  
38  public final class DefaultProxySelector implements ProxySelector {
39  
40      private final List<ProxyDef> proxies = new ArrayList<>();
41  
42      
43  
44  
45  
46  
47  
48  
49  
50      public DefaultProxySelector add(Proxy proxy, String nonProxyHosts) {
51          requireNonNull(proxy, "proxy cannot be null");
52          proxies.add(new ProxyDef(proxy, nonProxyHosts));
53  
54          return this;
55      }
56  
57      public Proxy getProxy(RemoteRepository repository) {
58          requireNonNull(repository, "repository cannot be null");
59          Map<String, ProxyDef> candidates = new HashMap<>();
60  
61          String host = repository.getHost();
62          for (ProxyDef proxy : proxies) {
63              if (!proxy.nonProxyHosts.isNonProxyHost(host)) {
64                  String key = proxy.proxy.getType().toLowerCase(Locale.ENGLISH);
65                  if (!candidates.containsKey(key)) {
66                      candidates.put(key, proxy);
67                  }
68              }
69          }
70  
71          String protocol = repository.getProtocol().toLowerCase(Locale.ENGLISH);
72  
73          if ("davs".equals(protocol)) {
74              protocol = "https";
75          } else if ("dav".equals(protocol)) {
76              protocol = "http";
77          } else if (protocol.startsWith("dav:")) {
78              protocol = protocol.substring("dav:".length());
79          }
80  
81          ProxyDef proxy = candidates.get(protocol);
82          if (proxy == null && "https".equals(protocol)) {
83              proxy = candidates.get("http");
84          }
85  
86          return (proxy != null) ? proxy.proxy : null;
87      }
88  
89      static class NonProxyHosts {
90  
91          private final Pattern[] patterns;
92  
93          NonProxyHosts(String nonProxyHosts) {
94              List<Pattern> patterns = new ArrayList<>();
95              if (nonProxyHosts != null) {
96                  for (StringTokenizer tokenizer = new StringTokenizer(nonProxyHosts, "|"); tokenizer.hasMoreTokens(); ) {
97                      String pattern = tokenizer.nextToken();
98                      pattern = pattern.replace(".", "\\.").replace("*", ".*");
99                      patterns.add(Pattern.compile(pattern, Pattern.CASE_INSENSITIVE));
100                 }
101             }
102             this.patterns = patterns.toArray(new Pattern[0]);
103         }
104 
105         boolean isNonProxyHost(String host) {
106             if (host != null) {
107                 for (Pattern pattern : patterns) {
108                     if (pattern.matcher(host).matches()) {
109                         return true;
110                     }
111                 }
112             }
113             return false;
114         }
115     }
116 
117     static class ProxyDef {
118 
119         final Proxy proxy;
120 
121         final NonProxyHosts nonProxyHosts;
122 
123         ProxyDef(Proxy proxy, String nonProxyHosts) {
124             this.proxy = proxy;
125             this.nonProxyHosts = new NonProxyHosts(nonProxyHosts);
126         }
127     }
128 }