All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.oreilly.servlet.multipart.LimitedServletInputStream Maven / Gradle / Ivy

There is a newer version: 2024.5.0.0
Show 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.
   * @param in ...
   * @param totalExpected ...
   */
  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);
  }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy