net.lightbody.bmp.proxy.jetty.http.ChunkingInputStream Maven / Gradle / Ivy
// ========================================================================
// $Id: ChunkingInputStream.java,v 1.7 2005/08/13 00:01:24 gregwilkins Exp $
// Copyright 1996-2004 Mort Bay Consulting Pty. Ltd.
// ------------------------------------------------------------------------
// 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 net.lightbody.bmp.proxy.jetty.http;
import net.lightbody.bmp.proxy.jetty.log.LogFactory;
import net.lightbody.bmp.proxy.jetty.util.LineInput;
import net.lightbody.bmp.proxy.jetty.util.LogSupport;
import org.apache.commons.logging.Log;
import java.io.IOException;
import java.io.InputStream;
/* ------------------------------------------------------------ */
/** Dechunk input.
* Or limit content length.
*/
public class ChunkingInputStream extends InputStream
{
private static Log log = LogFactory.getLog(ChunkingInputStream.class);
private static final String __UNEXPECTED_EOF="Unexpected EOF while chunking";
/* ------------------------------------------------------------ */
int _chunkSize=0;
HttpFields _trailer=null;
LineInput _in;
/* ------------------------------------------------------------ */
/** Constructor.
*/
public ChunkingInputStream(LineInput in)
{
_in=in;
}
/* ------------------------------------------------------------ */
public void resetStream()
{
_chunkSize=0;
_trailer=null;
}
/* ------------------------------------------------------------ */
public int read()
throws IOException
{
int b=-1;
if (_chunkSize<=0 && getChunkSize()<=0)
return -1;
b=_in.read();
if (b<0)
{
_chunkSize=-1;
throw new IOException(__UNEXPECTED_EOF);
}
_chunkSize--;
return b;
}
/* ------------------------------------------------------------ */
public int read(byte b[]) throws IOException
{
int len = b.length;
if (_chunkSize<=0 && getChunkSize()<=0)
return -1;
if (len > _chunkSize)
len=_chunkSize;
len=_in.read(b,0,len);
if (len<0)
{
_chunkSize=-1;
throw new IOException(__UNEXPECTED_EOF);
}
_chunkSize=_chunkSize-len;
return len;
}
/* ------------------------------------------------------------ */
public int read(byte b[], int off, int len) throws IOException
{
if (_chunkSize<=0 && getChunkSize()<=0)
return -1;
if (len > _chunkSize)
len=_chunkSize;
len=_in.read(b,off,len);
if (len<0)
{
_chunkSize=-1;
throw new IOException(__UNEXPECTED_EOF);
}
_chunkSize=_chunkSize-len;
return len;
}
/* ------------------------------------------------------------ */
public long skip(long len) throws IOException
{
if (_chunkSize<=0 && getChunkSize()<=0)
return -1;
if (len > _chunkSize)
len=_chunkSize;
len=_in.skip(len);
if (len<0)
{
_chunkSize=-1;
throw new IOException(__UNEXPECTED_EOF);
}
_chunkSize=_chunkSize-(int)len;
return len;
}
/* ------------------------------------------------------------ */
public int available()
throws IOException
{
int len = _in.available();
if (len<=_chunkSize || _chunkSize==0)
return len;
return _chunkSize;
}
/* ------------------------------------------------------------ */
public void close()
throws IOException
{
_chunkSize=-1;
}
/* ------------------------------------------------------------ */
/** Mark is not supported.
* @return false
*/
public boolean markSupported()
{
return false;
}
/* ------------------------------------------------------------ */
/** Not Implemented.
*/
public void reset()
{
log.warn(LogSupport.NOT_IMPLEMENTED);
}
/* ------------------------------------------------------------ */
/** Not Implemented.
* @param readlimit
*/
public void mark(int readlimit)
{
log.warn(LogSupport.NOT_IMPLEMENTED);
}
/* ------------------------------------------------------------ */
/* Get the size of the next chunk.
* @return size of the next chunk or -1 for EOF.
* @exception IOException
*/
private int getChunkSize()
throws IOException
{
if (_chunkSize<0)
return -1;
_trailer=null;
_chunkSize=-1;
// Get next non blank line
net.lightbody.bmp.proxy.jetty.util.LineInput.LineBuffer line_buffer
=_in.readLineBuffer();
while(line_buffer!=null && line_buffer.size==0)
line_buffer=_in.readLineBuffer();
// Handle early EOF or error in format
if (line_buffer==null)
throw new IOException("Unexpected EOF");
String line= new String(line_buffer.buffer,0,line_buffer.size);
// Get chunksize
int i=line.indexOf(';');
if (i>0)
line=line.substring(0,i).trim();
try
{
_chunkSize = Integer.parseInt(line,16);
}
catch (NumberFormatException e)
{
_chunkSize=-1;
log.warn("Bad Chunk:"+line);
log.debug(LogSupport.EXCEPTION,e);
throw new IOException("Bad chunk size");
}
// check for EOF
if (_chunkSize==0)
{
_chunkSize=-1;
// Look for trailers
_trailer = new HttpFields();
_trailer.read(_in);
}
return _chunkSize;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy