Skip to content

When Mojo WebSocket enables permessage-deflate, it causes abnormal data transmission. #2235

Open
@hbasrc

Description

@hbasrc

This issue occurs only with certain WebSocket server communications. When permessage-deflate is enabled, the first time the payload is sent, it works normally. However, when sending again the second time, it is found that the compressed payload generated by build_message is already corrupted, resulting in a 1006 disconnection. My solution is:

In Mojo::Transaction::WebSocket:

sub build_message {
  my ($self, $frame) = @_;
  ...
  $deflate->flush($out, Z_SYNC_FLUSH);
  $deflate->deflateReset();
}

But I believe this is not the final or best fix.

Here is the debug info after enabling permessage-deflate:

-- Parsing frame (1, 0, 0, 0, 9)
-- Small payload (4)
"ping"
-- Building frame (1, 0, 0, 0, 10)
-- Small payload (4)
"ping"
send heartbeat.
-- Building frame (1, 1, 0, 0, 1)
-- Small payload (52)
"\252VJL.\311\314\317S\262R\312HM,*IJM,Q\322QJ\316\311L\315+\211/)V\2622471\2604\260436300\3203\250\5\0"  <---- Payload is correct at this time
-- Parsing frame (1, 1, 0, 0, 1)
-- Small payload (66)
"\0<\0\303\377{\"channel\":\"heartbeat\",\"data\":[{\"server_ts\":1740909635305}]}\0"
\ {
    channel   "heartbeat",
    data      [
        [0] {
            server_ts   1740909635305
        }
    ]
}
-- Parsing frame (1, 0, 0, 0, 9)
-- Small payload (4)
"ping"
-- Building frame (1, 0, 0, 0, 10)
-- Small payload (4)
"ping"
send heartbeat.
-- Building frame (1, 1, 0, 0, 1)
-- Small payload (8)
"\252&Z\207)T\a\0"                   <--------- payload was wrong the second time
-- Parsing frame (1, 0, 0, 0, 9)
-- Small payload (4)
"ping"
-- Building frame (1, 0, 0, 0, 10)
-- Small payload (4)
"ping"
WebSocket closed with status 1006:
Attempting to websocket reconnect in 5 seconds...
Terminating on signal SIGINT(2)

Here is without permessage-deflate, it works fine:

-- Parsing frame (1, 0, 0, 0, 9)
-- Small payload (4)
"ping"
-- Building frame (1, 0, 0, 0, 10)
-- Small payload (4)
"ping"
send heartbeat.
-- Building frame (1, 0, 0, 0, 1)
-- Small payload (50)
"{\"action\":\"heartbeat\",\"client_ts\":1740909589000.0}"
-- Parsing frame (1, 0, 0, 0, 1)
-- Small payload (60)
"{\"channel\":\"heartbeat\",\"data\":[{\"server_ts\":1740909588668}]}"
\ {
    channel   "heartbeat",
    data      [
        [0] {
            server_ts   1740909588668
        }
    ]
}
-- Parsing frame (1, 0, 0, 0, 9)
-- Small payload (4)
"ping"
-- Building frame (1, 0, 0, 0, 10)
-- Small payload (4)
"ping"
-- Parsing frame (1, 0, 0, 0, 9)
-- Small payload (4)
"ping"
-- Building frame (1, 0, 0, 0, 10)
-- Small payload (4)
"ping"
send heartbeat.
-- Building frame (1, 0, 0, 0, 1)
-- Small payload (50)
"{\"action\":\"heartbeat\",\"client_ts\":1740909609000.0}"
-- Parsing frame (1, 0, 0, 0, 1)
-- Small payload (60)
"{\"channel\":\"heartbeat\",\"data\":[{\"server_ts\":1740909608669}]}"
\ {
    channel   "heartbeat",
    data      [
        [0] {
            server_ts   1740909608669
        }
    ]
}
Terminating on signal SIGINT(2)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions