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 org.jboss.netty.handler.codec.http.multipart;
17  
18  import java.nio.charset.Charset;
19  
20  import org.jboss.netty.buffer.ChannelBuffer;
21  import org.jboss.netty.util.CharsetUtil;
22  
23  /**
24   * Shared Static object between HttpMessageDecoder, HttpPostRequestDecoder and HttpPostRequestEncoder
25   */
26  final class HttpPostBodyUtil {
27  
28      public static int chunkSize = 8096;
29      /**
30       * HTTP content disposition header name.
31       */
32      public static final String CONTENT_DISPOSITION = "Content-Disposition";
33  
34      public static final String NAME = "name";
35  
36      public static final String FILENAME = "filename";
37  
38      /**
39       * Content-disposition value for form data.
40       */
41      public static final String FORM_DATA = "form-data";
42  
43      /**
44       * Content-disposition value for file attachment.
45       */
46      public static final String ATTACHMENT = "attachment";
47  
48      /**
49       * Content-disposition value for file attachment.
50       */
51      public static final String FILE = "file";
52  
53      /**
54       * HTTP content type body attribute for multiple uploads.
55       */
56      public static final String MULTIPART_MIXED = "multipart/mixed";
57  
58      /**
59       * Charset for 8BIT
60       */
61      public static final Charset ISO_8859_1 = CharsetUtil.ISO_8859_1;
62  
63      /**
64       * Charset for 7BIT
65       */
66      public static final Charset US_ASCII = CharsetUtil.US_ASCII;
67  
68      /**
69       * Default Content-Type in binary form
70       */
71      public static final String DEFAULT_BINARY_CONTENT_TYPE = "application/octet-stream";
72  
73      /**
74       * Default Content-Type in Text form
75       */
76      public static final String DEFAULT_TEXT_CONTENT_TYPE = "text/plain";
77  
78      /**
79       * Allowed mechanism for multipart
80       * mechanism := "7bit"
81                    / "8bit"
82                    / "binary"
83         Not allowed: "quoted-printable"
84                    / "base64"
85       */
86      public enum TransferEncodingMechanism {
87          /**
88           * Default encoding
89           */
90          BIT7("7bit"),
91          /**
92           * Short lines but not in ASCII - no encoding
93           */
94          BIT8("8bit"),
95          /**
96           * Could be long text not in ASCII - no encoding
97           */
98          BINARY("binary");
99  
100         public String value;
101 
102         TransferEncodingMechanism(String value) {
103             this.value = value;
104         }
105 
106         TransferEncodingMechanism() {
107             value = name();
108         }
109 
110         @Override
111         public String toString() {
112             return value;
113         }
114     }
115 
116     private HttpPostBodyUtil() {
117     }
118 
119 
120     /**
121     * Exception when NO Backend Array is found
122     */
123     static class SeekAheadNoBackArrayException extends Exception {
124         private static final long serialVersionUID = -630418804938699495L;
125     }
126 
127     /**
128     * This class intends to decrease the CPU in seeking ahead some bytes in
129     * HttpPostRequestDecoder
130     */
131     static class SeekAheadOptimize {
132         byte[] bytes;
133 
134         int readerIndex;
135 
136         int pos;
137 
138         int limit;
139 
140         ChannelBuffer buffer;
141 
142         /**
143         * @param buffer
144         */
145         SeekAheadOptimize(ChannelBuffer buffer) throws SeekAheadNoBackArrayException {
146             if (!buffer.hasArray()) {
147                 throw new SeekAheadNoBackArrayException();
148             }
149             this.buffer = buffer;
150             bytes = buffer.array();
151             pos = readerIndex = buffer.arrayOffset() + buffer.readerIndex();
152             limit = buffer.arrayOffset() + buffer.writerIndex();
153         }
154 
155         /**
156         *
157         * @param minus this value will be used as (currentPos - minus) to set
158         * the current readerIndex in the buffer.
159         */
160         void setReadPosition(int minus) {
161             pos -= minus;
162             readerIndex = pos;
163             buffer.readerIndex(readerIndex);
164         }
165 
166         void clear() {
167             buffer = null;
168             bytes = null;
169             limit = 0;
170             pos = 0;
171             readerIndex = 0;
172         }
173     }
174 
175     /**
176      * Find the first non whitespace
177      * @param sb
178      * @param offset
179      * @return the rank of the first non whitespace
180      */
181     static int findNonWhitespace(String sb, int offset) {
182         int result;
183         for (result = offset; result < sb.length(); result ++) {
184             if (!Character.isWhitespace(sb.charAt(result))) {
185                 break;
186             }
187         }
188         return result;
189     }
190 
191     /**
192      * Find the first whitespace
193      * @param sb
194      * @param offset
195      * @return the rank of the first whitespace
196      */
197     static int findWhitespace(String sb, int offset) {
198         int result;
199         for (result = offset; result < sb.length(); result ++) {
200             if (Character.isWhitespace(sb.charAt(result))) {
201                 break;
202             }
203         }
204         return result;
205     }
206 
207     /**
208      * Find the end of String
209      * @param sb
210      * @return the rank of the end of string
211      */
212     static int findEndOfString(String sb) {
213         int result;
214         for (result = sb.length(); result > 0; result --) {
215             if (!Character.isWhitespace(sb.charAt(result - 1))) {
216                 break;
217             }
218         }
219         return result;
220     }
221 
222 }