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 }