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 21 22 package org.apache.james.smtpserver; 23 24 import java.io.IOException; 25 import java.io.InputStream; 26 27 /** 28 * Wraps an underlying input stream, limiting the allowable size 29 * of incoming data. The size limit is configured in the conf file, 30 * and when the limit is reached, a MessageSizeException is thrown. 31 */ 32 public class SizeLimitedInputStream extends InputStream { 33 /** 34 * Maximum number of bytes to read. 35 */ 36 private long maxmessagesize = 0; 37 /** 38 * Running total of bytes read from wrapped stream. 39 */ 40 private long bytesread = 0; 41 42 /** 43 * InputStream that will be wrapped. 44 */ 45 private InputStream in = null; 46 47 /** 48 * Constructor for the stream. Wraps an underlying stream. 49 * @param in InputStream to use as basis for new Stream. 50 * @param maxmessagesize Message size limit, in Kilobytes 51 */ 52 public SizeLimitedInputStream(InputStream in, long maxmessagesize) { 53 this.in = in; 54 this.maxmessagesize = maxmessagesize; 55 } 56 57 /** 58 * Overrides the read method of InputStream to call the read() method of the 59 * wrapped input stream. 60 * @throws IOException Throws a MessageSizeException, which is a sub-type of IOException 61 * @return Returns the number of bytes read. 62 */ 63 public int read(byte[] b, int off, int len) throws IOException { 64 int l = in.read(b, off, len); 65 66 bytesread += l; 67 68 if (maxmessagesize > 0 && bytesread > maxmessagesize) { 69 throw new MessageSizeException(); 70 } 71 72 return l; 73 } 74 75 /** 76 * Overrides the read method of InputStream to call the read() method of the 77 * wrapped input stream. 78 * @throws IOException Throws a MessageSizeException, which is a sub-type of IOException. 79 * @return Returns the int character value of the byte read. 80 */ 81 public int read() throws IOException { 82 if (maxmessagesize > 0 && bytesread <= maxmessagesize) { 83 bytesread++; 84 return in.read(); 85 } else { 86 throw new MessageSizeException(); 87 } 88 } 89 }