/*
* This file is part of the OWASP Proxy, a free intercepting proxy library.
* Copyright (C) 2008-2010 Rogan Dawes <rogan@dawes.za.net>
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to:
* The Free Software Foundation, Inc.,
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*
*/
package org.owasp.proxy.http.server;
import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
import java.net.ProxySelector;
import java.net.SocketAddress;
import org.owasp.proxy.daemon.ServerGroup;
import org.owasp.proxy.http.MessageFormatException;
import org.owasp.proxy.http.MessageUtils;
import org.owasp.proxy.http.StreamingRequest;
import org.owasp.proxy.http.StreamingResponse;
import org.owasp.proxy.http.client.HttpClient;
import org.owasp.proxy.io.TimingInputStream;
public class DefaultHttpRequestHandler implements HttpRequestHandler {
private ProxySelector proxySelector = null;
private ServerGroup serverGroup = null;
private ThreadLocal<HttpClient> client = new ThreadLocal<HttpClient>() {
/*
* (non-Javadoc)
*
* @see java.lang.ThreadLocal#initialValue()
*/
@Override
protected HttpClient initialValue() {
return createClient();
}
};
public void setServerGroup(ServerGroup serverGroup) {
this.serverGroup = serverGroup;
}
public void setProxySelector(ProxySelector proxySelector) {
this.proxySelector = proxySelector;
}
protected HttpClient createClient() {
HttpClient client = new HttpClient() {
/*
* (non-Javadoc)
*
* @see org.owasp.httpclient.Client#checkLoop(java.net.SocketAddress)
*/
@Override
protected void validateTarget(SocketAddress target)
throws IOException {
if (serverGroup != null && target instanceof InetSocketAddress
&& serverGroup.wouldAccept((InetSocketAddress) target))
throw new IOException("Loop detected");
}
};
client.setProxySelector(proxySelector);
return client;
}
/*
* (non-Javadoc)
*
* @see org.owasp.proxy.daemon.HttpRequestHandler#dispose()
*/
public void dispose() throws IOException {
client.get().disconnect();
}
/*
* (non-Javadoc)
*
* @see org.owasp.proxy.daemon.HttpRequestHandler#handleRequest(java.net.InetAddress ,
* org.owasp.httpclient.StreamingRequest)
*/
public StreamingResponse handleRequest(InetAddress source,
StreamingRequest request, boolean isContinue) throws IOException,
MessageFormatException {
HttpClient client = this.client.get();
if (isContinue) {
client.sendRequestContent(request.getContent());
} else {
client.connect(request.getTarget(), request.isSsl());
client.sendRequestHeader(request.getHeader());
if (request.getContent() != null)
client.sendRequestContent(request.getContent());
}
request.setTime(client.getRequestTime());
StreamingResponse response = new StreamingResponse.Impl();
response.setHeader(client.getResponseHeader());
response.setHeaderTime(client.getResponseHeaderEndTime());
// handle unsolicited 100-continue responses
if (!MessageUtils.isExpectContinue(request)
&& "100".equals(response.getStatus())) {
byte[] cont = response.getHeader();
byte[] header = client.getResponseHeader();
response.setHeaderTime(client.getResponseHeaderEndTime());
byte[] both = new byte[cont.length + header.length];
System.arraycopy(cont, 0, both, 0, cont.length);
System.arraycopy(header, 0, both, cont.length + 1, header.length);
response.setHeader(both);
}
InputStream content = client.getResponseContent();
if (content != null)
content = new TimingInputStream(content, response);
response.setContent(content);
return response;
}
}