15
15
16
16
#include <aws/http/private/websocket_decoder.h>
17
17
18
- /* If 7bit payload length has these values, then the next few bytes contain the real payload length */
19
- #define VALUE_FOR_2BYTE_EXTENDED_LENGTH 126
20
- #define VALUE_FOR_8BYTE_EXTENDED_LENGTH 127
18
+ /* TODO: decoder logging */
21
19
22
20
typedef int (state_fn )(struct aws_websocket_decoder * decoder , struct aws_byte_cursor * data );
23
21
@@ -47,6 +45,20 @@ static int s_state_opcode_byte(struct aws_websocket_decoder *decoder, struct aws
47
45
/* next 4 bits are opcode */
48
46
decoder -> current_frame .opcode = byte & 0x0F ;
49
47
48
+ /* RFC-6455 Section 5.2 - Opcode
49
+ * If an unknown opcode is received, the receiving endpoint MUST _Fail the WebSocket Connection_. */
50
+ switch (decoder -> current_frame .opcode ) {
51
+ case AWS_WEBSOCKET_OPCODE_CONTINUATION :
52
+ case AWS_WEBSOCKET_OPCODE_TEXT :
53
+ case AWS_WEBSOCKET_OPCODE_BINARY :
54
+ case AWS_WEBSOCKET_OPCODE_CLOSE :
55
+ case AWS_WEBSOCKET_OPCODE_PING :
56
+ case AWS_WEBSOCKET_OPCODE_PONG :
57
+ break ;
58
+ default :
59
+ return aws_raise_error (AWS_ERROR_HTTP_PARSE );
60
+ }
61
+
50
62
/* RFC-6455 Section 5.2 Fragmentation
51
63
*
52
64
* Data frames with the FIN bit clear are considered fragmented and must be followed by
@@ -58,11 +70,11 @@ static int s_state_opcode_byte(struct aws_websocket_decoder *decoder, struct aws
58
70
if (aws_websocket_is_data_frame (decoder -> current_frame .opcode )) {
59
71
bool is_continuation_frame = AWS_WEBSOCKET_OPCODE_CONTINUATION == decoder -> current_frame .opcode ;
60
72
61
- if (decoder -> expecting_continuation_data_frames != is_continuation_frame ) {
73
+ if (decoder -> expecting_continuation_data_frame != is_continuation_frame ) {
62
74
return aws_raise_error (AWS_ERROR_HTTP_PARSE );
63
75
}
64
76
65
- decoder -> expecting_continuation_data_frames = !decoder -> current_frame .fin ;
77
+ decoder -> expecting_continuation_data_frame = !decoder -> current_frame .fin ;
66
78
67
79
} else {
68
80
/* Control frames themselves MUST NOT be fragmented. */
@@ -90,7 +102,7 @@ static int s_state_length_byte(struct aws_websocket_decoder *decoder, struct aws
90
102
/* remaining 7 bits are payload length */
91
103
decoder -> current_frame .payload_length = byte & 0x7F ;
92
104
93
- if (decoder -> current_frame .payload_length >= VALUE_FOR_2BYTE_EXTENDED_LENGTH ) {
105
+ if (decoder -> current_frame .payload_length >= AWS_WEBSOCKET_7BIT_VALUE_FOR_2BYTE_EXTENDED_LENGTH ) {
94
106
/* If 7bit payload length has a high value, then the next few bytes contain the real payload length */
95
107
decoder -> state_bytes_processed = 0 ;
96
108
decoder -> state = AWS_WEBSOCKET_DECODER_STATE_EXTENDED_LENGTH ;
@@ -108,27 +120,21 @@ static int s_state_extended_length(struct aws_websocket_decoder *decoder, struct
108
120
return AWS_OP_SUCCESS ;
109
121
}
110
122
111
- /* RFC-6455 Section 5.2 Base Framing Protocol - Payload length
112
- * 1) It is a crime to use more bytes than necessary to encode length.
113
- * > in all cases, the minimal number of bytes MUST be used to encode
114
- * > the length, for example, the length of a 124-byte-long string
115
- * > can't be encoded as the sequence 126, 0, 124
116
- * 2) It is a crime to use most-significant bit on 8 byte payloads.
117
- * > If 127, the following 8 bytes interpreted as a 64-bit unsigned integer
118
- * > (the most significant bit MUST be 0) are the payload length */
123
+ /* The 7bit payload value loaded during the previous state indicated that
124
+ * actual payload length is encoded across the next 2 or 8 bytes. */
119
125
uint8_t total_bytes_extended_length ;
120
126
uint64_t min_acceptable_value ;
121
127
uint64_t max_acceptable_value ;
122
- if (decoder -> current_frame .payload_length == VALUE_FOR_2BYTE_EXTENDED_LENGTH ) {
128
+ if (decoder -> current_frame .payload_length == AWS_WEBSOCKET_7BIT_VALUE_FOR_2BYTE_EXTENDED_LENGTH ) {
123
129
total_bytes_extended_length = 2 ;
124
- min_acceptable_value = VALUE_FOR_2BYTE_EXTENDED_LENGTH ;
125
- max_acceptable_value = UINT16_MAX ;
130
+ min_acceptable_value = AWS_WEBSOCKET_2BYTE_EXTENDED_LENGTH_MIN_VALUE ;
131
+ max_acceptable_value = AWS_WEBSOCKET_2BYTE_EXTENDED_LENGTH_MAX_VALUE ;
126
132
} else {
127
- assert (decoder -> current_frame .payload_length == VALUE_FOR_8BYTE_EXTENDED_LENGTH );
133
+ assert (decoder -> current_frame .payload_length == AWS_WEBSOCKET_7BIT_VALUE_FOR_8BYTE_EXTENDED_LENGTH );
128
134
129
135
total_bytes_extended_length = 8 ;
130
- min_acceptable_value = UINT16_MAX + 1 ;
131
- max_acceptable_value = 0x7FFFFFFFFFFFFFFFULL ;
136
+ min_acceptable_value = AWS_WEBSOCKET_8BYTE_EXTENDED_LENGTH_MIN_VALUE ;
137
+ max_acceptable_value = AWS_WEBSOCKET_8BYTE_EXTENDED_LENGTH_MAX_VALUE ;
132
138
}
133
139
134
140
/* Copy bytes of extended-length to state_cache, we'll process them later.*/
0 commit comments