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 }