/* * 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.io; import java.io.FilterInputStream; import java.io.IOException; import java.io.InputStream; import org.owasp.proxy.util.AsciiString; import org.owasp.proxy.util.CircularByteBuffer; public class ChunkingInputStream extends FilterInputStream { private static byte[] CRLF = { '\r', '\n' }; private CircularByteBuffer buff; private byte[] b; private boolean eof = false; public ChunkingInputStream(InputStream in) { this(in, 1024); } public ChunkingInputStream(InputStream in, int size) { super(in); buff = new CircularByteBuffer(size + 8); // 4 digits + CRLF + chunk + // CRLF b = new byte[size]; } private void fill() throws IOException { if (buff.length() > 0 || eof) return; int got = super.read(b, 0, b.length); if (got == -1) { buff.add(AsciiString.getBytes("0\r\n\r\n")); eof = true; } else { buff.add(AsciiString.getBytes(Integer.toHexString(got) + "\r\n")); buff.add(b, 0, got); buff.add(CRLF); } } /* * (non-Javadoc) * * @see java.io.FilterInputStream#read() */ @Override public int read() throws IOException { fill(); if (buff.length() > 0) return buff.remove(); return -1; } /* * (non-Javadoc) * * @see java.io.FilterInputStream#read(byte[], int, int) */ @Override public int read(byte[] b, int off, int len) throws IOException { int read = 0, got; fill(); while (read < len && (got = buff.remove(b, off + read, len - read)) > -1) { fill(); read += got; } if (len > 0 && read == 0) return -1; return read; } }