View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.client;
20  
21  import java.net.URI;
22  import java.util.ArrayList;
23  import java.util.HashSet;
24  import java.util.List;
25  import java.util.Set;
26  
27  import org.eclipse.jetty.io.ClientConnectionFactory;
28  import org.eclipse.jetty.util.HostPort;
29  
30  /**
31   * The configuration of the forward proxy to use with {@link org.eclipse.jetty.client.HttpClient}.
32   * <p>
33   * Applications add subclasses of {@link Proxy} to this configuration via:
34   * <pre>
35   * ProxyConfiguration proxyConfig = httpClient.getProxyConfiguration();
36   * proxyConfig.getProxies().add(new HttpProxy(proxyHost, 8080));
37   * </pre>
38   *
39   * @see HttpClient#getProxyConfiguration()
40   */
41  public class ProxyConfiguration
42  {
43      private final List<Proxy> proxies = new ArrayList<>();
44  
45      public List<Proxy> getProxies()
46      {
47          return proxies;
48      }
49  
50      public Proxy match(Origin origin)
51      {
52          for (Proxy proxy : getProxies())
53          {
54              if (proxy.matches(origin))
55                  return proxy;
56          }
57          return null;
58      }
59  
60      public static abstract class Proxy
61      {
62          // TO use IPAddress Map
63          private final Set<String> included = new HashSet<>();
64          private final Set<String> excluded = new HashSet<>();
65          private final Origin.Address address;
66          private final boolean secure;
67  
68          protected Proxy(Origin.Address address, boolean secure)
69          {
70              this.address = address;
71              this.secure = secure;
72          }
73  
74          /**
75           * @return the address of this proxy
76           */
77          public Origin.Address getAddress()
78          {
79              return address;
80          }
81  
82          /**
83           * @return whether the connection to the proxy must be secured via TLS
84           */
85          public boolean isSecure()
86          {
87              return secure;
88          }
89  
90          /**
91           * @return the list of origins that must be proxied
92           * @see #matches(Origin)
93           * @see #getExcludedAddresses()
94           */
95          public Set<String> getIncludedAddresses()
96          {
97              return included;
98          }
99  
100         /**
101          * @return the list of origins that must not be proxied.
102          * @see #matches(Origin)
103          * @see #getIncludedAddresses()
104          */
105         public Set<String> getExcludedAddresses()
106         {
107             return excluded;
108         }
109 
110         /**
111          * @return an URI representing this proxy, or null if no URI can represent this proxy
112          */
113         public URI getURI()
114         {
115             return null;
116         }
117 
118         /**
119          * Matches the given {@code origin} with the included and excluded addresses,
120          * returning true if the given {@code origin} is to be proxied.
121          *
122          * @param origin the origin to test for proxying
123          * @return true if the origin must be proxied, false otherwise
124          */
125         public boolean matches(Origin origin)
126         {
127             if (getAddress().equals(origin.getAddress()))
128                 return false;
129 
130             boolean result = included.isEmpty();
131             Origin.Address address = origin.getAddress();
132             for (String included : this.included)
133             {
134                 if (matches(address, included))
135                 {
136                     result = true;
137                     break;
138                 }
139             }
140             for (String excluded : this.excluded)
141             {
142                 if (matches(address, excluded))
143                 {
144                     result = false;
145                     break;
146                 }
147             }
148             return result;
149         }
150 
151         private boolean matches(Origin.Address address, String pattern)
152         {
153             // TODO: add support for CIDR notation like 192.168.0.0/24, see DoSFilter
154             HostPort hostPort = new HostPort(pattern);
155             String host = hostPort.getHost();
156             int port = hostPort.getPort();
157             return host.equals(address.getHost())  && ( port<=0 || port==address.getPort() ); 
158         }
159 
160         /**
161          * @param connectionFactory the nested {@link ClientConnectionFactory}
162          * @return a new {@link ClientConnectionFactory} for this {@link Proxy}
163          */
164         public abstract ClientConnectionFactory newClientConnectionFactory(ClientConnectionFactory connectionFactory);
165 
166         @Override
167         public String toString()
168         {
169             return address.toString();
170         }
171     }
172 
173 }