View Javadoc
1   /*
2    * DavMail POP/IMAP/SMTP/CalDav/LDAP Exchange Gateway
3    * Copyright (C) 2010  Mickael Guessant
4    *
5    * This program is free software; you can redistribute it and/or
6    * modify it under the terms of the GNU General Public License
7    * as published by the Free Software Foundation; either version 2
8    * of the License, or (at your option) any later version.
9    *
10   * This program is distributed in the hope that it will be useful,
11   * but WITHOUT ANY WARRANTY; without even the implied warranty of
12   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13   * GNU General Public License for more details.
14   *
15   * You should have received a copy of the GNU General Public License
16   * along with this program; if not, write to the Free Software
17   * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
18   */
19  
20  package davmail.http;
21  
22  import davmail.Settings;
23  import org.apache.log4j.Logger;
24  
25  import java.io.IOException;
26  import java.net.InetSocketAddress;
27  import java.net.Proxy;
28  import java.net.ProxySelector;
29  import java.net.SocketAddress;
30  import java.net.URI;
31  import java.util.ArrayList;
32  import java.util.Collections;
33  import java.util.List;
34  
35  /**
36   * Custom proxy selector based on DavMail settings.
37   * Interactive O365 authentication relies on native HttpUrlConnection so we need to override default proxy selector.
38   */
39  public class DavGatewayProxySelector extends ProxySelector {
40      static final Logger LOGGER = Logger.getLogger(DavGatewayProxySelector.class);
41  
42      static final List<Proxy> DIRECT = Collections.singletonList(Proxy.NO_PROXY);
43  
44      ProxySelector proxySelector;
45  
46      public DavGatewayProxySelector(ProxySelector proxySelector) {
47          this.proxySelector = proxySelector;
48      }
49  
50      @Override
51      public List<Proxy> select(URI uri) {
52          boolean useSystemProxies = Settings.getBooleanProperty("davmail.useSystemProxies", Boolean.FALSE);
53          boolean enableProxy = Settings.getBooleanProperty("davmail.enableProxy");
54          String proxyHost = Settings.getProperty("davmail.proxyHost");
55          int proxyPort = Settings.getIntProperty("davmail.proxyPort");
56          String scheme = uri.getScheme();
57          if ("socket".equals(scheme)) {
58              return DIRECT;
59          } else if (useSystemProxies) {
60              List<Proxy> proxyes = proxySelector.select(uri);
61              LOGGER.debug("Selected " + proxyes + " proxy for " + uri);
62              return proxyes;
63          } else if (enableProxy
64                  && proxyHost != null && proxyHost.length() > 0 && proxyPort > 0
65                  && !isNoProxyFor(uri)
66                  && ("http".equals(scheme) || "https".equals(scheme))) {
67              // DavMail defined proxies
68              ArrayList<Proxy> proxies = new ArrayList<>();
69              proxies.add(new Proxy(Proxy.Type.HTTP, InetSocketAddress.createUnresolved(proxyHost, proxyPort)));
70              return proxies;
71          } else {
72              return DIRECT;
73          }
74      }
75  
76      private boolean isNoProxyFor(URI uri) {
77          final String noProxyFor = Settings.getProperty("davmail.noProxyFor");
78          if (noProxyFor != null) {
79              final String urihost = uri.getHost().toLowerCase();
80              final String[] domains = noProxyFor.toLowerCase().split(",\\s*");
81              for (String domain : domains) {
82                  if (urihost.endsWith(domain)) {
83                      return true; //break;
84                  }
85              }
86          }
87          return false;
88      }
89  
90      @Override
91      public void connectFailed(URI uri, SocketAddress sa, IOException ioe) {
92          LOGGER.debug("Connection to " + uri + " failed, socket address " + sa + " " + ioe);
93          proxySelector.connectFailed(uri, sa, ioe);
94      }
95  }