/*
* 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.daemon;
import static org.junit.Assert.assertTrue;
import static org.junit.Assert.fail;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.InetSocketAddress;
import java.net.Socket;
import java.net.SocketAddress;
import java.net.SocketException;
import java.net.SocketTimeoutException;
import java.net.URL;
import java.net.URLConnection;
import java.util.logging.Logger;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Ignore;
import org.junit.Test;
import org.owasp.proxy.http.server.DefaultHttpRequestHandler;
import org.owasp.proxy.http.server.HttpProxyConnectionHandler;
import org.owasp.proxy.http.server.HttpRequestHandler;
import org.owasp.proxy.test.TraceServer;
import org.owasp.proxy.util.AsciiString;
public class DefaultHttpProxyTest {
private static Logger logger = Logger.getAnonymousLogger();
private static TraceServer ts;
private InetSocketAddress listen;
private TargetedConnectionHandler ch;
private HttpRequestHandler rh;
@BeforeClass
public static void setUpBeforeClass() throws Exception {
try {
ts = new TraceServer(9999);
ts.start();
} catch (Exception e) {
e.printStackTrace();
}
}
@Before
public void setup() throws Exception {
listen = new InetSocketAddress("localhost", 9998);
rh = new DefaultHttpRequestHandler();
ch = new HttpProxyConnectionHandler(rh);
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
ts.stop();
Thread.sleep(1000);
assertTrue("TraceServer shutdown failed!", ts.isStopped());
}
@Test
public void testListenerStartStop() throws Exception {
Proxy proxy = new Proxy(listen, ch, null);
proxy.start();
Thread.sleep(1000);
proxy.stop();
assertTrue("Listener didn't exit", proxy.isStopped());
}
@Test
public void testRun() throws Exception {
Proxy proxy = new Proxy(listen, ch, null);
proxy.start();
java.net.Proxy p = new java.net.Proxy(java.net.Proxy.Type.HTTP,
new InetSocketAddress("localhost", 9998));
try {
URL url = new URL("http://localhost:9999/");
URLConnection uc = url.openConnection(p);
uc.connect();
InputStream is = uc.getInputStream();
byte buff[] = new byte[1024];
int got;
while ((got = is.read(buff)) > 0) {
logger.finer(AsciiString.create(buff, 0, got));
}
is.close();
uc = url.openConnection(p);
uc.setRequestProperty("Content-Length", "15");
uc.setDoOutput(true);
uc.connect();
OutputStream os = uc.getOutputStream();
os.write("123456789012345".getBytes());
os.close();
is = uc.getInputStream();
while ((got = is.read(buff)) > 0) {
logger.finer(AsciiString.create(buff, 0, got));
}
is.close();
// request.setPort(999);
// request.setMessage("POST / HTTP/1.0\r\nContent-Length: 15\r\n\r\n123456789012345".getBytes());
// // c =
// client.fetchResponse(request);
// // System.out.write(c.getResponse().getMessage());
} finally {
proxy.stop();
}
}
@Test
@Ignore("needs internet access")
public void testChunked() throws Exception {
ts.setChunked(true);
Proxy proxy = new Proxy(listen, ch, null);
proxy.start();
// try {
// Request request = new Request();
// request.setSsl(false);
// request.setHost("localhost");
// request.setPort(9999);
// request.setStartLine("GET /search?q=OWASP+Proxy&ie=utf-8&oe=utf-8&aq=t&rls=org.mozilla:en-US:official&client=firefox-a HTTP/1.1");
// request.addHeader("Host", "www.google.co.za");
//
// Conversation c = client.fetchResponse(request);
// System.out.write(c.getResponse().getMessage());
// assertEquals("response did not match request", request.getMessage(),
// c.getResponse().getContent());
// } finally {
proxy.stop();
// assertTrue("Listener didn't exit", l.isStopped());
// }
}
/*
* Tests to make sure that the listener correctly closes idle sockets. This test ensures that completely unused
* sockets get closed, e.g. the result of "telnet proxy port" + doing nothing
*/
@Test
@Ignore("needs internet access")
public void testInitialTimeout() throws Exception {
Proxy proxy = new Proxy(listen, ch, null);
proxy.setSocketTimeout(1000);
proxy.start();
try {
SocketAddress addr = new InetSocketAddress("localhost", 9998);
Socket s = new Socket(java.net.Proxy.NO_PROXY);
s.connect(addr);
Thread.sleep(2500);
OutputStream os = s.getOutputStream();
os.write("GET http://localhost:9999/ HTTP/1.0\r\n\r\n".getBytes());
os.flush();
s.setSoTimeout(500);
InputStream is = s.getInputStream();
int got;
byte[] buff = new byte[1024];
try {
while ((got = is.read(buff)) > 0) {
logger.finer(AsciiString.create(buff, 0, got));
}
} catch (SocketTimeoutException expected) {
} catch (SocketException expected) {
return;
}
s.close();
fail("Should not get here if the socket was timed out correctly!");
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
proxy.stop();
assertTrue("Listener didn't exit", proxy.isStopped());
}
}
/*
* tests to make sure that idle sockets get closed. This test ensures that "used" sockets get closed after the
* timeout period.
*/
@Test
@Ignore("needs internet access")
public void testSecondTimeout() throws Exception {
ts.setVersion("HTTP/1.1");
Proxy proxy = new Proxy(listen, ch, null);
proxy.setSocketTimeout(1000);
proxy.start();
try {
SocketAddress addr = new InetSocketAddress("localhost", 9998);
Socket s = new Socket(java.net.Proxy.NO_PROXY);
s.connect(addr);
OutputStream os = s.getOutputStream();
os
.write("GET http://localhost:9999/ HTTP/1.1\r\nHost: localhost\r\n\r\n"
.getBytes());
os.flush();
InputStream is = s.getInputStream();
s.setSoTimeout(500);
int got;
byte[] buff = new byte[1024];
try {
while ((got = is.read(buff)) > 0)
;
fail("Socket closed unexpectedly!");
} catch (SocketTimeoutException expected) {
logger.fine("Finished reading the first response via timeout");
}
logger.fine("Submitting second request\n\n");
try {
Thread.sleep(2000);
os
.write("GET http://localhost:9999/ HTTP/1.1\r\nHost: localhost\r\n\r\n"
.getBytes());
os.flush();
try {
if ((got = is.read(buff)) > 0) {
logger.finer(AsciiString.create(buff, 0, got));
fail("Expected the socket to be closed");
} else {
return;
}
} catch (SocketTimeoutException unexpected) {
throw unexpected;
} catch (SocketException expected) {
logger.fine("Got expected socket exception: "
+ expected.getMessage());
return;
}
s.close();
fail("Should not get here if the socket was timed out correctly!");
} catch (IOException ioe) {
ioe.printStackTrace();
} finally {
if (s != null && !s.isClosed())
try {
s.close();
} catch (IOException ignored) {
}
}
} finally {
proxy.stop();
assertTrue("Listener didn't exit", proxy.isStopped());
}
}
}