View Javadoc
1   /*
2    * Copyright 2014 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.websocketx.extensions.compression;
17  
18  import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionData;
19  import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionDecoder;
20  import io.netty.handler.codec.http.websocketx.extensions.WebSocketExtensionEncoder;
21  import io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtension;
22  import io.netty.handler.codec.http.websocketx.extensions.WebSocketServerExtensionHandshaker;
23  
24  import java.util.Collections;
25  
26  /**
27   * <a href="https://tools.ietf.org/id/draft-tyoshino-hybi-websocket-perframe-deflate-06.txt">perframe-deflate</a>
28   * handshake implementation.
29   */
30  public final class DeflateFrameServerExtensionHandshaker implements WebSocketServerExtensionHandshaker {
31  
32      static final String X_WEBKIT_DEFLATE_FRAME_EXTENSION = "x-webkit-deflate-frame";
33      static final String DEFLATE_FRAME_EXTENSION = "deflate-frame";
34  
35      private final int compressionLevel;
36  
37      /**
38       * Constructor with default configuration.
39       */
40      public DeflateFrameServerExtensionHandshaker() {
41          this(6);
42      }
43  
44      /**
45       * Constructor with custom configuration.
46       *
47       * @param compressionLevel
48       *            Compression level between 0 and 9 (default is 6).
49       */
50      public DeflateFrameServerExtensionHandshaker(int compressionLevel) {
51          if (compressionLevel < 0 || compressionLevel > 9) {
52              throw new IllegalArgumentException(
53                      "compressionLevel: " + compressionLevel + " (expected: 0-9)");
54          }
55          this.compressionLevel = compressionLevel;
56      }
57  
58      @Override
59      public WebSocketServerExtension handshakeExtension(WebSocketExtensionData extensionData) {
60          if (!X_WEBKIT_DEFLATE_FRAME_EXTENSION.equals(extensionData.name()) &&
61              !DEFLATE_FRAME_EXTENSION.equals(extensionData.name())) {
62              return null;
63          }
64  
65          if (extensionData.parameters().isEmpty()) {
66              return new DeflateFrameServerExtension(compressionLevel, extensionData.name());
67          } else {
68              return null;
69          }
70      }
71  
72      private static class DeflateFrameServerExtension implements WebSocketServerExtension {
73  
74          private final String extensionName;
75          private final int compressionLevel;
76  
77          public DeflateFrameServerExtension(int compressionLevel, String extensionName) {
78              this.extensionName = extensionName;
79              this.compressionLevel = compressionLevel;
80          }
81  
82          @Override
83          public int rsv() {
84              return RSV1;
85          }
86  
87          @Override
88          public WebSocketExtensionEncoder newExtensionEncoder() {
89              return new PerFrameDeflateEncoder(compressionLevel, 15, false);
90          }
91  
92          @Override
93          public WebSocketExtensionDecoder newExtensionDecoder() {
94              return new PerFrameDeflateDecoder(false);
95          }
96  
97          @Override
98          public WebSocketExtensionData newReponseData() {
99              return new WebSocketExtensionData(extensionName, Collections.<String, String>emptyMap());
100         }
101     }
102 
103 }