diff --git a/pom.xml b/pom.xml index ded874b8..a4b75498 100644 --- a/pom.xml +++ b/pom.xml @@ -229,9 +229,9 @@ --> - commons-httpclient - commons-httpclient - 3.1 + org.apache.httpcomponents + httpclient + 4.3.5 diff --git a/src/main/java/com/notnoop/apns/internal/TlsTunnelBuilder.java b/src/main/java/com/notnoop/apns/internal/TlsTunnelBuilder.java index 36da7fea..76cc637f 100644 --- a/src/main/java/com/notnoop/apns/internal/TlsTunnelBuilder.java +++ b/src/main/java/com/notnoop/apns/internal/TlsTunnelBuilder.java @@ -36,25 +36,30 @@ import java.net.ProtocolException; import java.net.Proxy; import java.net.Socket; + import javax.net.ssl.SSLSocketFactory; -import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; -import org.apache.commons.httpclient.ConnectMethod; -import org.apache.commons.httpclient.NTCredentials; -import org.apache.commons.httpclient.ProxyClient; -import org.apache.commons.httpclient.UsernamePasswordCredentials; -import org.apache.commons.httpclient.auth.AuthScope; + +import org.apache.http.HttpHost; +import org.apache.http.auth.UsernamePasswordCredentials; +import org.apache.http.client.config.RequestConfig; +import org.apache.http.config.ConnectionConfig; +import org.apache.http.impl.client.ProxyClient; +import org.apache.http.impl.conn.ManagedHttpClientConnectionFactory; +import org.apache.http.params.HttpParams; +import org.apache.http.params.BasicHttpParams; import org.slf4j.Logger; import org.slf4j.LoggerFactory; +import edu.umd.cs.findbugs.annotations.SuppressFBWarnings; + /** - * Establishes a TLS connection using an HTTP proxy. See RFC 2817 5.2. This class does - * not support proxies requiring a "Proxy-Authorization" header. + * Establishes a TLS connection using an HTTP proxy. See RFC 2817 5.2. This + * class does not support proxies requiring a "Proxy-Authorization" header. */ public final class TlsTunnelBuilder { - + private static final Logger logger = LoggerFactory.getLogger(TlsTunnelBuilder.class); - + public Socket build(SSLSocketFactory factory, Proxy proxy, String proxyUsername, String proxyPassword, String host, int port) throws IOException { boolean success = false; @@ -65,7 +70,7 @@ public Socket build(SSLSocketFactory factory, Proxy proxy, String proxyUsername, proxySocket = makeTunnel(host, port, proxyUsername, proxyPassword, proxyAddress); // Handshake with the origin server. - if(proxySocket == null) { + if (proxySocket == null) { throw new ProtocolException("Unable to create tunnel through proxy server."); } Socket socket = factory.createSocket(proxySocket, host, port, true /* auto close */); @@ -78,39 +83,30 @@ public Socket build(SSLSocketFactory factory, Proxy proxy, String proxyUsername, } } - @SuppressFBWarnings(value = "VA_FORMAT_STRING_USES_NEWLINE", - justification = "use as according to RFC, not platform-linefeed") - Socket makeTunnel(String host, int port, String proxyUsername, - String proxyPassword, InetSocketAddress proxyAddress) throws IOException { - if(host == null || port < 0 || host.isEmpty() || proxyAddress == null){ - throw new ProtocolException("Incorrect parameters to build tunnel."); + @SuppressFBWarnings(value = "VA_FORMAT_STRING_USES_NEWLINE", justification = "use as according to RFC, not platform-linefeed") + Socket makeTunnel(String host, int port, String proxyUsername, String proxyPassword, InetSocketAddress proxyAddress) + throws IOException { + if (host == null || port < 0 || host.isEmpty() || proxyAddress == null) { + throw new ProtocolException("Incorrect parameters to build tunnel."); } logger.debug("Creating socket for Proxy : " + proxyAddress.getAddress() + ":" + proxyAddress.getPort()); Socket socket; try { - ProxyClient client = new ProxyClient(); - client.getParams().setParameter("http.useragent", "java-apns"); - client.getHostConfiguration().setHost(host, port); - String proxyHost = proxyAddress.getAddress().toString().substring(0, proxyAddress.getAddress().toString().indexOf("/")); - client.getHostConfiguration().setProxy(proxyHost, proxyAddress.getPort()); - - - ProxyClient.ConnectResponse response = client.connect(); - socket = response.getSocket(); - if (socket == null) { - ConnectMethod method = response.getConnectMethod(); - // Read the proxy's HTTP response. - if(method.getStatusLine().toString().matches("HTTP/1\\.\\d 407 Proxy Authentication Required")) { - // Proxy server returned 407. We will now try to connect with auth Header - if(proxyUsername != null && proxyPassword != null) { - socket = AuthenticateProxy(method, client,proxyHost, proxyAddress.getPort(), - proxyUsername, proxyPassword); - } else { - throw new ProtocolException("Socket not created: " + method.getStatusLine()); - } - } - } - + + HttpParams httpParams = new BasicHttpParams(); + httpParams.setParameter("http.useragent", "java-apns"); + + ProxyClient proxyClient = new ProxyClient(httpParams); + + String proxyHostString = proxyAddress.getAddress().toString() + .substring(0, proxyAddress.getAddress().toString().indexOf("/")); + HttpHost targetHost = new HttpHost(host, port); + HttpHost proxyHost = new HttpHost(proxyHostString, proxyAddress.getPort()); + + UsernamePasswordCredentials credentials = new UsernamePasswordCredentials(proxyUsername, proxyPassword); + + socket = proxyClient.tunnel(proxyHost, targetHost, credentials); + } catch (Exception e) { throw new ProtocolException("Error occurred while creating proxy socket : " + e.toString()); } @@ -119,30 +115,4 @@ Socket makeTunnel(String host, int port, String proxyUsername, } return socket; } - - private Socket AuthenticateProxy(ConnectMethod method, ProxyClient client, - String proxyHost, int proxyPort, - String proxyUsername, String proxyPassword) throws IOException { - if(method.getProxyAuthState().getAuthScheme().getSchemeName().equalsIgnoreCase("ntlm")) { - // If Auth scheme is NTLM, set NT credentials with blank host and domain name - client.getState().setProxyCredentials(new AuthScope(proxyHost, proxyPort), - new NTCredentials(proxyUsername, proxyPassword,"","")); - } else { - // If Auth scheme is Basic/Digest, set regular Credentials - client.getState().setProxyCredentials(new AuthScope(proxyHost, proxyPort), - new UsernamePasswordCredentials(proxyUsername, proxyPassword)); - } - - ProxyClient.ConnectResponse response = client.connect(); - Socket socket = response.getSocket(); - - if (socket == null) { - method = response.getConnectMethod(); - throw new ProtocolException("Proxy Authentication failed. Socket not created: " - + method.getStatusLine()); - } - return socket; - } - } -