001    /****************************************************************
002     * Licensed to the Apache Software Foundation (ASF) under one   *
003     * or more contributor license agreements.  See the NOTICE file *
004     * distributed with this work for additional information        *
005     * regarding copyright ownership.  The ASF licenses this file   *
006     * to you under the Apache License, Version 2.0 (the            *
007     * "License"); you may not use this file except in compliance   *
008     * with the License.  You may obtain a copy of the License at   *
009     *                                                              *
010     *   http://www.apache.org/licenses/LICENSE-2.0                 *
011     *                                                              *
012     * Unless required by applicable law or agreed to in writing,   *
013     * software distributed under the License is distributed on an  *
014     * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY       *
015     * KIND, either express or implied.  See the License for the    *
016     * specific language governing permissions and limitations      *
017     * under the License.                                           *
018     ****************************************************************/
019    
020    package org.apache.james.mime4j.stream;
021    
022    import org.apache.james.mime4j.MimeException;
023    
024    /**
025     * Properties used to configure the behavior of MIME stream parsers.
026     */
027    public final class MimeConfig implements Cloneable {
028    
029        private boolean strictParsing;
030        private int maxLineLen;
031        private int maxHeaderCount;
032        private int maxHeaderLen;
033        private long maxContentLen;
034        private boolean countLineNumbers;
035        private String headlessParsing;
036        private boolean malformedHeaderStartsBody;
037    
038        public MimeConfig() {
039            this.strictParsing = false;
040            this.countLineNumbers = false;
041            this.malformedHeaderStartsBody = false;
042            this.maxLineLen = 1000;
043            this.maxHeaderCount = 1000;
044            this.maxHeaderLen = 10000;
045            this.maxContentLen = -1;
046            this.headlessParsing = null;
047        }
048    
049        /**
050         * @see #setMalformedHeaderStartsBody(boolean)
051         *
052         * @return true if malformed header should "end" the headers and be part of
053         *         the body
054         */
055        public boolean isMalformedHeaderStartsBody() {
056            return malformedHeaderStartsBody;
057        }
058    
059        /**
060         * Define the behaviour for dealing with malformed headers while in lenient
061         * mode
062         *
063         * @param malformedHeaderStartsBody
064         *            <code>true</code> to make the parser interpret a malformed
065         *            header as end of the headers and as part of the body (as if
066         *            the CRLF separator was missing). <code>false</code> to simply
067         *            ignore malformed headers and continue parsing headers from the
068         *            following line.
069         */
070        public void setMalformedHeaderStartsBody(boolean malformedHeaderStartsBody) {
071            this.malformedHeaderStartsBody = malformedHeaderStartsBody;
072        }
073    
074        /**
075         * Returns the value of the strict parsing mode
076         *
077         * @see #setStrictParsing(boolean)
078         *
079         * @return value of the strict parsing mode
080         */
081        public boolean isStrictParsing() {
082            return this.strictParsing;
083        }
084    
085        /**
086         * Defines whether minor violations of the MIME specification should be
087         * tolerated or should result in a {@link MimeException}. If this parameter
088         * is set to <code>true</code>, a strict interpretation of the MIME
089         * specification will be enforced, If this parameter is set to
090         * <code>false</code> minor violations will result in a warning in the log.
091         * <p>
092         * Default value: <code>false</code>
093         *
094         * @param strictParsing
095         *            value of the strict parsing mode
096         */
097        public void setStrictParsing(boolean strictParsing) {
098            this.strictParsing = strictParsing;
099        }
100    
101        /**
102         * Returns the maximum line length limit
103         *
104         * @see #setMaxLineLen(int)
105         *
106         * @return value of the the maximum line length limit
107         */
108        public int getMaxLineLen() {
109            return this.maxLineLen;
110        }
111    
112        /**
113         * Sets the maximum line length limit. Parsing of a MIME entity will be
114         * terminated with a {@link MimeException} if a line is encountered that
115         * exceeds the maximum length limit. If this parameter is set to a non
116         * positive value the line length check will be disabled.
117         * <p>
118         * Default value: <code>1000</code>
119         *
120         * @param maxLineLen
121         *            maximum line length limit
122         */
123        public void setMaxLineLen(int maxLineLen) {
124            this.maxLineLen = maxLineLen;
125        }
126    
127        /**
128         * Returns the maximum header limit
129         *
130         * @see #setMaxHeaderCount(int)
131         *
132         * @return value of the the maximum header limit
133         */
134        public int getMaxHeaderCount() {
135            return this.maxHeaderCount;
136        }
137    
138        /**
139         * Sets the maximum header limit. Parsing of a MIME entity will be
140         * terminated with a {@link MimeException} if the number of headers exceeds
141         * the maximum limit. If this parameter is set to a non positive value the
142         * header limit check will be disabled.
143         * <p>
144         * Default value: <code>1000</code>
145         *
146         * @param maxHeaderCount
147         *            maximum header limit
148         */
149        public void setMaxHeaderCount(int maxHeaderCount) {
150            this.maxHeaderCount = maxHeaderCount;
151        }
152    
153        /**
154         * Returns the maximum header length limit
155         *
156         * @see #setMaxHeaderLen(int)
157         *
158         * @return value of the maximum header length limit
159         */
160        public int getMaxHeaderLen() {
161            return maxHeaderLen;
162        }
163    
164        /**
165         * Sets the maximum header length limit. Parsing of a MIME entity will be
166         * terminated with a {@link MimeException} if the total length of a header
167         * exceeds this limit. If this parameter is set to a non positive value the
168         * header length check will be disabled.
169         * <p>
170         * A message header may be folded across multiple lines. This configuration
171         * parameter is used to limit the total length of a header, i.e. the sum of
172         * the length of all lines the header spans across (including line
173         * terminators).
174         * <p>
175         * Default value: <code>10000</code>
176         *
177         * @param maxHeaderLen
178         *            maximum header length limit
179         */
180        public void setMaxHeaderLen(int maxHeaderLen) {
181            this.maxHeaderLen = maxHeaderLen;
182        }
183    
184        /**
185         * Returns the maximum content length limit
186         *
187         * @see #setMaxContentLen(long)
188         *
189         * @return value of the the maximum content length limit
190         */
191        public long getMaxContentLen() {
192            return maxContentLen;
193        }
194    
195        /**
196         * Sets the maximum content length limit. Parsing of a MIME entity will be
197         * terminated with a {@link MimeException} if a content body exceeds the
198         * maximum length limit. If this parameter is set to a non positive value
199         * the content length check will be disabled.
200         * <p>
201         * Default value: <code>-1</code>
202         *
203         * @param maxContentLen
204         *            maximum content length limit
205         */
206        public void setMaxContentLen(long maxContentLen) {
207            this.maxContentLen = maxContentLen;
208        }
209    
210        /**
211         * Returns the value of the line number counting mode.
212         *
213         * @return value of the line number counting mode.
214         */
215        public boolean isCountLineNumbers() {
216            return countLineNumbers;
217        }
218    
219        /**
220         * Defines whether the parser should count line numbers. If enabled line
221         * numbers are included in the debug output.
222         * <p>
223         * Default value: <code>false</code>
224         *
225         * @param countLineNumbers
226         *            value of the line number counting mode.
227         */
228        public void setCountLineNumbers(boolean countLineNumbers) {
229            this.countLineNumbers = countLineNumbers;
230        }
231    
232        /**
233         * Returns the value of the default content type. When not null, indicates
234         * that the parsing should be headless.
235         *
236         * @return default content type when parsing headless, null otherwise
237         * @see org.apache.james.mime4j.parser.MimeStreamParser#parse(java.io.InputStream)
238         */
239        public String getHeadlessParsing() {
240            return headlessParsing;
241        }
242    
243        /**
244         * Defines a default content type. When not null, indicates that the parsing
245         * should be headless.
246         * <p>
247         * Default value: <code>null</code>
248         *
249         * @param contentType
250         *            value of the default content type when parsing headless, null
251         *            otherwise
252         * @see org.apache.james.mime4j.parser.MimeStreamParser#parse(java.io.InputStream)
253         */
254        public void setHeadlessParsing(String contentType) {
255            this.headlessParsing = contentType;
256        }
257    
258        @Override
259        public MimeConfig clone() {
260            try {
261                return (MimeConfig) super.clone();
262            } catch (CloneNotSupportedException e) {
263                // this shouldn't happen, since we are Cloneable
264                throw new InternalError();
265            }
266        }
267    
268        @Override
269        public String toString() {
270            return "[strict parsing: " + strictParsing + ", max line length: " + maxLineLen + ", max header count: " + maxHeaderCount + ", max content length: " + maxContentLen + ", count line numbers: " + countLineNumbers + "]";
271        }
272    
273    }