/**
 * Copyright 2011-2012 eBusiness Information, Groupe Excilys (www.excilys.com)
 *
 * 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 com.excilys.ebi.gatling.recorder.http.handler;

import static com.excilys.ebi.gatling.recorder.http.event.RecorderEventBus.getEventBus;

import org.jboss.netty.channel.ChannelFuture;
import org.jboss.netty.channel.ChannelFutureListener;
import org.jboss.netty.channel.ChannelHandlerContext;
import org.jboss.netty.channel.ExceptionEvent;
import org.jboss.netty.channel.MessageEvent;
import org.jboss.netty.channel.SimpleChannelHandler;
import org.jboss.netty.handler.codec.http.HttpRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.excilys.ebi.gatling.recorder.http.event.MessageReceivedEvent;
import com.excilys.ebi.gatling.recorder.http.event.RequestReceivedEvent;

public abstract class AbstractBrowserRequestHandler extends SimpleChannelHandler {

	private static final Logger LOGGER = LoggerFactory.getLogger(AbstractBrowserRequestHandler.class);

	protected final String outgoingProxyHost;
	protected final int outgoingProxyPort;

	public AbstractBrowserRequestHandler(String outgoingProxyHost, int outgoingProxyPort) {
		this.outgoingProxyHost = outgoingProxyHost;
		this.outgoingProxyPort = outgoingProxyPort;
	}

	@Override
	public void messageReceived(ChannelHandlerContext ctx, MessageEvent event) throws Exception {

		getEventBus().post(new MessageReceivedEvent(ctx.getChannel()));

		HttpRequest request = HttpRequest.class.cast(event.getMessage());

		// remove Proxy-Connection header if it's not significant
		if (outgoingProxyHost == null)
			request.removeHeader("Proxy-Connection");

		ChannelFuture future = connectToServerOnBrowserRequestReceived(ctx, request);

		getEventBus().post(new RequestReceivedEvent(request));

		sendRequestToServerAfterConnection(future, request);
	}

	protected abstract ChannelFuture connectToServerOnBrowserRequestReceived(ChannelHandlerContext ctx, HttpRequest request) throws Exception;

	@Override
	public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
		LOGGER.error("Exception caught", e.getCause());

		// Properly closing
		ChannelFuture future = ctx.getChannel().getCloseFuture();
		future.addListener(new ChannelFutureListener() {
			@Override
			public void operationComplete(ChannelFuture future) throws Exception {
				future.getChannel().close();
			}
		});
		ctx.sendUpstream(e);
	}

	private void sendRequestToServerAfterConnection(ChannelFuture future, final HttpRequest request) {
		if (future != null)
			future.addListener(new ChannelFutureListener() {
				@Override
				public void operationComplete(ChannelFuture future) throws Exception {
					future.getChannel().write(request);
				}
			});
	}
}

@@ -781,16 +781,102 @@
 ntBus;%0A%0A
+import java.net.URI;%0Aimport java.net.URISyntaxException;%0Aimport java.util.Map.Entry;%0A%0A
 import o
@@ -1162,24 +1162,86 @@
 nelHandler;%0A
+import org.jboss.netty.handler.codec.http.DefaultHttpRequest;%0A
 import org.j
@@ -3368,24 +3368,140 @@
 Exception %7B%0A
+%09%09%09%09%09// once connected, must use a relative URI%0A%09%09%09%09%09HttpRequest newRequest = buildRequestWithRelativeURI(request);%0A
 %09%09%09%09%09future.
@@ -3519,17 +3519,20 @@
 ).write(
-r
+newR
 equest);
@@ -3547,11 +3547,614 @@
 %09%09%7D);%0A%09%7D
+%0A%0A%09private HttpRequest buildRequestWithRelativeURI(HttpRequest request) throws URISyntaxException %7B%0A%09%09URI uri = new URI(request.getUri());%0A%09%09String newUri = new URI(null, null, null, -1, uri.getPath(), uri.getQuery(), uri.getFragment()).toString();%0A%09%09DefaultHttpRequest newRequest = new DefaultHttpRequest(request.getProtocolVersion(), request.getMethod(), newUri);%0A%09%09newRequest.setChunked(request.isChunked());%0A%09%09newRequest.setContent(request.getContent());%0A%09%09for (Entry%3CString, String%3E header : request.getHeaders())%0A%09%09%09newRequest.addHeader(header.getKey(), header.getValue());%0A%09%09return newRequest;%0A%09%7D
 %0A%7D%0A

Use relative URIs once connected, close #489