View Javadoc
1   /*
2    * Copyright 2012 The Netty Project
3    *
4    * The Netty Project licenses this file to you under the Apache License,
5    * version 2.0 (the "License"); you may not use this file except in compliance
6    * with the License. You may obtain a copy of the License at:
7    *
8    *   http://www.apache.org/licenses/LICENSE-2.0
9    *
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
12   * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
13   * License for the specific language governing permissions and limitations
14   * under the License.
15   */
16  package io.netty.handler.codec.http.multipart;
17  
18  import io.netty.buffer.ByteBuf;
19  import io.netty.handler.codec.http.HttpHeaderValues;
20  
21  /**
22   * Shared Static object between HttpMessageDecoder, HttpPostRequestDecoder and HttpPostRequestEncoder
23   */
24  final class HttpPostBodyUtil {
25  
26      public static final int chunkSize = 8096;
27  
28      /**
29       * Default Content-Type in binary form
30       */
31      public static final String DEFAULT_BINARY_CONTENT_TYPE = HttpHeaderValues.APPLICATION_OCTET_STREAM.toString();
32  
33      /**
34       * Default Content-Type in Text form
35       */
36      public static final String DEFAULT_TEXT_CONTENT_TYPE = HttpHeaderValues.TEXT_PLAIN.toString();
37  
38      /**
39       * Allowed mechanism for multipart
40       * mechanism := "7bit"
41                    / "8bit"
42                    / "binary"
43         Not allowed: "quoted-printable"
44                    / "base64"
45       */
46      public enum TransferEncodingMechanism {
47          /**
48           * Default encoding
49           */
50          BIT7("7bit"),
51          /**
52           * Short lines but not in ASCII - no encoding
53           */
54          BIT8("8bit"),
55          /**
56           * Could be long text not in ASCII - no encoding
57           */
58          BINARY("binary");
59  
60          private final String value;
61  
62          TransferEncodingMechanism(String value) {
63              this.value = value;
64          }
65  
66          TransferEncodingMechanism() {
67              value = name();
68          }
69  
70          public String value() {
71              return value;
72          }
73  
74          @Override
75          public String toString() {
76              return value;
77          }
78      }
79  
80      private HttpPostBodyUtil() {
81      }
82  
83      /**
84      * Exception when NO Backend Array is found
85      */
86      static class SeekAheadNoBackArrayException extends Exception {
87          private static final long serialVersionUID = -630418804938699495L;
88      }
89  
90      /**
91      * This class intends to decrease the CPU in seeking ahead some bytes in
92      * HttpPostRequestDecoder
93      */
94      static class SeekAheadOptimize {
95          byte[] bytes;
96          int readerIndex;
97          int pos;
98          int origPos;
99          int limit;
100         ByteBuf buffer;
101 
102         SeekAheadOptimize(ByteBuf buffer) throws SeekAheadNoBackArrayException {
103             if (!buffer.hasArray()) {
104                 throw new SeekAheadNoBackArrayException();
105             }
106             this.buffer = buffer;
107             bytes = buffer.array();
108             readerIndex = buffer.readerIndex();
109             origPos = pos = buffer.arrayOffset() + readerIndex;
110             limit = buffer.arrayOffset() + buffer.writerIndex();
111         }
112 
113         /**
114         *
115         * @param minus this value will be used as (currentPos - minus) to set
116         * the current readerIndex in the buffer.
117         */
118         void setReadPosition(int minus) {
119             pos -= minus;
120             readerIndex = getReadPosition(pos);
121             buffer.readerIndex(readerIndex);
122         }
123 
124         /**
125         *
126         * @param index raw index of the array (pos in general)
127         * @return the value equivalent of raw index to be used in readerIndex(value)
128         */
129         int getReadPosition(int index) {
130             return index - origPos + readerIndex;
131         }
132 
133         void clear() {
134             buffer = null;
135             bytes = null;
136             limit = 0;
137             pos = 0;
138             readerIndex = 0;
139         }
140     }
141 
142     /**
143      * Find the first non whitespace
144      * @return the rank of the first non whitespace
145      */
146     static int findNonWhitespace(String sb, int offset) {
147         int result;
148         for (result = offset; result < sb.length(); result ++) {
149             if (!Character.isWhitespace(sb.charAt(result))) {
150                 break;
151             }
152         }
153         return result;
154     }
155 
156     /**
157      * Find the first whitespace
158      * @return the rank of the first whitespace
159      */
160     static int findWhitespace(String sb, int offset) {
161         int result;
162         for (result = offset; result < sb.length(); result ++) {
163             if (Character.isWhitespace(sb.charAt(result))) {
164                 break;
165             }
166         }
167         return result;
168     }
169 
170     /**
171      * Find the end of String
172      * @return the rank of the end of string
173      */
174     static int findEndOfString(String sb) {
175         int result;
176         for (result = sb.length(); result > 0; result --) {
177             if (!Character.isWhitespace(sb.charAt(result - 1))) {
178                 break;
179             }
180         }
181         return result;
182     }
183 
184 }