1 /***************************************************************** 2 * Licensed to the Apache Software Foundation (ASF) under one * 3 * or more contributor license agreements. See the NOTICE file * 4 * distributed with this work for additional information * 5 * regarding copyright ownership. The ASF licenses this file * 6 * to you under the Apache License, Version 2.0 (the * 7 * "License"); you may not use this file except in compliance * 8 * with the License. You may obtain a copy of the License at * 9 * * 10 * http://www.apache.org/licenses/LICENSE-2.0 * 11 * * 12 * Unless required by applicable law or agreed to in writing, * 13 * software distributed under the License is distributed on an * 14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY * 15 * KIND, either express or implied. See the License for the * 16 * specific language governing permissions and limitations * 17 * under the License. * 18 ****************************************************************/ 19 20 package org.apache.james.smtpserver; 21 22 import java.io.IOException; 23 import java.io.InputStream; 24 25 /*** 26 * Wraps an underlying input stream, limiting the allowable size 27 * of incoming data. The size limit is configured in the conf file, 28 * and when the limit is reached, a MessageSizeException is thrown. 29 */ 30 public class SizeLimitedInputStream extends InputStream { 31 /*** 32 * Maximum number of bytes to read. 33 */ 34 private long maxmessagesize = 0; 35 /*** 36 * Running total of bytes read from wrapped stream. 37 */ 38 private long bytesread = 0; 39 40 /*** 41 * InputStream that will be wrapped. 42 */ 43 private InputStream in = null; 44 45 /*** 46 * Constructor for the stream. Wraps an underlying stream. 47 * @param in InputStream to use as basis for new Stream. 48 * @param maxmessagesize Message size limit, in Kilobytes 49 */ 50 public SizeLimitedInputStream(InputStream in, long maxmessagesize) { 51 this.in = in; 52 this.maxmessagesize = maxmessagesize; 53 } 54 55 /*** 56 * Overrides the read method of InputStream to call the read() method of the 57 * wrapped input stream. 58 * @throws IOException Throws a MessageSizeException, which is a sub-type of IOException 59 * @return Returns the number of bytes read. 60 */ 61 public int read(byte[] b, int off, int len) throws IOException { 62 int l = in.read(b, off, len); 63 64 bytesread += l; 65 66 if (maxmessagesize > 0 && bytesread > maxmessagesize) { 67 throw new MessageSizeException(); 68 } 69 70 return l; 71 } 72 73 /*** 74 * Overrides the read method of InputStream to call the read() method of the 75 * wrapped input stream. 76 * @throws IOException Throws a MessageSizeException, which is a sub-type of IOException. 77 * @return Returns the int character value of the byte read. 78 */ 79 public int read() throws IOException { 80 if (maxmessagesize > 0 && bytesread <= maxmessagesize) { 81 bytesread++; 82 return in.read(); 83 } else { 84 throw new MessageSizeException(); 85 } 86 } 87 }