1 module hunt.http.WebSocketFrame;
2 
3 import hunt.io.ByteBuffer;
4 import hunt.Exceptions;
5 import hunt.util.Common;
6 
7 import std.conv;
8 import std.traits;
9 
10 
11 alias OutgoingFramesHandler = void delegate(WebSocketFrame frame, Callback callback);
12 
13 
14 /**
15  * 
16  */
17 enum WebSocketFrameType : byte {
18     CONTINUATION = 0x00,
19     TEXT = 0x01,
20     BINARY = 0x02,
21     CLOSE = 0x08,
22     PING = 0x09,
23     PONG = 0x0A
24 }
25 
26 
27 deprecated("Using WebSocketFrameType instead.")
28 alias FrameType = WebSocketFrameType;
29 
30 deprecated("Using WebSocketFrame instead.")
31 alias Frame = WebSocketFrame;
32 
33 
34 /**
35  * An immutable websocket frame.
36  */
37 interface WebSocketFrame {
38     deprecated("Using WebSocketFrameType instead.")
39     alias Type = WebSocketFrameType;
40     // enum Type : byte {
41     //     CONTINUATION = 0x00,
42     //     TEXT = 0x01,
43     //     BINARY = 0x02,
44     //     CLOSE = 0x08,
45     //     PING = 0x09,
46     //     PONG = 0x0A
47     // }
48 
49     byte[] getMask();
50 
51     byte getOpCode();
52 
53     ByteBuffer getPayload();
54 
55     /**
56      * The original payload length ({@link ByteBuffer#remaining()})
57      *
58      * @return the original payload length ({@link ByteBuffer#remaining()})
59      */
60     int getPayloadLength();
61 
62     WebSocketFrameType getType();
63 
64     bool hasPayload();
65 
66     bool isFin();
67 
68     bool isMasked();
69 
70     bool isRsv1();
71 
72     bool isRsv2();
73 
74     bool isRsv3();
75 }
76 
77 
78 /**
79  * 
80  */
81 struct OpCode {
82     /**
83      * OpCode for a Continuation Frame
84      *
85      * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
86      */
87     enum byte CONTINUATION = cast(byte) 0x00;
88 
89     /**
90      * OpCode for a Text Frame
91      *
92      * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
93      */
94     enum byte TEXT = cast(byte) 0x01;
95 
96     /**
97      * OpCode for a Binary Frame
98      *
99      * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
100      */
101     enum byte BINARY = cast(byte) 0x02;
102 
103     /**
104      * OpCode for a Close Frame
105      *
106      * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
107      */
108     enum byte CLOSE = cast(byte) 0x08;
109 
110     /**
111      * OpCode for a Ping Frame
112      *
113      * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
114      */
115     enum byte PING = cast(byte) 0x09;
116 
117     /**
118      * OpCode for a Pong Frame
119      *
120      * @see <a href="https://tools.ietf.org/html/rfc6455#section-11.8">RFC 6455, Section 11.8 (WebSocket Opcode Registry</a>
121      */
122     enum byte PONG = cast(byte) 0x0A;
123 
124     /**
125      * An undefined OpCode
126      */
127     enum byte UNDEFINED = cast(byte) -1;
128 
129     static bool isControlFrame(byte opcode) {
130         return (opcode >= CLOSE);
131     }
132 
133     static bool isDataFrame(byte opcode) {
134         return (opcode == TEXT) || (opcode == BINARY);
135     }
136 
137     /**
138      * Test for known opcodes (per the RFC spec)
139      *
140      * @param opcode the opcode to test
141      * @return true if known. false if unknown, undefined, or reserved
142      */
143     static bool isKnown(byte opcode) {
144         return (opcode == CONTINUATION) || (opcode == TEXT) || (opcode == BINARY) || 
145             (opcode == CLOSE) || (opcode == PING) || (opcode == PONG);
146     }
147 
148     static string name(byte opcode) {
149         switch (opcode) {
150             case -1:
151                 return "NO-OP";
152             case CONTINUATION:
153                 return "CONTINUATION";
154             case TEXT:
155                 return "TEXT";
156             case BINARY:
157                 return "BINARY";
158             case CLOSE:
159                 return "CLOSE";
160             case PING:
161                 return "PING";
162             case PONG:
163                 return "PONG";
164             default:
165                 return "NON-SPEC[" ~ opcode ~ "]";
166         }
167     }
168 }
169