Does Smack support for HTTP-Proxy Connection?

Hello to All,

I am using Smack library for connection to server in my application.

Now the protocol type of my proxy is HTTP. I am able to connect if there is no proxy. But I want to connect through HTTP proxy because we are using HTTP Proxy.

For Direct Connection (Without proxy) I wrote:

connection = new XMPPConnection(“Proxy server”, port);

Can anybody help me to connect through HTTP Proxy??

Thanks in Advance

Hi pathik,

no it doesn’'t. XMPP is not HTTP and thus even if Smack could establish a connection to a proxy the proxy would have a little problem to know what to do, see also http://www.jivesoftware.org/community/thread.jspa?threadID=21910

There’‘s afaik currently also no option to use HTTPS/connect for the old SSL method, if you search for “proxy” you’'ll find some very old threads like http://www.jivesoftware.org/community/thread.jspa?messageID=115282

LG

Smack currently only supports SOCKS proxies (via Java’'s built-in transparent proxy support).

it2000 wrote:

no it doesn’'t. XMPP is not HTTP and thus even if Smack could establish a connection to a proxy the proxy would have a little problem to know what to do

Well, there’'s a standard for XMPP-over-HTTP, which should work fine via HTTP proxies. However, that method is not supported by Smack yet.

Thanks for Reply

But I am very confuse regarding my problem because these things are new for me.

I am using XMPP for information transfer form my application to Server. And in between HTTP proxy is there. My application is desktop application. To send information to server, First I have to connect to server.

Now According to Reply XMPP does not support HTTP Proxy. Is there any solution of this problem? And what I should do?

PLease Guide me.

Pathik

Message was edited by: pathik

iampathik wrote:

But I am very confuse regarding my problem because these things are new for me.

I am using XMPP for information transfer form my application to Server. And in between HTTP proxy is there. My application is desktop application. To send information to server, First I have to connect to server.

Now According to Reply XMPP does not support HTTP Proxy. Is there any solution of this problem? And what I should do?

You can use JWChat as a guide on how to use XMPP-over-HTTP. However, you need a proxy service on the server side (like the one that ships with JWChat), which translates it back to XMPP. Maybe someday WildFire will have that built-in.

Hello Andreas,

I study JWChat but I am little confuse because JWChat is web based application and my application is Desktop application.

JWChat is web-based Jabber messenger and i think it used smack library. It is also work fine in HTTP. That means there should be some way which can be useful in desktop application also to cross HTTP proxy. BUT I am not getting that.

Let me know that my thinking is going to correct way or not.

Thank you

iampathik wrote:

I study JWChat but I am little confuse because JWChat is web based application and my application is Desktop application.

Well, it’'s still a client-side application, that happens to run inside another application (a web browser). No magic going on.

JWChat is web-based Jabber messenger and i think it used smack library.

No, JWChat is written in ECMAScript, so it can’'t use a Java library.

It is also work fine in HTTP. That means there should be some way which can be useful in desktop application also to cross HTTP proxy.

Yep, there is XEP-0124, which defines a standard for it. Unfortunatly, neither Smack nor Wildfire support it yet (but there are 3rd party applications that can proxy between HTTP and Wildfire).

Thanks Andreas,

That means 3rd party applications can solve my problem. Can you give me some application names that can help me in this problem please.

And what you think in future Smack and Wildfire have solution for this type of problem ?

iampathik wrote:

That means 3rd party applications can solve my problem. Can you give me some application names that can help me in this problem please.

I’'m using PunJab. Another options is JabberHTTPBind.

A XMPP-over-HTTP client library is JSJaC.

And what you think in future Smack and Wildfire have solution for this type of problem ?

All I know is that there are tickets filed for that.

Hi Pathik,

does the proxy you use allow HTTP CONNECT?

I did add a dirty hack to the Smack 3.x source code to do this (hard coded proxy, …) and it seems to work.

I’‘ll post it here so you can do what you want with it. I’'m not sure that it will be added to Smack.

Make sure to connect to :5223 (SSL-Port).

LG

//ConnectionConfiguration.java - new method:
    public Socket setProxy(String proxyHost, String proxyPort, String host, int port)
    {
        System.setProperty("java.protocol.handler.pkgs", "com.sun.net.ssl.internal.www.protocol");
        System.setProperty("https.proxyHost", proxyHost);
        System.setProperty("https.proxyPort", proxyPort);
        SSLTunnelSocketFactory SSLTSF = new SSLTunnelSocketFactory(proxyHost,proxyPort);
        Socket s = null;
        try {
          } catch (Exception e) {
               e.printStackTrace();
          }
          return s;
    } //XMPPConnection.java - connectUsingConfiguration()
//change
                    if (config.getSocketFactory() == null) {
                          this.socket = new Socket(host, port);
                    } else
                    {
                          this.socket = config.getSocketFactory().createSocket(host, port);
                    }
//to
                    this.socket = config.setProxy("10.1.1.1", "8080", host, port); //SSLTunnelSocketFactory.java - new class:
package org.jivesoftware.smack.util; import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.UnsupportedEncodingException;
import java.net.InetAddress;
import java.net.Socket;
import java.net.UnknownHostException;
import javax.net.ssl.HandshakeCompletedEvent;
import javax.net.ssl.HandshakeCompletedListener;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager; public class SSLTunnelSocketFactory extends SSLSocketFactory
{
   private SSLSocketFactory dfactory;
   private String tunnelHost;
   private int tunnelPort;     public SSLTunnelSocketFactory(String proxyhost, String proxyport){
      tunnelHost = proxyhost;
      tunnelPort = Integer.parseInt(proxyport);
    }     public Socket createSocket(String host, int port)
                              throws IOException, UnknownHostException
   {
      return createSocket(null,host,port,true);
   }    public Socket createSocket(String host,int port,InetAddress clientHost,
                              int clientPort)
                              throws IOException,UnknownHostException
   {
      return createSocket(null,host,port,true);
   }     public Socket createSocket(InetAddress host,int port)
                              throws IOException
   {
      return createSocket(null,host.getHostName(),port,true);
   }     public Socket createSocket(InetAddress address,int port,
                              InetAddress clientAddress,int clientPort)
                              throws IOException
   {
      return createSocket(null,address.getHostName(),port,true);
   }
   public Socket createSocket(Socket s, String host, int port,                               boolean autoClose)                               throws IOException,UnknownHostException
   {
         Socket tunnel = new Socket(tunnelHost,tunnelPort);
            doTunnelHandshake(tunnel,host,port);
      SSLContext sslContext = null;
      try {
          sslContext = SSLContext.getInstance("SSL");
          sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
      } catch (Exception e) {
      }
      dfactory = sslContext.getSocketFactory();           SSLSocket result = (SSLSocket)dfactory.createSocket(
                                       tunnel,host,port,autoClose);
       result.addHandshakeCompletedListener(
         new HandshakeCompletedListener() {
         public void handshakeCompleted(HandshakeCompletedEvent event) {
            System.out.println("Handshake finished!");
            System.out.println(
            "\t CipherSuite:" + event.getCipherSuite());
            System.out.println(
            "\t SessionId " + event.getSession());
            System.out.println(
            "\t PeerHost " + event.getSession().getPeerHost());
         }
         }
      );
      result.startHandshake();         return result;
   }      private void doTunnelHandshake(Socket tunnel, String host, int port)
                                    throws IOException
   {
      OutputStream out = tunnel.getOutputStream();
      String msg = "CONNECT " + host + ":" + port + " HTTP/1.0\n"
                  + "User-Agent: "
                  + sun.net.www.protocol.http.HttpURLConnection.userAgent
                  + "\r\n\r\n";
      byte b[];
      try {
         b = msg.getBytes("ASCII7");
      } catch (UnsupportedEncodingException ignored) {
         b = msg.getBytes();
      }
      out.write(b);
      out.flush();
      byte          reply[] = new byte[200];
      int          replyLen = 0;
      int          newlinesSeen = 0;
      boolean          headerDone = false;     /* Done on first newline */          InputStream     in = tunnel.getInputStream();
       while (newlinesSeen < 2) {
         int i = in.read();
         if (i < 0) {
            throw new IOException("Unexpected EOF from proxy");
         }
         if (i == ''\n'') {
            headerDone = true;
            ++newlinesSeen;
         } else if (i != ''\r'') {
            newlinesSeen = 0;
            if (!headerDone && replyLen < reply.length) {
               reply[replyLen++] = (byte) i;
            }
         }
      }
      String replyStr;
      try {
         replyStr = new String(reply, 0, replyLen, "ASCII7");
      } catch (UnsupportedEncodingException ignored) {
         replyStr = new String(reply, 0, replyLen);
      }
      if(replyStr.toLowerCase().indexOf("200 connection established") == -1){
         throw new IOException("Unable to tunnel through "
                                + tunnelHost + ":" + tunnelPort
                                + ".  Proxy returns \"" + replyStr + "\"");
      }
   }     public String[] getDefaultCipherSuites(){
      return dfactory.getDefaultCipherSuites();
   }    public String[] getSupportedCipherSuites(){
      return dfactory.getSupportedCipherSuites();
   }
   TrustManager[] trustAllCerts = new TrustManager[]{
       new X509TrustManager() {
           public java.security.cert.X509Certificate[] getAcceptedIssuers() {
               return null;
           }
           public void checkClientTrusted(
               java.security.cert.X509Certificate[] certs, String authType) {
           }
           public void checkServerTrusted(
               java.security.cert.X509Certificate[] certs, String authType) {
           }
       }
   };
}

Hi,

I just compiled smack-dev-2006-10-06 and the genereated jar files work great with Spark 2.0.2 (I did set the port manually to 5223). I need some further testing, up to now it looks fine.

LG

Hi LG,

Here Protocol of proxy is HTTP. And I think it will support HTTP Connection but I never try this thing So I have to see this.

I try to run code guide by you but it is giving me error for SSLTunnelSocketFactory.java for

if (!headerDone && replyLen < reply.length) {

reply[replyLen++] = (byte) i;

}

error:

C:\Documents and Settings\Administrator\Desktop\JBother-0.8.9\JBother\build\SSLTunnelSocketFacto ry.java:113: illegal character: \35

if (!headerDone && replyLen < reply.length) {

^

C:\Documents and Settings\Administrator\Desktop\JBother-0.8.9\JBother\build\SSLTunnelSocketFacto ry.java:113: ‘’)’’ expected

if (!headerDone && replyLen < reply.length) {

^

C:\Documents and Settings\Administrator\Desktop\JBother-0.8.9\JBother\build\SSLTunnelSocketFacto ry.java:113: illegal start of expression

if (!headerDone && replyLen < reply.length) {

^

C:\Documents and Settings\Administrator\Desktop\JBother-0.8.9\JBother\build\SSLTunnelSocketFacto ry.java:113: illegal character: \35

if (!headerDone && replyLen < reply.length) {

^

C:\Documents and Settings\Administrator\Desktop\JBother-0.8.9\JBother\build\SSLTunnelSocketFacto ry.java:113: > expected

if (!headerDone && replyLen < reply.length) {

^

C:\Documents and Settings\Administrator\Desktop\JBother-0.8.9\JBother\build\SSLTunnelSocketFacto ry.java:113: not a statement

if (!headerDone && replyLen < reply.length) {

^

Does Spark 2.0.2 is working good with HTTP Proxy using compiled smack-dev-2006-10-06 ? If yes than it is good news.

please guide me to solve this error.

Thanks

Hi,

did you change " & # 3 8 ; & # 3 8 ; " to " && " in your code?

The forum displays & within source code as & # 3 8 ; which is really annoying and already reported here: http://www.jivesoftware.org/community/thread.jspa?threadID=21216

LG