@@ -1300,10 +1300,10 @@ ssize_t WebSocket::send_frame(const swoole::WebSocketSettings &settings,
13001300 * return_value is false means socket.read() method returning -1.
13011301 * return_value is null means other error.
13021302 * return_value is empry string means socket is closed.
1303- * the opcode is returned so the caller can decide when to release the frame_buffer .
1303+ * the opcode is returned so the caller can decide when to release the continue_frame_buffer .
13041304 */
13051305void WebSocket::recv_frame (const WebSocketSettings &settings,
1306- std::shared_ptr<String> &frame_buffer ,
1306+ std::shared_ptr<String> &continue_frame_buffer ,
13071307 SocketImpl *sock,
13081308 zval *return_value,
13091309 double timeout) {
@@ -1364,39 +1364,47 @@ void WebSocket::recv_frame(const WebSocketSettings &settings,
13641364 }
13651365
13661366 if (opcode == WebSocket::OPCODE_CONTINUATION ) {
1367- if (sw_unlikely (!frame_buffer )) {
1367+ if (sw_unlikely (!continue_frame_buffer )) {
13681368 swoole_warning (" A continuation frame cannot stand alone and MUST be preceded by an initial frame whose "
13691369 " opcode indicates either text or binary data." );
13701370 RETURN_NULL ();
13711371 }
13721372
13731373 if (sw_likely (frame.payload )) {
1374- frame_buffer ->append (frame.payload , frame.payload_length );
1374+ continue_frame_buffer ->append (frame.payload , frame.payload_length );
13751375 }
13761376
13771377 if (frame.header .FIN ) {
13781378 uchar complete_opcode = 0 ;
13791379 uchar complete_flags = 0 ;
1380- WebSocket::parse_ext_flags (frame_buffer ->offset , &complete_opcode, &complete_flags);
1380+ WebSocket::parse_ext_flags (continue_frame_buffer ->offset , &complete_opcode, &complete_flags);
13811381
13821382 if (complete_flags & WebSocket::FLAG_RSV1 ) {
1383- if (sw_unlikely (!FrameObject::uncompress (&zpayload, frame_buffer->str , frame_buffer->length ))) {
1383+ if (sw_unlikely (!FrameObject::uncompress (
1384+ &zpayload, continue_frame_buffer->str , continue_frame_buffer->length ))) {
1385+ continue_frame_buffer.reset ();
13841386 swoole_set_last_error (SW_ERROR_PROTOCOL_ERROR );
13851387 RETURN_NULL ();
13861388 }
13871389 } else {
1388- zend::assign_zend_string_by_val (&zpayload, frame_buffer->str , frame_buffer->length );
1390+ zend::assign_zend_string_by_val (
1391+ &zpayload, continue_frame_buffer->str , continue_frame_buffer->length );
13891392 Z_TRY_ADDREF (zpayload);
1390- frame_buffer.reset ();
13911393 }
13921394
1395+ sw_set_bit (complete_flags, WebSocket::FLAG_FIN );
13931396 WebSocket::construct_frame (return_value, complete_opcode, &zpayload, complete_flags);
13941397 zend::object_set (return_value, ZEND_STRL (" fd" ), sock->get_fd ());
13951398 zval_ptr_dtor (&zpayload);
1399+ /* *
1400+ * The final frame of the continuous frame sequence has been received,
1401+ * and the complete message has been assembled. Memory can be released immediately.
1402+ */
1403+ continue_frame_buffer.reset ();
13961404 return ;
13971405 }
13981406 } else {
1399- if (sw_unlikely (frame_buffer )) {
1407+ if (sw_unlikely (continue_frame_buffer )) {
14001408 swoole_warning (" All fragments of a message, except for the initial frame, must use the continuation "
14011409 " frame opcode(0)." );
14021410 RETURN_NULL ();
@@ -1415,12 +1423,12 @@ void WebSocket::recv_frame(const WebSocketSettings &settings,
14151423 zval_ptr_dtor (&zpayload);
14161424 return ;
14171425 } else {
1418- frame_buffer = std::make_shared<String>(
1426+ continue_frame_buffer = std::make_shared<String>(
14191427 (frame.payload_length > 0 ? frame.payload_length : SW_WEBSOCKET_DEFAULT_BUFFER ),
14201428 sw_zend_string_allocator ());
1421- frame_buffer ->offset = WebSocket::get_ext_flags (frame.header .OPCODE , frame.get_flags ());
1429+ continue_frame_buffer ->offset = WebSocket::get_ext_flags (frame.header .OPCODE , frame.get_flags ());
14221430 if (sw_likely (frame.payload )) {
1423- frame_buffer ->append (frame.payload , frame.payload_length );
1431+ continue_frame_buffer ->append (frame.payload , frame.payload_length );
14241432 }
14251433 }
14261434 }
@@ -1445,7 +1453,8 @@ static PHP_METHOD(swoole_http_response, recv) {
14451453 Z_PARAM_DOUBLE (timeout)
14461454 ZEND_PARSE_PARAMETERS_END_EX (RETURN_FALSE );
14471455
1448- WebSocket::recv_frame (ctx->websocket_settings , ctx->frame_buffer , ctx->get_co_socket (), return_value, timeout);
1456+ WebSocket::recv_frame (
1457+ ctx->websocket_settings , ctx->continue_frame_buffer , ctx->get_co_socket (), return_value, timeout);
14491458 if (ZVAL_IS_EMPTY_STRING (return_value)) {
14501459 ctx->close (ctx);
14511460 return ;
0 commit comments