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.websocketx;
    17
    18  import java.io.UnsupportedEncodingException;
    19
    20  import org.jboss.netty.buffer.ChannelBuffer;
    21  import org.jboss.netty.buffer.ChannelBuffers;
    22  import org.jboss.netty.util.CharsetUtil;
    23
    24  /**
    25   * Web Socket Frame for closing the connection
    26   */
    27  public class CloseWebSocketFrame extends WebSocketFrame {
    28      /**
    29       * Creates a new empty close frame.
    30       */
    31      public CloseWebSocketFrame() {
    32          setBinaryData(ChannelBuffers.EMPTY_BUFFER);
    33      }
    34
    35      /**
    36       * Creates a new empty close frame with closing status code and reason text
    37       *
    38       * @param statusCode
    39       *            Integer status code as per <a href="http://tools.ietf.org/html/rfc6455#section-7.4">RFC 6455</a>. For
    40       *            example, <tt>1000</tt> indicates normal closure.
    41       * @param reasonText
    42       *            Reason text. Set to null if no text.
    43       */
    44      public CloseWebSocketFrame(int statusCode, String reasonText) {
    45          this(true, 0, statusCode, reasonText);
    46      }
    47
    48      /**
    49       * Creates a new close frame with no losing status code and no reason text
    50       *
    51       * @param finalFragment
    52       *            flag indicating if this frame is the final fragment
    53       * @param rsv
    54       *            reserved bits used for protocol extensions
    55       */
    56      public CloseWebSocketFrame(boolean finalFragment, int rsv) {
    57          this(finalFragment, rsv, null);
    58      }
    59
    60      /**
    61       * Creates a new close frame with closing status code and reason text
    62       *
    63       * @param finalFragment
    64       *            flag indicating if this frame is the final fragment
    65       * @param rsv
    66       *            reserved bits used for protocol extensions
    67       * @param statusCode
    68       *            Integer status code as per <a href="http://tools.ietf.org/html/rfc6455#section-7.4">RFC 6455</a>. For
    69       *            example, <tt>1000</tt> indicates normal closure.
    70       * @param reasonText
    71       *            Reason text. Set to null if no text.
    72       */
    73      public CloseWebSocketFrame(boolean finalFragment, int rsv, int statusCode, String reasonText) {
    74          setFinalFragment(finalFragment);
    75          setRsv(rsv);
    76
    77          byte[] reasonBytes = new byte[0];
    78          if (reasonText != null) {
    79              try {
    80                  reasonBytes = reasonText.getBytes("UTF-8");
    81              } catch (UnsupportedEncodingException e) {
    82                  // This should never happen, anyway provide a fallback here
    83                  reasonBytes = reasonText.getBytes();
    84              }
    85          }
    86
    87          ChannelBuffer binaryData = ChannelBuffers.buffer(2 + reasonBytes.length);
    88          binaryData.writeShort(statusCode);
    89          if (reasonBytes.length > 0) {
    90              binaryData.writeBytes(reasonBytes);
    91          }
    92
    93          binaryData.readerIndex(0);
    94          setBinaryData(binaryData);
    95      }
    96
    97      /**
    98       * Creates a new close frame
    99       *
    100      * @param finalFragment
    101      *            flag indicating if this frame is the final fragment
    102      * @param rsv
    103      *            reserved bits used for protocol extensions
    104      * @param binaryData
    105      *            the content of the frame. Must be 2 byte integer followed by optional UTF-8 encoded string.
    106      */
    107     public CloseWebSocketFrame(boolean finalFragment, int rsv, ChannelBuffer binaryData) {
    108         setFinalFragment(finalFragment);
    109         setRsv(rsv);
    110         if (binaryData == null) {
    111             setBinaryData(ChannelBuffers.EMPTY_BUFFER);
    112         } else {
    113             setBinaryData(binaryData);
    114         }
    115     }
    116
    117     /**
    118      * Returns the closing status code as per <a href="http://tools.ietf.org/html/rfc6455#section-7.4">RFC 6455</a>. If
    119      * a status code is set, -1 is returned.
    120      */
    121     public int getStatusCode() {
    122         ChannelBuffer binaryData = getBinaryData();
    123         if (binaryData == null || binaryData.capacity() == 0) {
    124             return -1;
    125         }
    126
    127         binaryData.readerIndex(0);
    128         int statusCode = binaryData.readShort();
    129         binaryData.readerIndex(0);
    130
    131         return statusCode;
    132     }
    133
    134     /**
    135      * Returns the reason text as per <a href="http://tools.ietf.org/html/rfc6455#section-7.4">RFC 6455</a> If a reason
    136      * text is not supplied, an empty string is returned.
    137      */
    138     public String getReasonText() {
    139         ChannelBuffer binaryData = getBinaryData();
    140         if (binaryData == null || binaryData.capacity() <= 2) {
    141             return "";
    142         }
    143
    144         binaryData.readerIndex(2);
    145         String reasonText = binaryData.toString(CharsetUtil.UTF_8);
    146         binaryData.readerIndex(0);
    147
    148         return reasonText;
    149     }
    150
    151     @Override
    152     public String toString() {
    153         return getClass().getSimpleName();
    154     }
    155 }