| /* |
| * Copyright 2000-2013 JetBrains s.r.o. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| package com.intellij.util.net; |
| |
| import com.btr.proxy.search.ProxySearch; |
| import com.btr.proxy.selector.pac.PacProxySelector; |
| import com.btr.proxy.selector.pac.UrlPacScriptSource; |
| import com.intellij.openapi.diagnostic.Logger; |
| import com.intellij.openapi.util.Comparing; |
| import com.intellij.openapi.util.text.StringUtil; |
| import com.intellij.util.proxy.CommonProxy; |
| import org.jetbrains.annotations.NotNull; |
| |
| import java.io.IOException; |
| import java.net.*; |
| import java.util.Collections; |
| import java.util.List; |
| import java.util.concurrent.atomic.AtomicReference; |
| import java.util.regex.Pattern; |
| |
| /** |
| * @author Irina.Chernushina |
| * @since 1/30/13 |
| */ |
| public class IdeaWideProxySelector extends ProxySelector { |
| private final static Logger LOG = Logger.getInstance("#com.intellij.util.net.IdeaWideProxySelector"); |
| |
| private final HttpConfigurable myHttpConfigurable; |
| private final AtomicReference<ProxySelector> myPacProxySelector = new AtomicReference<ProxySelector>(); |
| |
| public IdeaWideProxySelector(HttpConfigurable configurable) { |
| myHttpConfigurable = configurable; |
| } |
| |
| @Override |
| public List<Proxy> select(@NotNull URI uri) { |
| LOG.debug("IDEA-wide proxy selector asked for " + uri.toString()); |
| |
| String scheme = uri.getScheme(); |
| if (!("http".equals(scheme) || "https".equals(scheme))) { |
| LOG.debug("No proxy: not http/https scheme: " + scheme); |
| return CommonProxy.NO_PROXY_LIST; |
| } |
| |
| if (myHttpConfigurable.USE_HTTP_PROXY) { |
| if (isProxyException(uri)) { |
| LOG.debug("No proxy: URI '", uri, "' matches proxy exceptions [", myHttpConfigurable.PROXY_EXCEPTIONS, "]"); |
| return CommonProxy.NO_PROXY_LIST; |
| } |
| |
| if (myHttpConfigurable.PROXY_PORT < 0 || myHttpConfigurable.PROXY_PORT > 65535) { |
| LOG.debug("No proxy: invalid port: " + myHttpConfigurable.PROXY_PORT); |
| return CommonProxy.NO_PROXY_LIST; |
| } |
| |
| Proxy.Type type = myHttpConfigurable.PROXY_TYPE_IS_SOCKS ? Proxy.Type.SOCKS : Proxy.Type.HTTP; |
| Proxy proxy = new Proxy(type, new InetSocketAddress(myHttpConfigurable.PROXY_HOST, myHttpConfigurable.PROXY_PORT)); |
| LOG.debug("Defined proxy: ", proxy); |
| myHttpConfigurable.LAST_ERROR = null; |
| return Collections.singletonList(proxy); |
| } |
| |
| if (myHttpConfigurable.USE_PROXY_PAC) { |
| ProxySelector pacProxySelector = myPacProxySelector.get(); |
| if (myHttpConfigurable.USE_PAC_URL && !StringUtil.isEmpty(myHttpConfigurable.PAC_URL)) { |
| myPacProxySelector.set(new PacProxySelector(new UrlPacScriptSource(myHttpConfigurable.PAC_URL))); |
| } |
| else if (pacProxySelector == null) { |
| ProxySearch proxySearch = ProxySearch.getDefaultProxySearch(); |
| proxySearch.setPacCacheSettings(32, 10 * 60 * 1000); // Cache 32 urls for up to 10 min. |
| pacProxySelector = proxySearch.getProxySelector(); |
| myPacProxySelector.lazySet(pacProxySelector); |
| } |
| |
| if (pacProxySelector != null) { |
| List<Proxy> select = pacProxySelector.select(uri); |
| LOG.debug("Autodetected proxies: ", select); |
| return select; |
| } |
| else { |
| LOG.debug("No proxies detected"); |
| } |
| } |
| |
| return CommonProxy.NO_PROXY_LIST; |
| } |
| |
| private boolean isProxyException(URI uri) { |
| String uriHost = uri.getHost(); |
| if (StringUtil.isEmptyOrSpaces(uriHost) || StringUtil.isEmptyOrSpaces(myHttpConfigurable.PROXY_EXCEPTIONS)) { |
| return false; |
| } |
| |
| List<String> hosts = StringUtil.split(myHttpConfigurable.PROXY_EXCEPTIONS, ","); |
| for (String hostPattern : hosts) { |
| String regexpPattern = StringUtil.escapeToRegexp(hostPattern.trim()).replace("\\*", ".*"); |
| if (Pattern.compile(regexpPattern).matcher(uriHost).matches()) { |
| return true; |
| } |
| } |
| |
| return false; |
| } |
| |
| @Override |
| public void connectFailed(URI uri, SocketAddress sa, IOException ioe) { |
| if (myHttpConfigurable.USE_PROXY_PAC) { |
| myHttpConfigurable.removeGeneric(new CommonProxy.HostInfo(uri.getScheme(), uri.getHost(), uri.getPort())); |
| LOG.debug("generic proxy credentials (if were saved) removed"); |
| return; |
| } |
| |
| final InetSocketAddress isa = sa instanceof InetSocketAddress ? (InetSocketAddress) sa : null; |
| if (myHttpConfigurable.USE_HTTP_PROXY && isa != null && Comparing.equal(myHttpConfigurable.PROXY_HOST, isa.getHostName())) { |
| LOG.debug("connection failed message passed to http configurable"); |
| myHttpConfigurable.LAST_ERROR = ioe.getMessage(); |
| } |
| } |
| } |