/* * 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.test; import java.io.BufferedReader; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStreamReader; import java.io.OutputStream; import java.net.InetSocketAddress; import java.net.Socket; import java.util.logging.Logger; import org.owasp.proxy.daemon.ConnectionHandler; import org.owasp.proxy.daemon.Server; import org.owasp.proxy.http.MessageFormatException; import org.owasp.proxy.http.MessageUtils; import org.owasp.proxy.http.MutableBufferedRequest; import org.owasp.proxy.http.MutableBufferedResponse; import org.owasp.proxy.io.ChunkedOutputStream; import org.owasp.proxy.io.CopyInputStream; import org.owasp.proxy.util.AsciiString; public class TraceServer { private static Logger logger = Logger .getLogger(TraceServer.class.getName()); private Server server; private boolean chunked = false; private boolean verbose = false; private String version = "HTTP/1.0"; public TraceServer(int port) throws IOException { CH ch = new CH(); server = new Server(new InetSocketAddress("localhost", port), ch); } public void setChunked(boolean chunked) { this.chunked = chunked; } public void setVerbose(boolean verbose) { this.verbose = verbose; } public void setVersion(String version) { this.version = version; } public void start() { server.start(); } public boolean stop() { return server.stop(); } public boolean isStopped() { return server.isStopped(); } private class CH implements ConnectionHandler { public void handleConnection(Socket socket) { try { ByteArrayOutputStream copy = new ByteArrayOutputStream(); CopyInputStream in = new CopyInputStream(socket .getInputStream(), copy); OutputStream out = socket.getOutputStream(); if (verbose) logger.info("Connection: " + socket); boolean close = true; do { copy.reset(); MutableBufferedRequest request = null; // read the whole header. Each line gets written into the // copy defined // above String line; do { line = in.readLine(); } while (line != null && !"".equals(line)); { byte[] headerBytes = copy.toByteArray(); // empty request line, connection closed? if (headerBytes == null || headerBytes.length == 0) return; request = new MutableBufferedRequest.Impl(); request.setHeader(headerBytes); } boolean expectContinue = "100-continue" .equalsIgnoreCase(request.getHeader("Expect")); if (expectContinue) out.write(AsciiString.getBytes(version + " 100 Continue\r\n\r\n")); // Get the request content (if any) from the stream, copy.reset(); if (MessageUtils.expectContent(request) && MessageUtils.flushContent(request, in)) request.setContent(copy.toByteArray()); if (verbose) { logger.info(AsciiString.create(request.getHeader())); if (request.getContent() != null) logger.info(AsciiString .create(request.getContent())); } MutableBufferedResponse response = new MutableBufferedResponse.Impl(); response.setStartLine(version + " 200 Ok"); if (chunked) { response.setHeader("Transfer-Encoding", "chunked"); ByteArrayOutputStream baos = new ByteArrayOutputStream(); ChunkedOutputStream cos = new ChunkedOutputStream(baos, 16); cos.write(request.getHeader()); if (request.getContent() != null) out.write(request.getContent()); cos.close(); response.setContent(baos.toByteArray()); } else { byte[] content = request.getContent() == null ? request .getHeader() : request.getContent(); response.setContent(content); } if (verbose) { logger.info(AsciiString.create(response.getHeader())); if (response.getContent() != null) logger.info(AsciiString.create(response .getContent())); } out.write(response.getHeader()); if (response.getContent() != null) out.write(response.getContent()); out.flush(); String connection = request.getHeader("Connection"); if ("Keep-Alive".equalsIgnoreCase(connection)) { close = false; } else { close = true; } } while (!close); } catch (IOException e) { e.printStackTrace(); } catch (MessageFormatException e) { e.printStackTrace(); } finally { try { if (!socket.isClosed()) socket.close(); } catch (IOException ioe2) { } } } } public static void main(String[] args) throws Exception { TraceServer ts = new TraceServer(9999); ts.setChunked(true); ts.setVerbose(true); ts.start(); System.out.println("Started"); new BufferedReader(new InputStreamReader(System.in)).readLine(); ts.stop(); System.out.println("stopped"); } }