mirror of
https://github.com/curl/curl.git
synced 2026-07-31 20:28:04 +03:00
ws: make pong sending lazy
Do not send PONG frames unless there is sufficient space left in the websocket send buffer. A server might be lazy in reading our data and intermediary PONG frames can be skipped by a client (RFC 6455, ch. 5.5.3). Add test case measuring no real RSS increase on a server blasting with PING frames. Closes #21911
This commit is contained in:
parent
fb9a520873
commit
849317ff5c
2 changed files with 99 additions and 12 deletions
33
lib/ws.c
33
lib/ws.c
|
|
@ -632,6 +632,7 @@ static CURLcode ws_enc_add_cntrl(struct Curl_easy *data,
|
|||
size_t plen,
|
||||
unsigned int frame_type)
|
||||
{
|
||||
(void)data;
|
||||
DEBUGASSERT(plen <= WS_MAX_CNTRL_LEN);
|
||||
if(plen > WS_MAX_CNTRL_LEN)
|
||||
return CURLE_BAD_FUNCTION_ARGUMENT;
|
||||
|
|
@ -641,13 +642,6 @@ static CURLcode ws_enc_add_cntrl(struct Curl_easy *data,
|
|||
ws->pending.type = frame_type;
|
||||
ws->pending.payload_len = plen;
|
||||
memcpy(ws->pending.payload, payload, plen);
|
||||
|
||||
if(!ws->enc.payload_remain) { /* not in the middle of another frame */
|
||||
CURLcode result = ws_enc_add_pending(data, ws);
|
||||
if(!result)
|
||||
(void)ws_flush(data, ws, Curl_is_in_callback(data));
|
||||
return result;
|
||||
}
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
|
|
@ -716,7 +710,7 @@ static CURLcode ws_cw_write(struct Curl_easy *data,
|
|||
{
|
||||
struct ws_cw_ctx *ctx = writer->ctx;
|
||||
struct websocket *ws;
|
||||
CURLcode result;
|
||||
CURLcode result = CURLE_OK;
|
||||
|
||||
CURL_TRC_WRITE(data, "ws_cw_write(len=%zu, type=%d)", nbytes, type);
|
||||
if(!(type & CLIENTWRITE_BODY) || data->set.ws_raw_mode)
|
||||
|
|
@ -749,7 +743,8 @@ static CURLcode ws_cw_write(struct Curl_easy *data,
|
|||
if(result == CURLE_AGAIN) {
|
||||
/* insufficient amount of data, keep it for later.
|
||||
* we pretend to have written all since we have a copy */
|
||||
return CURLE_OK;
|
||||
result = CURLE_OK;
|
||||
goto out;
|
||||
}
|
||||
else if(result) {
|
||||
failf(data, "[WS] decode payload error %d", (int)result);
|
||||
|
|
@ -760,10 +755,16 @@ static CURLcode ws_cw_write(struct Curl_easy *data,
|
|||
if((type & CLIENTWRITE_EOS) && !Curl_bufq_is_empty(&ctx->buf)) {
|
||||
failf(data, "[WS] decode ending with %zu frame bytes remaining",
|
||||
Curl_bufq_len(&ctx->buf));
|
||||
return CURLE_RECV_ERROR;
|
||||
result = CURLE_RECV_ERROR;
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
out:
|
||||
if(!result) {
|
||||
result = ws_flush(data, ws, Curl_is_in_callback(data));
|
||||
if(result == CURLE_AGAIN)
|
||||
result = CURLE_OK;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
/* WebSocket payload decoding client writer. */
|
||||
|
|
@ -1627,8 +1628,16 @@ CURLcode curl_ws_recv(CURL *curl, void *buffer,
|
|||
static CURLcode ws_flush(struct Curl_easy *data, struct websocket *ws,
|
||||
bool blocking)
|
||||
{
|
||||
CURLcode result;
|
||||
|
||||
/* If there is space, add any pending control frame */
|
||||
if(Curl_bufq_len(&ws->sendbuf) < ws->sendbuf.chunk_size) {
|
||||
result = ws_enc_add_pending(data, ws);
|
||||
if(result && (result != CURLE_AGAIN))
|
||||
return result;
|
||||
}
|
||||
|
||||
if(!Curl_bufq_is_empty(&ws->sendbuf)) {
|
||||
CURLcode result;
|
||||
const uint8_t *out;
|
||||
size_t outlen, n;
|
||||
#ifdef DEBUGBUILD
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue