View Javadoc

1   package org.apache.mina.filter.codec.prefixedstring;
2   
3   import org.apache.mina.common.IoBuffer;
4   import org.apache.mina.common.IoSession;
5   import org.apache.mina.common.BufferDataException;
6   import org.apache.mina.filter.codec.CumulativeProtocolDecoder;
7   import org.apache.mina.filter.codec.ProtocolDecoder;
8   import org.apache.mina.filter.codec.ProtocolDecoderOutput;
9   
10  import java.nio.charset.Charset;
11  
12  /**
13   * A {@link ProtocolDecoder} which decodes a String using a fixed-length length prefix.
14   *
15   * @author The Apache MINA Project (dev@mina.apache.org)
16   * @version $Rev: 591182 $, $Date: 2007-11-02 01:59:27 +0100 (vr, 02 nov 2007) $,
17   */
18  public class PrefixedStringDecoder extends CumulativeProtocolDecoder {
19  
20      public final static int DEFAULT_PREFIX_LENGTH = 4;
21  
22      public final static int DEFAULT_MAX_DATA_LENGTH = 2048;
23  
24      private final Charset charset;
25  
26      private int prefixLength = DEFAULT_PREFIX_LENGTH;
27  
28      private int maxDataLength = DEFAULT_MAX_DATA_LENGTH;
29  
30      /**
31       * @param charset       the charset to use for encoding
32       * @param prefixLength  the length of the prefix
33       * @param maxDataLength maximum number of bytes allowed for a single String
34       */
35      public PrefixedStringDecoder(Charset charset, int prefixLength, int maxDataLength) {
36          this.charset = charset;
37          this.prefixLength = prefixLength;
38          this.maxDataLength = maxDataLength;
39      }
40  
41      public PrefixedStringDecoder(Charset charset, int prefixLength) {
42          this(charset, prefixLength, DEFAULT_MAX_DATA_LENGTH);
43      }
44  
45      public PrefixedStringDecoder(Charset charset) {
46          this(charset, DEFAULT_PREFIX_LENGTH);
47      }
48  
49      /**
50       * Sets the number of bytes used by the length prefix
51       *
52       * @param prefixLength the length of the length prefix (1, 2, or 4)
53       */
54      public void setPrefixLength(int prefixLength) {
55          this.prefixLength = prefixLength;
56      }
57  
58      /**
59       * Gets the length of the length prefix (1, 2, or 4)
60       *
61       * @return length of the length prefix
62       */
63      public int getPrefixLength() {
64          return prefixLength;
65      }
66  
67      /**
68       * Sets the maximum allowed value specified as data length in the incoming data
69       * <p>
70       * Useful for preventing an OutOfMemory attack by the peer.
71       * The decoder will throw a {@link BufferDataException} when data length
72       * specified in the incoming data is greater than maxDataLength
73       * The default value is {@link PrefixedStringDecoder#DEFAULT_MAX_DATA_LENGTH}.
74       * </p>
75       *
76       * @param maxDataLength maximum allowed value specified as data length in the incoming data
77       */
78      public void setMaxDataLength(int maxDataLength) {
79          this.maxDataLength = maxDataLength;
80      }
81  
82      /**
83       * Gets the maximum number of bytes allowed for a single String
84       *
85       * @return maximum number of bytes allowed for a single String
86       */
87      public int getMaxDataLength() {
88          return maxDataLength;
89      }
90  
91      protected boolean doDecode(IoSession session, IoBuffer in, ProtocolDecoderOutput out) throws Exception {
92          if (in.prefixedDataAvailable(prefixLength, maxDataLength)) {
93              String msg = in.getPrefixedString(prefixLength, charset.newDecoder());
94              out.write(msg);
95              return true;
96          } else {
97              return false;
98          }
99      }
100 }