[LIB-13] Several options for working through a proxy server
authorgotty <gotty@hedgecode.org>
Mon, 20 Jan 2020 06:00:09 +0000 (09:00 +0300)
committergotty <gotty@hedgecode.org>
Mon, 20 Jan 2020 06:00:09 +0000 (09:00 +0300)
20 files changed:
src/main/java/org/hedgecode/chess/scanner/ChessHogScannerApp.java
src/main/java/org/hedgecode/chess/scanner/ScannerConstants.java
src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java
src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java
src/main/java/org/hedgecode/chess/scanner/proxy/Proxy.java
src/main/java/org/hedgecode/chess/scanner/proxy/ProxyParams.java
src/main/java/org/hedgecode/chess/scanner/proxy/ProxyType.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/proxy/client/HttpRequestClient.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/proxy/client/LocalDnsResolver.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/proxy/client/SSLSocksSocketFactory.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksRequestClient.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksSocketFactory.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/proxy/system/HttpSetter.java [moved from src/main/java/org/hedgecode/chess/scanner/proxy/type/HTTPSetter.java with 78% similarity]
src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxyAuthenticator.java [moved from src/main/java/org/hedgecode/chess/scanner/proxy/type/ProxyAuthenticator.java with 96% similarity]
src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxySetter.java [moved from src/main/java/org/hedgecode/chess/scanner/proxy/ProxySetter.java with 90% similarity]
src/main/java/org/hedgecode/chess/scanner/proxy/system/SocksSetter.java [moved from src/main/java/org/hedgecode/chess/scanner/proxy/type/SOCKSSetter.java with 82% similarity]
src/main/java/org/hedgecode/chess/scanner/proxy/system/SystemProxy.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/request/PlainRequestClient.java [new file with mode: 0644]
src/main/java/org/hedgecode/chess/scanner/request/RequestClient.java [new file with mode: 0644]
src/main/resources/scanner.properties

index 060773c..44cee75 100644 (file)
@@ -35,7 +35,8 @@ public final class ChessHogScannerApp {
         if (useProxy) {
             ProxyParams proxyParams = new ProxyParams(
                     ScannerProperties.get("scanner.proxy.server"),
-                    ScannerProperties.get("scanner.proxy.auth")
+                    ScannerProperties.get("scanner.proxy.auth"),
+                    ScannerProperties.is("scanner.proxy.system")
             );
             Proxy.setProxy(proxyParams);
         }
index a78a058..ca291b5 100644 (file)
@@ -28,6 +28,8 @@ public final class ScannerConstants {
 
     public static final Charset CHARSET = StandardCharsets.UTF_8;
 
+    public static final String LOCALE_BUNDLE_FILE = "org.hedgecode.chess.scanner.LocalStrings";
+
     public static final String CRLF = System.getProperty("line.separator");
 
     public static final String TYPE_CHESSGAMES = "chessgames";
@@ -35,18 +37,26 @@ public final class ScannerConstants {
     public static final String TYPE_CHESSBOMB = "chessbomb";
     public static final String TYPE_CHESS24 = "chess24";
     public static final String TYPE_CHESSCOM = "chesscom";
+    public static final String TYPE_2700CHESS = "2700chess";
 
     public static final String DOMAIN_CHESSGAMES = "chessgames.com";
     public static final String DOMAIN_LICHESS = "lichess.org";
-    public static final String DOMAIN_CHESSBOMB = "www.chessbomb.com";
+    public static final String DOMAIN_CHESSBOMB = "chessbomb.com";
     public static final String DOMAIN_CHESS24 = "chess24.com";
     public static final String DOMAIN_CHESSCOM = "chess.com";
-
-    public static final String PGN_DETECT_REGEX = "^\\[Event \"[^\"]+\"\\]$";
+    public static final String DOMAIN_2700CHESS = "2700chess.com";
 
     public static final String PROXY_UNDEFINED = "undefined";
     public static final String PROXY_HTTP = "http";
+    public static final String PROXY_HTTPS = "https";
     public static final String PROXY_SOCKS = "socks";
+    public static final String PROXY_SOCKS_ADDRESS = "socks.address";
+
+    public static final String PROXY_SERVER_REGEX =
+            "^([^:]+):([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}):([0-9]{1,5})$";
+    public static final String PROXY_AUTH_REGEX =
+            "^([^:]+):(.+)$";
+
 
     private ScannerConstants() {
         throw new AssertionError(
index e179d2c..d6aa38b 100644 (file)
@@ -24,11 +24,12 @@ import java.util.Map;
 
 import org.apache.http.client.methods.CloseableHttpResponse;
 import org.apache.http.client.methods.HttpGet;
+import org.apache.http.client.protocol.HttpClientContext;
 import org.apache.http.impl.client.CloseableHttpClient;
-import org.apache.http.impl.client.HttpClients;
 
 import org.hedgecode.chess.scanner.Scanner;
 import org.hedgecode.chess.scanner.ScannerException;
+import org.hedgecode.chess.scanner.proxy.Proxy;
 import org.hedgecode.chess.scanner.regex.RegexMatcher;
 import org.hedgecode.chess.scanner.regex.RegexResult;
 import org.hedgecode.chess.scanner.regex.RegexType;
@@ -48,11 +49,10 @@ public abstract class AbstractRequestScanner implements Scanner {
     }
 
     protected String request(String url, boolean withCrlf) throws ScannerException {
-        HttpGet request = new HttpGet(url);
-        CloseableHttpResponse response = null;
         StringBuilder sb = new StringBuilder();
-        try {
-            response = getClient().execute(request);
+        try (CloseableHttpResponse response = getClient().execute(
+                new HttpGet(url), getContext()
+        )) {
             try (BufferedReader br = new BufferedReader(
                     new InputStreamReader(
                             response.getEntity().getContent(), CHARSET
@@ -70,12 +70,6 @@ public abstract class AbstractRequestScanner implements Scanner {
             throw new ScannerException(
                     String.format("Error occurred for requesting URL: %s", url), cause
             );
-        } finally {
-            if (response != null) {
-                try {
-                    response.close();
-                } catch (IOException ignored) {}
-            }
         }
         return sb.toString();
     }
@@ -168,10 +162,9 @@ public abstract class AbstractRequestScanner implements Scanner {
     protected RegexResult matchRequest(String url, RegexMatcher matcher, boolean isFirst)
             throws ScannerException
     {
-        HttpGet request = new HttpGet(url);
-        CloseableHttpResponse response = null;
-        try {
-            response = getClient().execute(request);
+        try (CloseableHttpResponse response = getClient().execute(
+                new HttpGet(url), getContext()
+        )) {
             try (BufferedReader br = new BufferedReader(
                     new InputStreamReader(
                             response.getEntity().getContent(),
@@ -190,18 +183,16 @@ public abstract class AbstractRequestScanner implements Scanner {
             throw new ScannerException(
                     String.format("Error occurred for requesting URL: %s", url), cause
             );
-        } finally {
-            if (response != null) {
-                try {
-                    response.close();
-                } catch (IOException ignored) {}
-            }
         }
         return matcher.result();
     }
 
     private CloseableHttpClient getClient() {
-        return HttpClients.createMinimal();
+        return Proxy.getRequestClient().getClient();
+    }
+
+    private HttpClientContext getContext() {
+        return Proxy.getRequestClient().getContext();
     }
 
 }
index 8d0ccf4..4126115 100644 (file)
@@ -27,7 +27,6 @@ import org.hedgecode.chess.scanner.regex.RegexBuilder;
 import org.hedgecode.chess.scanner.regex.RegexParams;
 import org.hedgecode.chess.scanner.spi.ServiceRegistry;
 
-import static org.hedgecode.chess.scanner.ScannerConstants.*;
 import static org.hedgecode.chess.scanner.regex.RegexBuilder.Type;
 
 /**
@@ -106,18 +105,6 @@ public abstract class AbstractSettingsScanner extends AbstractRequestScanner imp
         );
     }
 
-    protected String regex(String source, String regex) {
-        Matcher matcher = Pattern.compile(regex, Pattern.MULTILINE).matcher(source);
-        if (matcher.find()) {
-            return matcher.groupCount() > 0 ? matcher.group(1) : matcher.group();
-        }
-        return null;
-    }
-
-    protected boolean isPgnFormat(String source) {
-        return regex(source, PGN_DETECT_REGEX) != null;
-    }
-
     private String assignUrlWithParams(String url, String params) {
         return params != null
                 ? url.concat(params)
index b54fece..f190008 100644 (file)
 
 package org.hedgecode.chess.scanner.proxy;
 
-import org.hedgecode.chess.scanner.proxy.type.HTTPSetter;
-import org.hedgecode.chess.scanner.proxy.type.SOCKSSetter;
-
-import static org.hedgecode.chess.scanner.ScannerConstants.*;
+import org.hedgecode.chess.scanner.proxy.client.HttpRequestClient;
+import org.hedgecode.chess.scanner.proxy.client.SocksRequestClient;
+import org.hedgecode.chess.scanner.proxy.system.SystemProxy;
+import org.hedgecode.chess.scanner.request.PlainRequestClient;
+import org.hedgecode.chess.scanner.request.RequestClient;
 
 /**
- * Setter for proxy settings.
+ * Proxy settings main class.
  *
  * @author Dmitry Samoshin aka gotty
  */
-public enum Proxy {
+public final class Proxy {
 
-    UNDEFINED ( PROXY_UNDEFINED, null              ),
-    HTTP      ( PROXY_HTTP,      new HTTPSetter()  ),
-    SOCKS     ( PROXY_SOCKS,     new SOCKSSetter() );
+    private static Proxy proxy;
 
-    private String name;
-    private ProxySetter setter;
+    private RequestClient requestClient;
 
-    Proxy(String name, ProxySetter setter) {
-        this.name = name;
-        this.setter = setter;
+    private Proxy() {
+        requestClient = new PlainRequestClient();
     }
 
-    private ProxySetter getSetter() {
-        return setter;
+    public static void setProxy(ProxyParams proxyParams) {
+        getProxy().set(proxyParams);
     }
 
-    public static Proxy byName(String name) {
-        for (Proxy proxy : Proxy.values()) {
-            if (proxy.name.equals(name))
-                return proxy;
-        }
-        return UNDEFINED;
+    public static RequestClient getRequestClient() {
+        return getProxy().client();
     }
 
-    public static void setProxy(ProxyParams proxyParams) {
-        setProxy(
-                proxyParams.getType(),
-                proxyParams.getHost(), proxyParams.getPort(),
-                proxyParams.getUser(), proxyParams.getPassword()
-        );
+    private void set(ProxyParams proxyParams) {
+        if (proxyParams.isSystem()) {
+            SystemProxy.setProxy(proxyParams);
+            requestClient = new PlainRequestClient();
+        } else {
+            switch (proxyParams.getType()) {
+                case HTTP:
+                    requestClient = new HttpRequestClient(proxyParams);
+                    break;
+                case SOCKS:
+                    requestClient = new SocksRequestClient(proxyParams);
+                    break;
+                default:
+                    requestClient = new PlainRequestClient();
+            }
+        }
     }
 
-    public static void setProxy(Proxy type, String host, String port) {
-        setProxy(type, host, port, null, null);
+    private RequestClient client() {
+        return requestClient;
     }
 
-    public static void setProxy(Proxy type, String host, String port, String user, String password) {
-        ProxySetter proxySetter = type.getSetter();
-        if (proxySetter != null) {
-            proxySetter.setProxyHost(host);
-            proxySetter.setProxyPort(port);
-            if (user != null) {
-                proxySetter.setProxyAuth(user, password);
-            }
+    private static Proxy getProxy() {
+        if (proxy == null) {
+            proxy = new Proxy();
         }
+        return proxy;
     }
 
 }
index 6dba49b..6802109 100644 (file)
@@ -19,6 +19,8 @@ package org.hedgecode.chess.scanner.proxy;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
+import static org.hedgecode.chess.scanner.ScannerConstants.*;
+
 /**
  * Aggregate the proxy parameters for {@link Proxy}.
  *
@@ -26,29 +28,26 @@ import java.util.regex.Pattern;
  */
 public class ProxyParams {
 
-    private static final Pattern PROXY_SERVER_PATTERN = Pattern.compile(
-            "^([^:]+):([0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}\\.[0-9]{1,3}):([0-9]{1,5})$"
-    );
-
-    private static final Pattern PROXY_AUTH_PATTERN = Pattern.compile(
-            "^([^:]+):(.+)$"
-    );
+    private static final Pattern PROXY_SERVER_PATTERN = Pattern.compile(PROXY_SERVER_REGEX);
+    private static final Pattern PROXY_AUTH_PATTERN = Pattern.compile(PROXY_AUTH_REGEX);
 
-    private Proxy type;
+    private ProxyType type;
+    private boolean isSystem;
 
     private String host;
-    private String port;
+    private int port;
 
-    private String user = null;
-    private String password = null;
+    private String user;
+    private String password;
 
-    public ProxyParams(String proxyServer, String proxyAuth) {
+    public ProxyParams(String proxyServer, String proxyAuth, boolean isSystemProxy) {
+        isSystem = isSystemProxy;
 
         Matcher matcher = PROXY_SERVER_PATTERN.matcher(proxyServer);
         if (matcher.find()) {
-            type = Proxy.byName(matcher.group(1));
+            type = ProxyType.byName(matcher.group(1));
             host = matcher.group(2);
-            port = matcher.group(3);
+            port = Integer.parseInt(matcher.group(3));
         }
 
         if (proxyAuth != null && !proxyAuth.isEmpty()) {
@@ -60,29 +59,19 @@ public class ProxyParams {
         }
     }
 
-    public ProxyParams(Proxy type, String host, String port) {
-        this.type = type;
-        this.host = host;
-        this.port = port;
-    }
-
-    public ProxyParams(Proxy type, String host, String port, String user, String password) {
-        this.type = type;
-        this.host = host;
-        this.port = port;
-        this.user = user;
-        this.password = password;
+    public ProxyType getType() {
+        return type;
     }
 
-    public Proxy getType() {
-        return type;
+    public boolean isSystem() {
+        return isSystem;
     }
 
     public String getHost() {
         return host;
     }
 
-    public String getPort() {
+    public int getPort() {
         return port;
     }
 
@@ -97,11 +86,11 @@ public class ProxyParams {
     @Override
     public String toString() {
         return String.format(
-                "[%s] %s:%s%s",
+                "[%s] %s:%%s",
                 type,
                 host,
                 port,
-                user != null ? " (with auth)" : ""
+                user != null ? String.format("(user: %s)", user)  : ""
         );
     }
 
diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/ProxyType.java b/src/main/java/org/hedgecode/chess/scanner/proxy/ProxyType.java
new file mode 100644 (file)
index 0000000..348fada
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.proxy;
+
+import static org.hedgecode.chess.scanner.ScannerConstants.*;
+
+/**
+ * ProxyType
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public enum ProxyType {
+
+    UNDEFINED ( PROXY_UNDEFINED ),
+    HTTP      ( PROXY_HTTP      ),
+    SOCKS     ( PROXY_SOCKS     );
+
+    private String name;
+
+    ProxyType(String name) {
+        this.name = name;
+    }
+
+    public static ProxyType byName(String name) {
+        for (ProxyType type : ProxyType.values()) {
+            if (type.name.equals(name))
+                return type;
+        }
+        return UNDEFINED;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/client/HttpRequestClient.java b/src/main/java/org/hedgecode/chess/scanner/proxy/client/HttpRequestClient.java
new file mode 100644 (file)
index 0000000..f3b8517
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.proxy.client;
+
+import org.apache.http.HttpHost;
+import org.apache.http.auth.AuthScope;
+import org.apache.http.auth.UsernamePasswordCredentials;
+import org.apache.http.client.CredentialsProvider;
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.BasicCredentialsProvider;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+import org.apache.http.impl.client.HttpClientBuilder;
+import org.hedgecode.chess.scanner.proxy.ProxyParams;
+import org.hedgecode.chess.scanner.request.RequestClient;
+
+/**
+ * HttpRequestClient
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class HttpRequestClient implements RequestClient {
+
+    private final HttpClientBuilder clientBuilder;
+
+    public HttpRequestClient(ProxyParams params) {
+        HttpHost proxy = new HttpHost(
+                params.getHost(), params.getPort()
+        );
+        clientBuilder = HttpClientBuilder.create().setProxy(proxy);
+        if (params.getUser() != null) {
+            CredentialsProvider credentialsProvider = new BasicCredentialsProvider();
+            credentialsProvider.setCredentials(
+                    new AuthScope(
+                            params.getHost(), params.getPort()
+                    ),
+                    new UsernamePasswordCredentials(
+                            params.getUser(), params.getPassword()
+                    )
+            );
+            clientBuilder.setDefaultCredentialsProvider(
+                    credentialsProvider
+            );
+        }
+    }
+
+    @Override
+    public CloseableHttpClient getClient() {
+        return clientBuilder.build();
+    }
+
+    @Override
+    public HttpClientContext getContext() {
+        return null;
+    }
+
+/*
+    private void ntlm() {
+        NTCredentials ntCreds = new NTCredentials(ntUsername, ntPassword,localMachineName, domainName );
+
+        CredentialsProvider credsProvider = new BasicCredentialsProvider();
+        credsProvider.setCredentials( new AuthScope(proxyHost,proxyPort), ntCreds );
+        HttpClientBuilder clientBuilder = HttpClientBuilder.create();
+
+        clientBuilder.useSystemProperties();
+        clientBuilder.setProxy(new HttpHost(pxInfo.getProxyURL(), pxInfo.getProxyPort()));
+        clientBuilder.setDefaultCredentialsProvider(credsProvider);
+        clientBuilder.setProxyAuthenticationStrategy(new ProxyAuthenticationStrategy());
+
+        CloseableHttpClient client = clientBuilder.build();
+    }
+*/
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/client/LocalDnsResolver.java b/src/main/java/org/hedgecode/chess/scanner/proxy/client/LocalDnsResolver.java
new file mode 100644 (file)
index 0000000..ae96759
--- /dev/null
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.proxy.client;
+
+import java.net.InetAddress;
+import java.net.UnknownHostException;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.http.conn.DnsResolver;
+
+/**
+ * LocalDnsResolver
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class LocalDnsResolver implements DnsResolver {
+
+    private static final String LOCALHOST = "localhost";
+    private static final byte[] IP_ADDRESS = { 127, 0, 0, 1 };
+
+    private final Map<String, byte[]> resolvers = new HashMap<String, byte[]>() {
+        {
+            put( LOCALHOST, IP_ADDRESS );
+        }
+    };
+
+    @Override
+    public InetAddress[] resolve(String host) throws UnknownHostException {
+        return new InetAddress[] {
+                InetAddress.getByAddress(
+                        LOCALHOST, resolvers.get(LOCALHOST)
+                )
+        };
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/client/SSLSocksSocketFactory.java b/src/main/java/org/hedgecode/chess/scanner/proxy/client/SSLSocksSocketFactory.java
new file mode 100644 (file)
index 0000000..49190c4
--- /dev/null
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.proxy.client;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.Socket;
+
+import org.apache.http.HttpHost;
+import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
+import org.apache.http.protocol.HttpContext;
+import org.apache.http.ssl.SSLContexts;
+
+import org.hedgecode.chess.scanner.ScannerConstants;
+
+/**
+ * SSLSocksSocketFactory
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class SSLSocksSocketFactory extends SSLConnectionSocketFactory {
+
+    SSLSocksSocketFactory() {
+        super(
+                SSLContexts.createSystemDefault()
+        );
+    }
+
+    @Override
+    public Socket createSocket(final HttpContext context) throws IOException {
+        Proxy proxy = new Proxy(
+                Proxy.Type.SOCKS,
+                (InetSocketAddress) context.getAttribute(ScannerConstants.PROXY_SOCKS_ADDRESS)
+        );
+        return new Socket(proxy);
+    }
+
+    @Override
+    public Socket connectSocket(
+            int connectTimeout, Socket socket, HttpHost host,
+            InetSocketAddress remoteAddress, InetSocketAddress localAddress,
+            HttpContext context
+    ) throws IOException {
+        InetSocketAddress unresolvedAddress = InetSocketAddress.createUnresolved(
+                host.getHostName(), remoteAddress.getPort()
+        );
+        return super.connectSocket(
+                connectTimeout, socket, host, unresolvedAddress, localAddress, context
+        );
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksRequestClient.java b/src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksRequestClient.java
new file mode 100644 (file)
index 0000000..44170e9
--- /dev/null
@@ -0,0 +1,99 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.proxy.client;
+
+import java.net.InetSocketAddress;
+import java.util.HashMap;
+import java.util.Map;
+
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.config.RegistryBuilder;
+import org.apache.http.conn.HttpClientConnectionManager;
+import org.apache.http.conn.socket.ConnectionSocketFactory;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
+
+import org.hedgecode.chess.scanner.ScannerConstants;
+import org.hedgecode.chess.scanner.proxy.ProxyParams;
+import org.hedgecode.chess.scanner.request.RequestClient;
+
+/**
+ * SocksRequestClient
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class SocksRequestClient implements RequestClient {
+
+    private final Map<String, ConnectionSocketFactory> socketFactories =
+            new HashMap<String, ConnectionSocketFactory>()
+            {
+                {
+                    put( ScannerConstants.PROXY_HTTP, new SocksSocketFactory() );
+                    put( ScannerConstants.PROXY_HTTPS, new SSLSocksSocketFactory() );
+                }
+            };
+
+    private final HttpClientConnectionManager connectionManager;
+    private /*final*/ HttpClientContext clientContext;
+    private final InetSocketAddress proxySocketAddress;
+
+
+    public SocksRequestClient(ProxyParams params) {
+        RegistryBuilder<ConnectionSocketFactory> registryBuilder = RegistryBuilder.create();
+        for (Map.Entry<String, ConnectionSocketFactory> socketFactory : socketFactories.entrySet()) {
+            registryBuilder.register(
+                    socketFactory.getKey(), socketFactory.getValue()
+            );
+        }
+        connectionManager = new PoolingHttpClientConnectionManager(
+                registryBuilder.build(),
+                new LocalDnsResolver()
+        );
+        proxySocketAddress = new InetSocketAddress(
+                params.getHost(), params.getPort()
+        );
+
+/*
+        clientContext = HttpClientContext.create();
+        clientContext.setAttribute(
+                ScannerConstants.PROXY_SOCKS_ADDRESS,
+                new InetSocketAddress(
+                        params.getHost(), params.getPort()
+                )
+        );
+*/
+    }
+
+    @Override
+    public CloseableHttpClient getClient() {
+        return HttpClients.custom()
+                .setConnectionManager(connectionManager)
+                .build();
+    }
+
+    @Override
+    public HttpClientContext getContext() {
+        clientContext = HttpClientContext.create();
+        clientContext.setAttribute(
+                ScannerConstants.PROXY_SOCKS_ADDRESS,
+                proxySocketAddress
+        );
+        return clientContext;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksSocketFactory.java b/src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksSocketFactory.java
new file mode 100644 (file)
index 0000000..c3a679a
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.proxy.client;
+
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.Proxy;
+import java.net.Socket;
+
+import org.apache.http.HttpHost;
+import org.apache.http.conn.socket.PlainConnectionSocketFactory;
+import org.apache.http.protocol.HttpContext;
+
+import org.hedgecode.chess.scanner.ScannerConstants;
+
+/**
+ * SocksSocketFactory
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class SocksSocketFactory extends PlainConnectionSocketFactory {
+
+    @Override
+    public Socket createSocket(final HttpContext context) throws IOException {
+        Proxy proxy = new Proxy(
+                Proxy.Type.SOCKS,
+                (InetSocketAddress) context.getAttribute(ScannerConstants.PROXY_SOCKS_ADDRESS)
+        );
+        return new Socket(proxy);
+    }
+
+    @Override
+    public Socket connectSocket(
+            int connectTimeout, Socket socket, HttpHost host,
+            InetSocketAddress remoteAddress, InetSocketAddress localAddress,
+            HttpContext context
+    ) throws IOException {
+        InetSocketAddress unresolvedAddress = InetSocketAddress.createUnresolved(
+                host.getHostName(), remoteAddress.getPort()
+        );
+        return super.connectSocket(
+                connectTimeout, socket, host, unresolvedAddress, localAddress, context
+        );
+    }
+
+}
  * limitations under the License.
  */
 
-package org.hedgecode.chess.scanner.proxy.type;
+package org.hedgecode.chess.scanner.proxy.system;
 
 import java.net.Authenticator;
 
-import org.hedgecode.chess.scanner.proxy.ProxySetter;
-
 /**
  * HTTP/HTTPS proxy server setter.
  *
  * @author Dmitry Samoshin aka gotty
  */
-public class HTTPSetter implements ProxySetter {
+public class HttpSetter implements ProxySetter {
 
     @Override
     public void setProxyHost(String proxyHost) {
@@ -34,9 +32,9 @@ public class HTTPSetter implements ProxySetter {
     }
 
     @Override
-    public void setProxyPort(String proxyPort) {
-        System.setProperty("http.proxyPort", proxyPort);
-        System.setProperty("https.proxyPort", proxyPort);
+    public void setProxyPort(int proxyPort) {
+        System.setProperty("http.proxyPort", String.valueOf(proxyPort));
+        System.setProperty("https.proxyPort", String.valueOf(proxyPort));
     }
 
     @Override
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.hedgecode.chess.scanner.proxy.type;
+package org.hedgecode.chess.scanner.proxy.system;
 
 import java.net.Authenticator;
 import java.net.PasswordAuthentication;
@@ -14,7 +14,7 @@
  * limitations under the License.
  */
 
-package org.hedgecode.chess.scanner.proxy;
+package org.hedgecode.chess.scanner.proxy.system;
 
 /**
  * Proxy server setter interface.
@@ -25,7 +25,7 @@ public interface ProxySetter {
 
     void setProxyHost(String proxyHost);
 
-    void setProxyPort(String proxyPort);
+    void setProxyPort(int proxyPort);
 
     void setProxyAuth(String user, String password);
 
  * limitations under the License.
  */
 
-package org.hedgecode.chess.scanner.proxy.type;
+package org.hedgecode.chess.scanner.proxy.system;
 
 import java.net.Authenticator;
 
-import org.hedgecode.chess.scanner.proxy.ProxySetter;
-
 /**
  * SOCKS proxy server setter.
  *
  * @author Dmitry Samoshin aka gotty
  */
-public class SOCKSSetter implements ProxySetter {
+public class SocksSetter implements ProxySetter {
 
     @Override
     public void setProxyHost(String proxyHost) {
@@ -33,8 +31,8 @@ public class SOCKSSetter implements ProxySetter {
     }
 
     @Override
-    public void setProxyPort(String proxyPort) {
-        System.setProperty("socksProxyPort", proxyPort);
+    public void setProxyPort(int proxyPort) {
+        System.setProperty("socksProxyPort", String.valueOf(proxyPort));
     }
 
     @Override
diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/system/SystemProxy.java b/src/main/java/org/hedgecode/chess/scanner/proxy/system/SystemProxy.java
new file mode 100644 (file)
index 0000000..603ba69
--- /dev/null
@@ -0,0 +1,64 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.proxy.system;
+
+import java.util.HashMap;
+import java.util.Map;
+
+import org.hedgecode.chess.scanner.proxy.ProxyParams;
+import org.hedgecode.chess.scanner.proxy.ProxyType;
+
+/**
+ * Setter for system proxy settings.
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public final class SystemProxy {
+
+    private static final Map<ProxyType, ProxySetter> setters = new HashMap<ProxyType, ProxySetter>() {
+        {
+            put( ProxyType.HTTP, new HttpSetter() );
+            put( ProxyType.SOCKS, new SocksSetter() );
+        }
+    };
+
+    public static void setProxy(ProxyParams proxyParams) {
+        setProxy(
+                proxyParams.getType(),
+                proxyParams.getHost(),
+                proxyParams.getPort(),
+                proxyParams.getUser(),
+                proxyParams.getPassword()
+        );
+    }
+
+    public static void setProxy(ProxyType type, String host, int port) {
+        setProxy(type, host, port, null, null);
+    }
+
+    public static void setProxy(ProxyType type, String host, int port, String user, String password) {
+        ProxySetter proxySetter = setters.get(type);
+        if (proxySetter != null) {
+            proxySetter.setProxyHost(host);
+            proxySetter.setProxyPort(port);
+            if (user != null) {
+                proxySetter.setProxyAuth(user, password);
+            }
+        }
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/request/PlainRequestClient.java b/src/main/java/org/hedgecode/chess/scanner/request/PlainRequestClient.java
new file mode 100644 (file)
index 0000000..8c9786c
--- /dev/null
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.request;
+
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.CloseableHttpClient;
+import org.apache.http.impl.client.HttpClients;
+
+/**
+ * PlainRequestClient
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public class PlainRequestClient implements RequestClient {
+
+    @Override
+    public CloseableHttpClient getClient() {
+        return HttpClients.createMinimal();
+    }
+
+    @Override
+    public HttpClientContext getContext() {
+        return null;
+    }
+
+}
diff --git a/src/main/java/org/hedgecode/chess/scanner/request/RequestClient.java b/src/main/java/org/hedgecode/chess/scanner/request/RequestClient.java
new file mode 100644 (file)
index 0000000..43b04b0
--- /dev/null
@@ -0,0 +1,33 @@
+/*
+ * Copyright (c) 2019-2020. Developed by Hedgecode.
+ *
+ * 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 org.hedgecode.chess.scanner.request;
+
+import org.apache.http.client.protocol.HttpClientContext;
+import org.apache.http.impl.client.CloseableHttpClient;
+
+/**
+ * RequestClient
+ *
+ * @author Dmitry Samoshin aka gotty
+ */
+public interface RequestClient {
+
+    CloseableHttpClient getClient();
+
+    HttpClientContext getContext();
+
+}
index bb0415e..e2b6446 100644 (file)
@@ -21,3 +21,4 @@ scanner.lazy.init=true
 scanner.use.proxy=false
 scanner.proxy.server=
 scanner.proxy.auth=
+scanner.proxy.system=false