View Javadoc

1   //
2   //  ========================================================================
3   //  Copyright (c) 1995-2016 Mort Bay Consulting Pty. Ltd.
4   //  ------------------------------------------------------------------------
5   //  All rights reserved. This program and the accompanying materials
6   //  are made available under the terms of the Eclipse Public License v1.0
7   //  and Apache License v2.0 which accompanies this distribution.
8   //
9   //      The Eclipse Public License is available at
10  //      http://www.eclipse.org/legal/epl-v10.html
11  //
12  //      The Apache License v2.0 is available at
13  //      http://www.opensource.org/licenses/apache2.0.php
14  //
15  //  You may elect to redistribute this code under either of these licenses.
16  //  ========================================================================
17  //
18  
19  package org.eclipse.jetty.websocket.common.frames;
20  
21  import java.nio.ByteBuffer;
22  import java.util.Arrays;
23  
24  import org.eclipse.jetty.websocket.api.ProtocolException;
25  import org.eclipse.jetty.websocket.common.WebSocketFrame;
26  
27  public abstract class ControlFrame extends WebSocketFrame
28  {
29      /** Maximum size of Control frame, per RFC 6455 */
30      public static final int MAX_CONTROL_PAYLOAD = 125;
31  
32      public ControlFrame(byte opcode)
33      {
34          super(opcode);
35      }
36  
37      public void assertValid()
38      {
39          if (isControlFrame())
40          {
41              if (getPayloadLength() > ControlFrame.MAX_CONTROL_PAYLOAD)
42              {
43                  throw new ProtocolException("Desired payload length [" + getPayloadLength() + "] exceeds maximum control payload length ["
44                          + MAX_CONTROL_PAYLOAD + "]");
45              }
46  
47              if ((finRsvOp & 0x80) == 0)
48              {
49                  throw new ProtocolException("Cannot have FIN==false on Control frames");
50              }
51  
52              if ((finRsvOp & 0x40) != 0)
53              {
54                  throw new ProtocolException("Cannot have RSV1==true on Control frames");
55              }
56  
57              if ((finRsvOp & 0x20) != 0)
58              {
59                  throw new ProtocolException("Cannot have RSV2==true on Control frames");
60              }
61  
62              if ((finRsvOp & 0x10) != 0)
63              {
64                  throw new ProtocolException("Cannot have RSV3==true on Control frames");
65              }
66          }
67      }
68  
69      @Override
70      public boolean equals(Object obj)
71      {
72          if (this == obj)
73          {
74              return true;
75          }
76          if (obj == null)
77          {
78              return false;
79          }
80          if (getClass() != obj.getClass())
81          {
82              return false;
83          }
84          ControlFrame other = (ControlFrame)obj;
85          if (data == null)
86          {
87              if (other.data != null)
88              {
89                  return false;
90              }
91          }
92          else if (!data.equals(other.data))
93          {
94              return false;
95          }
96          if (finRsvOp != other.finRsvOp)
97          {
98              return false;
99          }
100         if (!Arrays.equals(mask,other.mask))
101         {
102             return false;
103         }
104         if (masked != other.masked)
105         {
106             return false;
107         }
108         return true;
109     }
110 
111     public boolean isControlFrame()
112     {
113         return true;
114     }
115 
116     @Override
117     public boolean isDataFrame()
118     {
119         return false;
120     }
121 
122     @Override
123     public WebSocketFrame setPayload(ByteBuffer buf)
124     {
125         if (buf != null && buf.remaining() > MAX_CONTROL_PAYLOAD)
126         {
127             throw new ProtocolException("Control Payloads can not exceed " + MAX_CONTROL_PAYLOAD + " bytes in length.");
128         }
129         return super.setPayload(buf);
130     }
131 }