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