com.oreilly.servlet.multipart.LimitedServletInputStream Maven / Gradle / Ivy
The newest version!
// Copyright (C) 1999-2001 by Jason Hunter .
// All rights reserved. Use of this class is limited.
// Please see the LICENSE for more information.
package com.oreilly.servlet.multipart;
import java.io.IOException;
import javax.servlet.ReadListener;
import javax.servlet.ServletInputStream;
/**
* A LimitedServletInputStream
wraps another
* ServletInputStream
in order to keep track of how many bytes
* have been read and detect when the Content-Length limit has been reached.
* This is necessary since some servlet containers are slow to notice the end
* of stream and cause the client code to hang if it tries to read past it.
*
* @author Jason Hunter
* @author Geoff Soutter
* @version 1.0, 2000/10/27, initial revision
*/
public class LimitedServletInputStream extends ServletInputStream {
/** input stream we are filtering */
private ServletInputStream in;
/** number of bytes to read before giving up */
private long totalExpected;
/** number of bytes we have currently read */
private long totalRead = 0;
/**
* Creates a LimitedServletInputStream
with the specified
* length limit that wraps the provided ServletInputStream
.
*/
public LimitedServletInputStream(ServletInputStream in, long totalExpected) {
this.in = in;
this.totalExpected = totalExpected;
}
/**
* Implement length limitation on top of the readLine
method of
* the wrapped ServletInputStream
.
*
* @param b an array of bytes into which data is read.
* @param off an integer specifying the character at which
* this method begins reading.
* @param len an integer specifying the maximum number of
* bytes to read.
* @return an integer specifying the actual number of bytes
* read, or -1 if the end of the stream is reached.
* @exception IOException if an I/O error occurs.
*/
public int readLine(byte b[], int off, int len) throws IOException {
int result;
long left = totalExpected - totalRead;
if (left <= 0L) {
return -1;
} else {
result = in.readLine(b, off, (int)Math.min(left,len));
}
if (result > 0) {
totalRead += result;
}
return result;
}
/**
* Implement length limitation on top of the read
method of
* the wrapped ServletInputStream
.
*
* @return the next byte of data, or -1
if the end of the
* stream is reached.
* @exception IOException if an I/O error occurs.
*/
public int read() throws IOException {
if (totalRead >= totalExpected) {
return -1;
}
int result = in.read();
if (result != -1) {
totalRead++;
}
return result;
}
/**
* Implement length limitation on top of the read
method of
* the wrapped ServletInputStream
.
*
* @param b destination buffer.
* @param off offset at which to start storing bytes.
* @param len maximum number of bytes to read.
* @return the number of bytes read, or -1
if the end of
* the stream has been reached.
* @exception IOException if an I/O error occurs.
*/
public int read( byte b[], int off, int len ) throws IOException {
int result;
long left = totalExpected - totalRead;
if (left <= 0) {
return -1;
} else {
result = in.read(b, off, (int)Math.min(left, len));
}
if (result > 0) {
totalRead += result;
}
return result;
}
@Override
public boolean isFinished() {
return in.isFinished();
}
@Override
public boolean isReady() {
return in.isReady();
}
@Override
public void setReadListener(ReadListener readListener) {
in.setReadListener(readListener);
}
}