Problem when using the HTTP client with SSL through a proxy

Giovanni giovanni.mels at agfa.com
Mon Aug 16 05:12:25 EDT 2010


Hi,

I am trying to extend the async HTTP client example so it works using SSL
and through a proxy.

Here is my code:


	URI uri = new URI("https://...");
	String username = "...";
	char[] password = "...".toCharArray();

	String scheme = uri.getScheme();

	boolean ssl = scheme.equalsIgnoreCase("https");

	// Configure the client.
	ClientBootstrap bootstrap = new ClientBootstrap(
		new NioClientSocketChannelFactory(Executors.newCachedThreadPool(),
Executors.newCachedThreadPool()));

	// Set up the event pipeline factory.

	SSLContext sslContext = null; 
	File keystore = new File("...");
	char[] keyStorepass = "...".toCharArray();
	if (ssl) {
		FileInputStream in = new FileInputStream(keystore);
		sslContext = loadSSLContext(in, keyStorepass);
		in.close();  	
	}

	bootstrap.setPipelineFactory(new HttpClientPipelineFactory(sslContext));


	Proxy proxy = new Proxy(Type.HTTP, new InetSocketAddress("localhost",
5865));
	// Start the connection attempt.
	ChannelFuture future = bootstrap.connect(proxy.address());

	// Wait until the connection attempt succeeds or fails.
	Channel channel = future.awaitUninterruptibly().getChannel();
	if (!future.isSuccess()) {
		future.getCause().printStackTrace();
		bootstrap.releaseExternalResources();
		return;
	}



	log.info("connected to proxy!");

	// Prepare the HTTP request.
	HttpRequest request = new DefaultHttpRequest(HttpVersion.HTTP_1_1,
HttpMethod.CONNECT, uri.getHost() + ":" + uri.getPort());

	System.out.println(request);

	// Send the HTTP request.
	ChannelFuture connect = channel.write(request);
	connect.awaitUninterruptibly();
	if (!connect.isSuccess()) {
		System.out.println("connect failed: " + connect.getCause());
		// connect.getCause().printStackTrace();
		bootstrap.releaseExternalResources();
		return;
	}

	System.out.println("---------------------------------------------------");

	request = new DefaultHttpRequest(HttpVersion.HTTP_1_1, HttpMethod.GET,
uri.getPath());
	request.setHeader(HttpHeaders.Names.HOST, uri.getHost() + ":" +
uri.getPort());
	request.setHeader(HttpHeaders.Names.AUTHORIZATION,
createAuthorizationString(username, password));
	ChannelFuture get = channel.write(request);
	get.awaitUninterruptibly();
	if (!get.isSuccess()) {
		System.out.println("get failed: " + connect.getCause());
		get.getCause().printStackTrace();
		bootstrap.releaseExternalResources();
		return;
	}
	

	System.out.println("---------------------------------------------------");

	// Wait for the server to close the connection.
	channel.getCloseFuture().awaitUninterruptibly();

	// Shut down executor threads to exit.
	bootstrap.releaseExternalResources();


I also changed HttpClientPipelineFactory so the first write message (the
connection to the proxy) isn't encrypted

	SSLEngine engine = ssl.createSSLEngine();
	engine.setUseClientMode(true);

	pipeline.addLast("ssl", new SslHandler(engine, true));


When I run my code, I get this exception:


16-aug-2010 9:55:11 org.jboss.netty.channel.SimpleChannelUpstreamHandler
WARNING: EXCEPTION, please implement
test.netty.HttpResponseHandler.exceptionCaught() for proper handling.
javax.net.ssl.SSLException: not an SSL/TLS record:
485454502f312e312032303020436f6e6e656374696f6e2065737461626c69736865640d0a0d0a
	at org.jboss.netty.handler.ssl.SslHandler.decode(SslHandler.java:576)
	at
org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:282)
	at
org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:216)
	at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
	at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
	at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349)
	at
org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:281)
	at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:201)
	at
org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:619)


Note that
485454502f312e312032303020436f6e6e656374696f6e2065737461626c69736865640d0a0d0a
is a hexdump for
"HTTP/1.1 200 Connection established".

The result from the server seems to be ok,


STATUS: 200 OK
VERSION: HTTP/1.1

HEADER: Cache-Control = no-cache
HEADER: Cache-Control = no-cache
HEADER: Content-Length = 3924
HEADER: Content-Type = text/html;charset=utf-8
HEADER: Date = Mon, 16 Aug 2010 07:55:10 GMT
HEADER: Expires = Thu, 01 Jan 1970 01:00:00 CET
HEADER: Pragma = No-cache
HEADER: Pragma = no-cache
HEADER: Server = Apache-Coyote/1.1
HEADER: Vary = Accept, User-Agent

	
but reading the content gives another exception:


16-aug-2010 9:55:12 org.jboss.netty.channel.SimpleChannelUpstreamHandler
WARNING: EXCEPTION, please implement
test.netty.HttpResponseHandler.exceptionCaught() for proper handling.
java.lang.ClassCastException:
org.jboss.netty.buffer.BigEndianHeapChannelBuffer cannot be cast to
org.jboss.netty.handler.codec.http.HttpResponse
	at
test.netty.HttpResponseHandler.messageReceived(HttpResponseHandler.java:40)
	at
org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:131)
	at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:302)
	at
org.jboss.netty.handler.codec.replay.ReplayingDecoder.unfoldAndfireMessageReceived(ReplayingDecoder.java:513)
	at
org.jboss.netty.handler.codec.replay.ReplayingDecoder.callDecode(ReplayingDecoder.java:497)
	at
org.jboss.netty.handler.codec.replay.ReplayingDecoder.messageReceived(ReplayingDecoder.java:434)
	at
org.jboss.netty.handler.codec.http.HttpClientCodec.handleUpstream(HttpClientCodec.java:77)
	at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:302)
	at
org.jboss.netty.handler.codec.frame.FrameDecoder.unfoldAndFireMessageReceived(FrameDecoder.java:317)
	at
org.jboss.netty.handler.codec.frame.FrameDecoder.callDecode(FrameDecoder.java:299)
	at
org.jboss.netty.handler.codec.frame.FrameDecoder.messageReceived(FrameDecoder.java:214)
	at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:274)
	at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:261)
	at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:349)
	at
org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:281)
	at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:201)
	at
org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:619)
16-aug-2010 9:56:12 org.jboss.netty.channel.SimpleChannelUpstreamHandler
WARNING: EXCEPTION, please implement
test.netty.HttpResponseHandler.exceptionCaught() for proper handling.
java.lang.ClassCastException:
org.jboss.netty.buffer.BigEndianHeapChannelBuffer cannot be cast to
org.jboss.netty.handler.codec.http.HttpResponse
	at
test.netty.HttpResponseHandler.messageReceived(HttpResponseHandler.java:40)
	at
org.jboss.netty.handler.codec.http.HttpContentDecoder.messageReceived(HttpContentDecoder.java:131)
	at org.jboss.netty.channel.Channels.fireMessageReceived(Channels.java:302)
	at
org.jboss.netty.handler.codec.replay.ReplayingDecoder.unfoldAndfireMessageReceived(ReplayingDecoder.java:513)
	at
org.jboss.netty.handler.codec.replay.ReplayingDecoder.cleanup(ReplayingDecoder.java:540)
	at
org.jboss.netty.handler.codec.replay.ReplayingDecoder.channelDisconnected(ReplayingDecoder.java:440)
	at
org.jboss.netty.handler.codec.http.HttpClientCodec.handleUpstream(HttpClientCodec.java:77)
	at
org.jboss.netty.handler.codec.frame.FrameDecoder.cleanup(FrameDecoder.java:344)
	at
org.jboss.netty.handler.codec.frame.FrameDecoder.channelDisconnected(FrameDecoder.java:226)
	at
org.jboss.netty.handler.ssl.SslHandler.channelDisconnected(SslHandler.java:462)
	at
org.jboss.netty.channel.Channels.fireChannelDisconnected(Channels.java:360)
	at org.jboss.netty.channel.socket.nio.NioWorker.close(NioWorker.java:598)
	at
org.jboss.netty.channel.socket.nio.NioClientSocketPipelineSink.eventSunk(NioClientSocketPipelineSink.java:91)
	at org.jboss.netty.channel.Channels.close(Channels.java:736)
	at
org.jboss.netty.handler.ssl.SslHandler.exceptionCaught(SslHandler.java:504)
	at org.jboss.netty.channel.Channels.fireExceptionCaught(Channels.java:432)
	at org.jboss.netty.channel.socket.nio.NioWorker.read(NioWorker.java:332)
	at
org.jboss.netty.channel.socket.nio.NioWorker.processSelectedKeys(NioWorker.java:281)
	at org.jboss.netty.channel.socket.nio.NioWorker.run(NioWorker.java:201)
	at
org.jboss.netty.util.internal.IoWorkerRunnable.run(IoWorkerRunnable.java:46)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
	at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
	at java.lang.Thread.run(Thread.java:619)


First, I am new to netty, and I am not sure this is the way to do it. If
there is a better way, please let me know, if not, what am I doing wrong
here?

Thanks,

Giovanni
-- 
View this message in context: http://netty-forums-and-mailing-lists.685743.n2.nabble.com/Problem-when-using-the-HTTP-client-with-SSL-through-a-proxy-tp5427188p5427188.html
Sent from the Netty User Group mailing list archive at Nabble.com.


More information about the netty-users mailing list