diff options
Diffstat (limited to 'src/org/jivesoftware/smack/proxy/HTTPProxySocketFactory.java')
-rw-r--r-- | src/org/jivesoftware/smack/proxy/HTTPProxySocketFactory.java | 172 |
1 files changed, 172 insertions, 0 deletions
diff --git a/src/org/jivesoftware/smack/proxy/HTTPProxySocketFactory.java b/src/org/jivesoftware/smack/proxy/HTTPProxySocketFactory.java new file mode 100644 index 0000000..4ee5dd6 --- /dev/null +++ b/src/org/jivesoftware/smack/proxy/HTTPProxySocketFactory.java @@ -0,0 +1,172 @@ +/** + * $RCSfile$ + * $Revision$ + * $Date$ + * + * All rights reserved. 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.jivesoftware.smack.proxy; + +import java.io.BufferedReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.StringReader; +import java.net.HttpURLConnection; +import java.net.InetAddress; +import java.net.Socket; +import java.net.UnknownHostException; +import javax.net.SocketFactory; +import org.jivesoftware.smack.util.StringUtils; + +import java.util.regex.Matcher; +import java.util.regex.Pattern; + +/** + * Http Proxy Socket Factory which returns socket connected to Http Proxy + * + * @author Atul Aggarwal + */ +class HTTPProxySocketFactory + extends SocketFactory +{ + + private ProxyInfo proxy; + + public HTTPProxySocketFactory(ProxyInfo proxy) + { + this.proxy = proxy; + } + + public Socket createSocket(String host, int port) + throws IOException, UnknownHostException + { + return httpProxifiedSocket(host, port); + } + + public Socket createSocket(String host ,int port, InetAddress localHost, + int localPort) + throws IOException, UnknownHostException + { + return httpProxifiedSocket(host, port); + } + + public Socket createSocket(InetAddress host, int port) + throws IOException + { + return httpProxifiedSocket(host.getHostAddress(), port); + + } + + public Socket createSocket( InetAddress address, int port, + InetAddress localAddress, int localPort) + throws IOException + { + return httpProxifiedSocket(address.getHostAddress(), port); + } + + private Socket httpProxifiedSocket(String host, int port) + throws IOException + { + String proxyhost = proxy.getProxyAddress(); + int proxyPort = proxy.getProxyPort(); + Socket socket = new Socket(proxyhost,proxyPort); + String hostport = "CONNECT " + host + ":" + port; + String proxyLine; + String username = proxy.getProxyUsername(); + if (username == null) + { + proxyLine = ""; + } + else + { + String password = proxy.getProxyPassword(); + proxyLine = "\r\nProxy-Authorization: Basic " + StringUtils.encodeBase64(username + ":" + password); + } + socket.getOutputStream().write((hostport + " HTTP/1.1\r\nHost: " + + hostport + proxyLine + "\r\n\r\n").getBytes("UTF-8")); + + InputStream in = socket.getInputStream(); + StringBuilder got = new StringBuilder(100); + int nlchars = 0; + + while (true) + { + char c = (char) in.read(); + got.append(c); + if (got.length() > 1024) + { + throw new ProxyException(ProxyInfo.ProxyType.HTTP, "Recieved " + + "header of >1024 characters from " + + proxyhost + ", cancelling connection"); + } + if (c == -1) + { + throw new ProxyException(ProxyInfo.ProxyType.HTTP); + } + if ((nlchars == 0 || nlchars == 2) && c == '\r') + { + nlchars++; + } + else if ((nlchars == 1 || nlchars == 3) && c == '\n') + { + nlchars++; + } + else + { + nlchars = 0; + } + if (nlchars == 4) + { + break; + } + } + + if (nlchars != 4) + { + throw new ProxyException(ProxyInfo.ProxyType.HTTP, "Never " + + "received blank line from " + + proxyhost + ", cancelling connection"); + } + + String gotstr = got.toString(); + + BufferedReader br = new BufferedReader(new StringReader(gotstr)); + String response = br.readLine(); + + if (response == null) + { + throw new ProxyException(ProxyInfo.ProxyType.HTTP, "Empty proxy " + + "response from " + proxyhost + ", cancelling"); + } + + Matcher m = RESPONSE_PATTERN.matcher(response); + if (!m.matches()) + { + throw new ProxyException(ProxyInfo.ProxyType.HTTP , "Unexpected " + + "proxy response from " + proxyhost + ": " + response); + } + + int code = Integer.parseInt(m.group(1)); + + if (code != HttpURLConnection.HTTP_OK) + { + throw new ProxyException(ProxyInfo.ProxyType.HTTP); + } + + return socket; + } + + private static final Pattern RESPONSE_PATTERN + = Pattern.compile("HTTP/\\S+\\s(\\d+)\\s(.*)\\s*"); + +} |