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