From 70d45ca74e19c98d0bef2a081f77fc1e3543691e Mon Sep 17 00:00:00 2001 From: gotty Date: Mon, 20 Jan 2020 09:00:09 +0300 Subject: [PATCH] [LIB-13] Several options for working through a proxy server --- .../chess/scanner/ChessHogScannerApp.java | 3 +- .../hedgecode/chess/scanner/ScannerConstants.java | 16 +++- .../scanner/portal/AbstractRequestScanner.java | 35 +++----- .../scanner/portal/AbstractSettingsScanner.java | 13 --- .../org/hedgecode/chess/scanner/proxy/Proxy.java | 75 ++++++++-------- .../hedgecode/chess/scanner/proxy/ProxyParams.java | 51 +++++------ .../hedgecode/chess/scanner/proxy/ProxyType.java | 46 ++++++++++ .../scanner/proxy/client/HttpRequestClient.java | 88 +++++++++++++++++++ .../scanner/proxy/client/LocalDnsResolver.java | 51 +++++++++++ .../proxy/client/SSLSocksSocketFactory.java | 67 +++++++++++++++ .../scanner/proxy/client/SocksRequestClient.java | 99 ++++++++++++++++++++++ .../scanner/proxy/client/SocksSocketFactory.java | 60 +++++++++++++ .../HTTPSetter.java => system/HttpSetter.java} | 12 ++- .../proxy/{type => system}/ProxyAuthenticator.java | 2 +- .../scanner/proxy/{ => system}/ProxySetter.java | 4 +- .../SOCKSSetter.java => system/SocksSetter.java} | 10 +-- .../chess/scanner/proxy/system/SystemProxy.java | 64 ++++++++++++++ .../chess/scanner/request/PlainRequestClient.java | 40 +++++++++ .../chess/scanner/request/RequestClient.java | 33 ++++++++ src/main/resources/scanner.properties | 1 + 20 files changed, 646 insertions(+), 124 deletions(-) create mode 100644 src/main/java/org/hedgecode/chess/scanner/proxy/ProxyType.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/proxy/client/HttpRequestClient.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/proxy/client/LocalDnsResolver.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/proxy/client/SSLSocksSocketFactory.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksRequestClient.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksSocketFactory.java rename src/main/java/org/hedgecode/chess/scanner/proxy/{type/HTTPSetter.java => system/HttpSetter.java} (78%) rename src/main/java/org/hedgecode/chess/scanner/proxy/{type => system}/ProxyAuthenticator.java (96%) rename src/main/java/org/hedgecode/chess/scanner/proxy/{ => system}/ProxySetter.java (90%) rename src/main/java/org/hedgecode/chess/scanner/proxy/{type/SOCKSSetter.java => system/SocksSetter.java} (82%) create mode 100644 src/main/java/org/hedgecode/chess/scanner/proxy/system/SystemProxy.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/request/PlainRequestClient.java create mode 100644 src/main/java/org/hedgecode/chess/scanner/request/RequestClient.java diff --git a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerApp.java b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerApp.java index 060773c..44cee75 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerApp.java +++ b/src/main/java/org/hedgecode/chess/scanner/ChessHogScannerApp.java @@ -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); } diff --git a/src/main/java/org/hedgecode/chess/scanner/ScannerConstants.java b/src/main/java/org/hedgecode/chess/scanner/ScannerConstants.java index a78a058..ca291b5 100644 --- a/src/main/java/org/hedgecode/chess/scanner/ScannerConstants.java +++ b/src/main/java/org/hedgecode/chess/scanner/ScannerConstants.java @@ -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( diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java index e179d2c..d6aa38b 100644 --- a/src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractRequestScanner.java @@ -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(); } } diff --git a/src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java index 8d0ccf4..4126115 100644 --- a/src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java +++ b/src/main/java/org/hedgecode/chess/scanner/portal/AbstractSettingsScanner.java @@ -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) diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/Proxy.java b/src/main/java/org/hedgecode/chess/scanner/proxy/Proxy.java index b54fece..f190008 100644 --- a/src/main/java/org/hedgecode/chess/scanner/proxy/Proxy.java +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/Proxy.java @@ -16,63 +16,62 @@ 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; } } diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/ProxyParams.java b/src/main/java/org/hedgecode/chess/scanner/proxy/ProxyParams.java index 6dba49b..6802109 100644 --- a/src/main/java/org/hedgecode/chess/scanner/proxy/ProxyParams.java +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/ProxyParams.java @@ -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:%d %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 index 0000000..348fada --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/ProxyType.java @@ -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 index 0000000..f3b8517 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/client/HttpRequestClient.java @@ -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 index 0000000..ae96759 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/client/LocalDnsResolver.java @@ -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 resolvers = new HashMap() { + { + 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 index 0000000..49190c4 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/client/SSLSocksSocketFactory.java @@ -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 index 0000000..44170e9 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksRequestClient.java @@ -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 socketFactories = + new HashMap() + { + { + 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 registryBuilder = RegistryBuilder.create(); + for (Map.Entry 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 index 0000000..c3a679a --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/client/SocksSocketFactory.java @@ -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 + ); + } + +} diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/type/HTTPSetter.java b/src/main/java/org/hedgecode/chess/scanner/proxy/system/HttpSetter.java similarity index 78% rename from src/main/java/org/hedgecode/chess/scanner/proxy/type/HTTPSetter.java rename to src/main/java/org/hedgecode/chess/scanner/proxy/system/HttpSetter.java index 188aa7c..2595122 100644 --- a/src/main/java/org/hedgecode/chess/scanner/proxy/type/HTTPSetter.java +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/system/HttpSetter.java @@ -14,18 +14,16 @@ * 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 diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/type/ProxyAuthenticator.java b/src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxyAuthenticator.java similarity index 96% rename from src/main/java/org/hedgecode/chess/scanner/proxy/type/ProxyAuthenticator.java rename to src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxyAuthenticator.java index 04744ea..096e502 100644 --- a/src/main/java/org/hedgecode/chess/scanner/proxy/type/ProxyAuthenticator.java +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxyAuthenticator.java @@ -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; diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/ProxySetter.java b/src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxySetter.java similarity index 90% rename from src/main/java/org/hedgecode/chess/scanner/proxy/ProxySetter.java rename to src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxySetter.java index f809c90..3dd1cd1 100644 --- a/src/main/java/org/hedgecode/chess/scanner/proxy/ProxySetter.java +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/system/ProxySetter.java @@ -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); diff --git a/src/main/java/org/hedgecode/chess/scanner/proxy/type/SOCKSSetter.java b/src/main/java/org/hedgecode/chess/scanner/proxy/system/SocksSetter.java similarity index 82% rename from src/main/java/org/hedgecode/chess/scanner/proxy/type/SOCKSSetter.java rename to src/main/java/org/hedgecode/chess/scanner/proxy/system/SocksSetter.java index 323065a..605049a 100644 --- a/src/main/java/org/hedgecode/chess/scanner/proxy/type/SOCKSSetter.java +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/system/SocksSetter.java @@ -14,18 +14,16 @@ * 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 index 0000000..603ba69 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/proxy/system/SystemProxy.java @@ -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 setters = new HashMap() { + { + 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 index 0000000..8c9786c --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/request/PlainRequestClient.java @@ -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 index 0000000..43b04b0 --- /dev/null +++ b/src/main/java/org/hedgecode/chess/scanner/request/RequestClient.java @@ -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(); + +} diff --git a/src/main/resources/scanner.properties b/src/main/resources/scanner.properties index bb0415e..e2b6446 100644 --- a/src/main/resources/scanner.properties +++ b/src/main/resources/scanner.properties @@ -21,3 +21,4 @@ scanner.lazy.init=true scanner.use.proxy=false scanner.proxy.server= scanner.proxy.auth= +scanner.proxy.system=false -- 2.10.0