websocket: fix curl_ws_recv()

- when data arrived in several chunks, the collection into
  the passed buffer always started at offset 0, overwriting
  the data already there.

adding test_20_07 to verify fix

- debug environment var CURL_WS_CHUNK_SIZE can be used to
  influence the buffer chunk size used for en-/decoding.

Closes #12945
This commit is contained in:
Stefan Eissing 2024-02-15 16:39:40 +01:00 committed by Daniel Stenberg
parent e3461bbd05
commit f0c446ab57
No known key found for this signature in database
GPG key ID: 5CC908FDB71E12C2
4 changed files with 37 additions and 6 deletions

View file

@ -754,13 +754,26 @@ CURLcode Curl_ws_accept(struct Curl_easy *data,
DEBUGASSERT(data->conn);
ws = data->conn->proto.ws;
if(!ws) {
size_t chunk_size = WS_CHUNK_SIZE;
ws = calloc(1, sizeof(*ws));
if(!ws)
return CURLE_OUT_OF_MEMORY;
data->conn->proto.ws = ws;
Curl_bufq_init2(&ws->recvbuf, WS_CHUNK_SIZE, WS_CHUNK_COUNT,
#ifdef DEBUGBUILD
{
char *p = getenv("CURL_WS_CHUNK_SIZE");
if(p) {
long l = strtol(p, NULL, 10);
if(l > 0 && l <= (1*1024*1024)) {
chunk_size = (size_t)l;
}
}
}
#endif
DEBUGF(infof(data, "WS, using chunk size %zu", chunk_size));
Curl_bufq_init2(&ws->recvbuf, chunk_size, WS_CHUNK_COUNT,
BUFQ_OPT_SOFT_LIMIT);
Curl_bufq_init2(&ws->sendbuf, WS_CHUNK_SIZE, WS_CHUNK_COUNT,
Curl_bufq_init2(&ws->sendbuf, chunk_size, WS_CHUNK_COUNT,
BUFQ_OPT_SOFT_LIMIT);
ws_dec_init(&ws->dec);
ws_enc_init(&ws->enc);
@ -834,7 +847,7 @@ CURLcode Curl_ws_accept(struct Curl_easy *data,
struct ws_collect {
struct Curl_easy *data;
void *buffer;
unsigned char *buffer;
size_t buflen;
size_t bufidx;
int frame_age;
@ -886,7 +899,7 @@ static ssize_t ws_client_collect(const unsigned char *buf, size_t buflen,
return -1;
}
*err = CURLE_OK;
memcpy(ctx->buffer, buf, nwritten);
memcpy(ctx->buffer + ctx->bufidx, buf, nwritten);
ctx->bufidx += nwritten;
}
return nwritten;