@@ -24,6 +24,7 @@ static const char *TAG = "transport_ws";
2424
2525#define WS_BUFFER_SIZE CONFIG_WS_BUFFER_SIZE
2626#define WS_FIN 0x80
27+ #define WS_COMPRESSED 0x40
2728#define WS_OPCODE_CONT 0x00
2829#define WS_OPCODE_TEXT 0x01
2930#define WS_OPCODE_BINARY 0x02
@@ -56,6 +57,7 @@ typedef struct {
5657 int payload_len ; /*!< Total length of the payload */
5758 int bytes_remaining ; /*!< Bytes left to read of the payload */
5859 bool header_received ; /*!< Flag to indicate that a new message header was received */
60+ bool compressed ; /*!< Per-message deflate compress flag (RSV1) */
5961} ws_transport_frame_state_t ;
6062
6163typedef struct {
@@ -75,6 +77,11 @@ typedef struct {
7577 char * redir_host ;
7678 char * response_header ;
7779 size_t response_header_len ;
80+ bool per_msg_compress ;
81+ int per_msg_client_deflate_window_bit ;
82+ int per_msg_server_deflate_window_bit ;
83+ bool per_msg_server_no_ctx_takeover ;
84+ bool per_msg_client_no_ctx_takeover ;
7885} transport_ws_t ;
7986
8087/**
@@ -201,6 +208,20 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int
201208#endif
202209
203210 size_t outlen = 0 ;
211+ char extension_header [160 ] = { 0 };
212+ if (ws -> per_msg_compress ) {
213+ if (ws -> per_msg_client_deflate_window_bit != 0 ) {
214+
215+ }
216+
217+ int ext_len = snprintf (extension_header ,
218+ sizeof (extension_header ),
219+ "Sec-WebSocket-Extensions: permessage-deflate;%s%s%s%s" ,
220+ ws -> per_msg_client_no_ctx_takeover ? " client_no_context_takeover; " : "" ,
221+ ws -> per_msg_server_no_ctx_takeover ? " server_no_context_takeover; " : "" ,
222+ );
223+ }
224+
204225 esp_crypto_base64_encode (client_key , sizeof (client_key ), & outlen , random_key , sizeof (random_key ));
205226 int len = snprintf (ws -> buffer , WS_BUFFER_SIZE ,
206227 "GET %s HTTP/1.1\r\n"
@@ -209,7 +230,8 @@ static int ws_connect(esp_transport_handle_t t, const char *host, int port, int
209230 "User-Agent: %s\r\n"
210231 "Upgrade: websocket\r\n"
211232 "Sec-WebSocket-Version: 13\r\n"
212- "Sec-WebSocket-Key: %s\r\n" ,
233+ "Sec-WebSocket-Key: %s\r\n"
234+ "%s" , // For "Sec-WebSocket-Extensions"
213235 ws -> path ,
214236 host , port , user_agent_ptr ,
215237 client_key );
@@ -575,6 +597,7 @@ static int ws_read_header(esp_transport_handle_t t, char *buffer, int len, int t
575597 ws -> frame_state .header_received = true;
576598 ws -> frame_state .fin = (* data_ptr & 0x80 ) != 0 ;
577599 ws -> frame_state .opcode = (* data_ptr & 0x0F );
600+ ws -> frame_state .compressed = (* data_ptr & 0x40 ) != 0 ; // RSV1 bit in the header
578601 data_ptr ++ ;
579602 mask = ((* data_ptr >> 7 ) & 0x01 );
580603 payload_len = (* data_ptr & 0x7F );
@@ -979,6 +1002,21 @@ esp_err_t esp_transport_ws_set_config(esp_transport_handle_t t, const esp_transp
9791002 }
9801003
9811004 ws -> propagate_control_frames = config -> propagate_control_frames ;
1005+ ws -> per_msg_compress = config -> per_msg_compress ;
1006+ ws -> per_msg_client_no_ctx_takeover = config -> per_msg_client_no_ctx_takeover ;
1007+ ws -> per_msg_server_no_ctx_takeover = config -> per_msg_server_no_ctx_takeover ;
1008+
1009+ if (config -> per_msg_client_deflate_window_bit < 8 || config -> per_msg_client_deflate_window_bit > 15 ) {
1010+ ws -> per_msg_client_deflate_window_bit = 0 ;
1011+ } else {
1012+ ws -> per_msg_client_deflate_window_bit = config -> per_msg_client_deflate_window_bit ;
1013+ }
1014+
1015+ if (config -> per_msg_server_deflate_window_bit < 8 || config -> per_msg_server_deflate_window_bit > 15 ) {
1016+ ws -> per_msg_server_deflate_window_bit = 0 ;
1017+ } else {
1018+ ws -> per_msg_server_deflate_window_bit = config -> per_msg_server_deflate_window_bit ;
1019+ }
9821020
9831021 return err ;
9841022}
0 commit comments