@@ -1007,6 +1007,9 @@ int WebSocket_putdatas(networkHandles* net, char** buf0, size_t* buf0len, Packet
10071007/**
10081008 * receives incoming socket data and parses websocket frames
10091009 * Copes with socket reads returning partial websocket frames by using the
1010+
1011+ if (in_frames->count == 0)
1012+ ListAppend( in_frames, res, sizeof(struct ws_frame) + res->len);
10101013 * SocketBuffer mechanism.
10111014 *
10121015 * @param[in] net network connection
@@ -1030,24 +1033,65 @@ int WebSocket_receiveFrame(networkHandles *net, size_t *actual_len)
10301033 if ( in_frames -> first )
10311034 res = in_frames -> first -> content ;
10321035
1033- //while( !res )
1034- //{
1035- opcode = WebSocket_OP_BINARY ;
1036- do
1036+ opcode = WebSocket_OP_BINARY ;
1037+ do
1038+ {
1039+ /* obtain all frames in the sequence */
1040+ int is_final = 0 ;
1041+ while ( is_final == 0 )
10371042 {
1038- /* obtain all frames in the sequence */
1039- int is_final = 0 ;
1040- while ( is_final == 0 )
1043+ char * b ;
1044+ size_t len = 0u ;
1045+ int tmp_opcode ;
1046+ int has_mask ;
1047+ size_t cur_len = 0u ;
1048+ uint8_t mask [4 ] = { 0u , 0u , 0u , 0u };
1049+ size_t payload_len ;
1050+ int rcs ; /* socket return code */
1051+
1052+ b = WebSocket_getRawSocketData (net , 2u , & len , & rcs );
1053+ if (rcs == SOCKET_ERROR )
1054+ {
1055+ rc = rcs ;
1056+ goto exit ;
1057+ }
1058+ if ( !b )
1059+ {
1060+ rc = TCPSOCKET_INTERRUPTED ;
1061+ goto exit ;
1062+ }
1063+ else if (len < 2u )
1064+ {
1065+ rc = TCPSOCKET_INTERRUPTED ;
1066+ goto exit ;
1067+ }
1068+
1069+ /* 1st byte */
1070+ is_final = (b [0 ] & 0xFF ) >> 7 ;
1071+ tmp_opcode = (b [0 ] & 0x0F );
1072+
1073+ if ( tmp_opcode ) /* not a continuation frame */
1074+ opcode = tmp_opcode ;
1075+
1076+ /* invalid websocket packet must return error */
1077+ if ( opcode < WebSocket_OP_CONTINUE ||
1078+ opcode > WebSocket_OP_PONG ||
1079+ ( opcode > WebSocket_OP_BINARY &&
1080+ opcode < WebSocket_OP_CLOSE ) )
10411081 {
1042- char * b ;
1043- size_t len = 0u ;
1044- int tmp_opcode ;
1045- int has_mask ;
1046- size_t cur_len = 0u ;
1047- uint8_t mask [4 ] = { 0u , 0u , 0u , 0u };
1048- size_t payload_len ;
1049- int rcs ; /* socket return code */
1082+ rc = SOCKET_ERROR ;
1083+ goto exit ;
1084+ }
1085+
1086+ /* 2nd byte */
1087+ has_mask = (b [1 ] & 0xFF ) >> 7 ;
1088+ payload_len = (b [1 ] & 0x7F );
10501089
1090+ /* determine payload length */
1091+ if ( payload_len == 126 )
1092+ {
1093+ /* If 126, the following 2 bytes interpreted as a
1094+ 16-bit unsigned integer are the payload length. */
10511095 b = WebSocket_getRawSocketData (net , 2u , & len , & rcs );
10521096 if (rcs == SOCKET_ERROR )
10531097 {
@@ -1056,197 +1100,150 @@ int WebSocket_receiveFrame(networkHandles *net, size_t *actual_len)
10561100 }
10571101 if ( !b )
10581102 {
1059- rc = TCPSOCKET_INTERRUPTED ;
1103+ rc = SOCKET_ERROR ;
10601104 goto exit ;
1061- }
1105+ }
10621106 else if (len < 2u )
10631107 {
10641108 rc = TCPSOCKET_INTERRUPTED ;
10651109 goto exit ;
10661110 }
1067-
1068- /* 1st byte */
1069- is_final = (b [0 ] & 0xFF ) >> 7 ;
1070- tmp_opcode = (b [0 ] & 0x0F );
1071-
1072- if ( tmp_opcode ) /* not a continuation frame */
1073- opcode = tmp_opcode ;
1074-
1075- /* invalid websocket packet must return error */
1076- if ( opcode < WebSocket_OP_CONTINUE ||
1077- opcode > WebSocket_OP_PONG ||
1078- ( opcode > WebSocket_OP_BINARY &&
1079- opcode < WebSocket_OP_CLOSE ) )
1111+ /* convert from big endian 16 to host */
1112+ payload_len = be16toh (* (uint16_t * )b );
1113+ }
1114+ else if ( payload_len == 127 )
1115+ {
1116+ /* If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the
1117+ most significant bit MUST be 0) are the payload length */
1118+ b = WebSocket_getRawSocketData (net , 8u , & len , & rcs );
1119+ if (rcs == SOCKET_ERROR )
10801120 {
1081- rc = SOCKET_ERROR ;
1121+ rc = rcs ;
10821122 goto exit ;
10831123 }
1084-
1085- /* 2nd byte */
1086- has_mask = (b [1 ] & 0xFF ) >> 7 ;
1087- payload_len = (b [1 ] & 0x7F );
1088-
1089- /* determine payload length */
1090- if ( payload_len == 126 )
1091- {
1092- /* If 126, the following 2 bytes interpreted as a
1093- 16-bit unsigned integer are the payload length. */
1094- b = WebSocket_getRawSocketData (net , 2u , & len , & rcs );
1095- if (rcs == SOCKET_ERROR )
1096- {
1097- rc = rcs ;
1098- goto exit ;
1099- }
1100- if ( !b )
1101- {
1102- rc = SOCKET_ERROR ;
1103- goto exit ;
1104- }
1105- else if (len < 2u )
1106- {
1107- rc = TCPSOCKET_INTERRUPTED ;
1108- goto exit ;
1109- }
1110- /* convert from big endian 16 to host */
1111- payload_len = be16toh (* (uint16_t * )b );
1112- }
1113- else if ( payload_len == 127 )
1124+ if ( !b )
11141125 {
1115- /* If 127, the following 8 bytes interpreted as a 64-bit unsigned integer (the
1116- most significant bit MUST be 0) are the payload length */
1117- b = WebSocket_getRawSocketData (net , 8u , & len , & rcs );
1118- if (rcs == SOCKET_ERROR )
1119- {
1120- rc = rcs ;
1121- goto exit ;
1122- }
1123- if ( !b )
1124- {
1125- rc = SOCKET_ERROR ;
1126- goto exit ;
1127- }
1128- else if (len < 8u )
1129- {
1130- rc = TCPSOCKET_INTERRUPTED ;
1131- goto exit ;
1132- }
1133- /* convert from big-endian 64 to host */
1134- payload_len = (size_t )be64toh (* (uint64_t * )b );
1126+ rc = SOCKET_ERROR ;
1127+ goto exit ;
11351128 }
1136-
1137- if ( has_mask )
1129+ else if (len < 8u )
11381130 {
1139- uint8_t mask [4 ];
1140- b = WebSocket_getRawSocketData (net , 4u , & len , & rcs );
1141- if (rcs == SOCKET_ERROR )
1142- {
1143- rc = rcs ;
1144- goto exit ;
1145- }
1146- if ( !b )
1147- {
1148- rc = SOCKET_ERROR ;
1149- goto exit ;
1150- }
1151- if (len < 4u )
1152- {
1153- rc = TCPSOCKET_INTERRUPTED ;
1154- goto exit ;
1155- }
1156- memcpy ( & mask [0 ], b , sizeof (uint32_t ));
1131+ rc = TCPSOCKET_INTERRUPTED ;
1132+ goto exit ;
11571133 }
1134+ /* convert from big-endian 64 to host */
1135+ payload_len = (size_t )be64toh (* (uint64_t * )b );
1136+ }
11581137
1159- /* use the socket buffer to read in the whole websocket frame */
1160- b = WebSocket_getRawSocketData (net , payload_len , & len , & rcs );
1138+ if ( has_mask )
1139+ {
1140+ uint8_t mask [4 ];
1141+ b = WebSocket_getRawSocketData (net , 4u , & len , & rcs );
11611142 if (rcs == SOCKET_ERROR )
11621143 {
11631144 rc = rcs ;
11641145 goto exit ;
11651146 }
1166- if (! b )
1147+ if ( ! b )
11671148 {
11681149 rc = SOCKET_ERROR ;
11691150 goto exit ;
1170- }
1171- if (len < payload_len )
1151+ }
1152+ if (len < 4u )
11721153 {
11731154 rc = TCPSOCKET_INTERRUPTED ;
11741155 goto exit ;
11751156 }
1157+ memcpy ( & mask [0 ], b , sizeof (uint32_t ));
1158+ }
11761159
1177- /* unmask data */
1178- if ( has_mask )
1179- {
1180- size_t i ;
1181- for ( i = 0u ; i < payload_len ; ++ i )
1182- b [i ] ^= mask [i % 4 ];
1183- }
1160+ /* use the socket buffer to read in the whole websocket frame */
1161+ b = WebSocket_getRawSocketData (net , payload_len , & len , & rcs );
1162+ if (rcs == SOCKET_ERROR )
1163+ {
1164+ rc = rcs ;
1165+ goto exit ;
1166+ }
1167+ if (!b )
1168+ {
1169+ rc = SOCKET_ERROR ;
1170+ goto exit ;
1171+ }
1172+ if (len < payload_len )
1173+ {
1174+ rc = TCPSOCKET_INTERRUPTED ;
1175+ goto exit ;
1176+ }
1177+
1178+ /* unmask data */
1179+ if ( has_mask )
1180+ {
1181+ size_t i ;
1182+ for ( i = 0u ; i < payload_len ; ++ i )
1183+ b [i ] ^= mask [i % 4 ];
1184+ }
11841185
1185- if ( res )
1186- cur_len = res -> len ;
1186+ if ( res )
1187+ cur_len = res -> len ;
11871188
1188- if (res == NULL )
1189+ if (res == NULL )
1190+ {
1191+ if ((res = malloc ( sizeof (struct ws_frame ) + cur_len + len )) == NULL )
11891192 {
1190- if ((res = malloc ( sizeof (struct ws_frame ) + cur_len + len )) == NULL )
1191- {
1192- rc = PAHO_MEMORY_ERROR ;
1193- goto exit ;
1194- }
1195- res -> pos = 0u ;
1196- } else
1193+ rc = PAHO_MEMORY_ERROR ;
1194+ goto exit ;
1195+ }
1196+ res -> pos = 0u ;
1197+ } else
1198+ {
1199+ void * newPtr = realloc ( res , sizeof (struct ws_frame ) + cur_len + len );
1200+ if (newPtr == NULL )
11971201 {
1198- void * newPtr = realloc ( res , sizeof (struct ws_frame ) + cur_len + len );
1199- if (newPtr == NULL )
1200- {
1201- free (res );
1202- res = NULL ;
1202+ free (res );
1203+ res = NULL ;
12031204
1204- rc = PAHO_MEMORY_ERROR ;
1205- goto exit ;
1206- }
1207- else
1208- {
1209- res = newPtr ;
1210- }
1205+ rc = PAHO_MEMORY_ERROR ;
1206+ goto exit ;
12111207 }
1212- if (in_frames && in_frames -> first )
1213- in_frames -> first -> content = res ; /* realloc moves the data */
1214- memcpy ( (unsigned char * )res + sizeof (struct ws_frame ) + cur_len , b , len );
1215- res -> len = cur_len + len ;
1216-
1217- WebSocket_getRawSocketData (net , 0u , & len , & rcs );
1218- if (rcs == SOCKET_ERROR )
1208+ else
12191209 {
1220- rc = rcs ;
1221- goto exit ;
1210+ res = newPtr ;
12221211 }
12231212 }
1213+ if (in_frames && in_frames -> first )
1214+ in_frames -> first -> content = res ; /* realloc moves the data */
1215+ memcpy ( (unsigned char * )res + sizeof (struct ws_frame ) + cur_len , b , len );
1216+ res -> len = cur_len + len ;
12241217
1225- if ( opcode == WebSocket_OP_PING || opcode == WebSocket_OP_PONG )
1218+ WebSocket_getRawSocketData (net , 0u , & len , & rcs );
1219+ if (rcs == SOCKET_ERROR )
12261220 {
1227- /* respond to a "ping" with a "pong" */
1228- if ( opcode == WebSocket_OP_PING )
1229- WebSocket_pong ( net ,
1230- (char * )res + sizeof (struct ws_frame ),
1231- res -> len );
1232-
1233- /* discard message */
1234- free ( res );
1235- res = NULL ;
1236- }
1237- else if ( opcode == WebSocket_OP_CLOSE )
1238- {
1239- /* server end closed websocket connection */
1240- free ( res );
1241- WebSocket_close ( net , WebSocket_CLOSE_GOING_AWAY , NULL );
1242- rc = SOCKET_ERROR ; /* closes socket */
1221+ rc = rcs ;
12431222 goto exit ;
12441223 }
1245- } while ( opcode == WebSocket_OP_PING || opcode == WebSocket_OP_PONG );
1246- //}
1224+ }
12471225
1248- if (in_frames -> count == 0 )
1249- ListAppend ( in_frames , res , sizeof (struct ws_frame ) + res -> len );
1226+ if ( opcode == WebSocket_OP_PING || opcode == WebSocket_OP_PONG )
1227+ {
1228+ /* respond to a "ping" with a "pong" */
1229+ if ( opcode == WebSocket_OP_PING )
1230+ WebSocket_pong ( net ,
1231+ (char * )res + sizeof (struct ws_frame ),
1232+ res -> len );
1233+
1234+ /* discard message */
1235+ free ( res );
1236+ res = NULL ;
1237+ }
1238+ else if ( opcode == WebSocket_OP_CLOSE )
1239+ {
1240+ /* server end closed websocket connection */
1241+ free ( res );
1242+ WebSocket_close ( net , WebSocket_CLOSE_GOING_AWAY , NULL );
1243+ rc = SOCKET_ERROR ; /* closes socket */
1244+ goto exit ;
1245+ }
1246+ } while ( opcode == WebSocket_OP_PING || opcode == WebSocket_OP_PONG );
12501247 * actual_len = res -> len - res -> pos ;
12511248
12521249exit :
0 commit comments