0
votes
java - Netty HTTP Authetication for Client - Stack Overflow
Asked
Viewed 6k times
0

Look at the test code I have written below. Using pure java I set an Authenticator and make a URI call to get some xml data and convert it to an object.

I wrote the code below to test performance of hotpotato (netty) vs. pure java (no pipelining).

The trouble is, I can't figure out how to Authenticate my request with hotpotato or netty, code for either is acceptable, I just want to test the performance diff (i.e. see how many requests will be performed in 5 seconds).

    public static void main(String[] args) throws Exception {
        Authenticator.setDefault(new MyAuthenticator("DummyUser", "DummyPassword"));

        int timeToTestFor = 5000; //5 seconds;
        int count = 0;
        System.out.println("Start time");
        long starttime = System.currentTimeMillis();
        do {
            URL url = new URL(
                    "http://example.com/rest/GetData.ashx?what=pizza&where=new%20york&visitorId=12345&sessionId=123456");

            SearchResultsDocument doc = SearchResultsDocument.Factory.parse(url);
            count++;
        } while (System.currentTimeMillis() - starttime < timeToTestFor);
        System.out.println("DONE Total count=" + count);

        System.out.println("Netty/Hotpotatoe Start time");
        count = 0;
        starttime = System.currentTimeMillis();
        do {
            // Create & initialise the client
            HttpClient client = new DefaultHttpClient();
            client.init();


            // Setup the request
            HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_0,
                    HttpMethod.GET, "/rest/GetData.ashx?what=pizza&where=new%20york&visitorId=12345&sessionId=123456");

            // Execute the request, turning the result into a String
            HttpRequestFuture future = client.execute("example.com", 80, request,
                    new BodyAsStringProcessor());
            future.awaitUninterruptibly();
            // Print some details about the request
            System.out.println("A >> " + future);

            // If response was >= 200 and <= 299, print the body
            if (future.isSuccessfulResponse()) {
                System.out.println("B >> "+future.getProcessedResult());
            }

            // Cleanup
            client.terminate();
            count++;
        } while (System.currentTimeMillis() - starttime < timeToTestFor);
        System.out.println("DONE Total count=" + count);
    }
    2

    Here is working example of using basic authentication with Netty only. Tested with Jetty as a server requiring basic authentication.

    import java.net.InetSocketAddress;
    import java.util.concurrent.Executors;
    
    import org.jboss.netty.bootstrap.ClientBootstrap;
    import org.jboss.netty.buffer.ChannelBuffer;
    import org.jboss.netty.buffer.ChannelBuffers;
    import org.jboss.netty.channel.ChannelHandlerContext;
    import org.jboss.netty.channel.ChannelPipeline;
    import org.jboss.netty.channel.ChannelPipelineFactory;
    import org.jboss.netty.channel.Channels;
    import org.jboss.netty.channel.ExceptionEvent;
    import org.jboss.netty.channel.MessageEvent;
    import org.jboss.netty.channel.SimpleChannelHandler;
    import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
    import org.jboss.netty.handler.codec.base64.Base64;
    import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
    import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
    import org.jboss.netty.handler.codec.http.HttpClientCodec;
    import org.jboss.netty.handler.codec.http.HttpHeaders;
    import org.jboss.netty.handler.codec.http.HttpMethod;
    import org.jboss.netty.handler.codec.http.HttpResponse;
    import org.jboss.netty.handler.codec.http.HttpVersion;
    import org.jboss.netty.util.CharsetUtil;
    
    public class BasicAuthTest {
    private static final int PORT = 80;
    private static final String USERNAME = "";
    private static final String PASSWORD = "";
    private static final String URI = "";
    private static final String HOST = "";
    
    public static void main(String[] args) {
    
        ClientBootstrap client = new ClientBootstrap(
                new NioClientSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));
    
        client.setPipelineFactory(new ChannelPipelineFactory() {
    
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = Channels.pipeline();
                pipeline.addLast("codec", new HttpClientCodec());
                pipeline.addLast("aggregator", new HttpChunkAggregator(5242880));
                pipeline.addLast("authHandler", new ClientMessageHandler());
                return pipeline;
            }
        });
    
        DefaultHttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, URI);
    
        request.addHeader(HttpHeaders.Names.HOST, HOST);
    
        String authString = USERNAME + ":" + PASSWORD;
        ChannelBuffer authChannelBuffer = ChannelBuffers.copiedBuffer(authString, CharsetUtil.UTF_8);
        ChannelBuffer encodedAuthChannelBuffer = Base64.encode(authChannelBuffer);
        request.addHeader(HttpHeaders.Names.AUTHORIZATION, encodedAuthChannelBuffer.toString(CharsetUtil.UTF_8));
    
        client.connect(new InetSocketAddress(HOST, PORT)).awaitUninterruptibly().getChannel()
                .write(request).awaitUninterruptibly();
    
    }
    
    public static class ClientMessageHandler extends SimpleChannelHandler {
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
            e.getCause().printStackTrace();
        }
    
        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
            HttpResponse httpResponse = (HttpResponse) e.getMessage();
            String json = httpResponse.getContent().toString(CharsetUtil.UTF_8);
            System.out.println(json);
        }
    }
    
    }
    
    4
    • Thanks, the example with a pipeline is much appreciated but is there a way to do it without using pipelining?
      – Ali
      Sep 30 2011 at 19:20
    • Oh wait, you use awaitUninterruptibly() I'm guessing this means the example is not using a pipeline?
      – Ali
      Sep 30 2011 at 19:23
    • Pipeline is used of cause. If you mean the pipeline with HttpClientCodec in it. This example is very crud and doesn't even stop the execution. It is just the illustration of the fact, that basic authentication is simply one header in the HttpRequest. (en.wikipedia.org/wiki/Basic_access_authentication)
      – Ivan Sopov
      Oct 1 2011 at 21:30
    • Thanks for this. It almost worked for me. Encoding gave chunked output, which was mitigated by adding a parameter: Base64.encode(authChannelBuffer, false). Also, the header value needed to be changed just a bit: request.addHeader(HttpHeaders.Names.AUTHORIZATION, "Basic " + encodedAuthChannelBuffer.toString(CharsetUtil.UTF_8));
      – Tinclon
      Apr 23 2013 at 21:23

    Your Answer

    By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

    Not the answer you're looking for? Browse other questions tagged or ask your own question.

     
    1

    1 Answers

    2
    votes

    Here is working example of using basic authentication with Netty only. Tested with Jetty as a server requiring basic authentication.

    import java.net.InetSocketAddress;
    import java.util.concurrent.Executors;
    
    import org.jboss.netty.bootstrap.ClientBootstrap;
    import org.jboss.netty.buffer.ChannelBuffer;
    import org.jboss.netty.buffer.ChannelBuffers;
    import org.jboss.netty.channel.ChannelHandlerContext;
    import org.jboss.netty.channel.ChannelPipeline;
    import org.jboss.netty.channel.ChannelPipelineFactory;
    import org.jboss.netty.channel.Channels;
    import org.jboss.netty.channel.ExceptionEvent;
    import org.jboss.netty.channel.MessageEvent;
    import org.jboss.netty.channel.SimpleChannelHandler;
    import org.jboss.netty.channel.socket.nio.NioClientSocketChannelFactory;
    import org.jboss.netty.handler.codec.base64.Base64;
    import org.jboss.netty.handler.codec.http.DefaultHttpRequest;
    import org.jboss.netty.handler.codec.http.HttpChunkAggregator;
    import org.jboss.netty.handler.codec.http.HttpClientCodec;
    import org.jboss.netty.handler.codec.http.HttpHeaders;
    import org.jboss.netty.handler.codec.http.HttpMethod;
    import org.jboss.netty.handler.codec.http.HttpResponse;
    import org.jboss.netty.handler.codec.http.HttpVersion;
    import org.jboss.netty.util.CharsetUtil;
    
    public class BasicAuthTest {
    private static final int PORT = 80;
    private static final String USERNAME = "";
    private static final String PASSWORD = "";
    private static final String URI = "";
    private static final String HOST = "";
    
    public static void main(String[] args) {
    
        ClientBootstrap client = new ClientBootstrap(
                new NioClientSocketChannelFactory(
                        Executors.newCachedThreadPool(),
                        Executors.newCachedThreadPool()));
    
        client.setPipelineFactory(new ChannelPipelineFactory() {
    
            @Override
            public ChannelPipeline getPipeline() throws Exception {
                ChannelPipeline pipeline = Channels.pipeline();
                pipeline.addLast("codec", new HttpClientCodec());
                pipeline.addLast("aggregator", new HttpChunkAggregator(5242880));
                pipeline.addLast("authHandler", new ClientMessageHandler());
                return pipeline;
            }
        });
    
        DefaultHttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET, URI);
    
        request.addHeader(HttpHeaders.Names.HOST, HOST);
    
        String authString = USERNAME + ":" + PASSWORD;
        ChannelBuffer authChannelBuffer = ChannelBuffers.copiedBuffer(authString, CharsetUtil.UTF_8);
        ChannelBuffer encodedAuthChannelBuffer = Base64.encode(authChannelBuffer);
        request.addHeader(HttpHeaders.Names.AUTHORIZATION, encodedAuthChannelBuffer.toString(CharsetUtil.UTF_8));
    
        client.connect(new InetSocketAddress(HOST, PORT)).awaitUninterruptibly().getChannel()
                .write(request).awaitUninterruptibly();
    
    }
    
    public static class ClientMessageHandler extends SimpleChannelHandler {
        @Override
        public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
            e.getCause().printStackTrace();
        }
    
        @Override
        public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
            HttpResponse httpResponse = (HttpResponse) e.getMessage();
            String json = httpResponse.getContent().toString(CharsetUtil.UTF_8);
            System.out.println(json);
        }
    }
    
    }