Browse code

lwsc: wait to read more data if not last ws fragment

- GH #2862

Daniel-Constantin Mierla authored on 01/10/2021 10:41:02
Showing 1 changed files
... ...
@@ -144,6 +144,7 @@ typedef struct lwsc_endpoint {
144 144
 	/* first LWS_PRE bytes must preserved for headers */
145 145
 	str wbuf;
146 146
 	str rbuf;
147
+	int rdone;
147 148
 	int tlson;
148 149
 	struct lws_protocols protocols[2];
149 150
 	struct lws_context_creation_info crtinfo;
... ...
@@ -226,6 +227,7 @@ static int ksr_lwsc_callback(struct lws *wsi, enum lws_callback_reasons reason,
226 227
 	lwsc_endpoint_t *ep = NULL;
227 228
 	str rbuf = STR_NULL;
228 229
 	str wbuf = STR_NULL;
230
+	int blen = 0;
229 231
 
230 232
 	if(_lwsc_verbosity>1) {
231 233
 		LM_DBG("callback called with reason %d\n", reason);
... ...
@@ -349,28 +351,35 @@ static int ksr_lwsc_callback(struct lws *wsi, enum lws_callback_reasons reason,
349 351
 			LM_DBG("LWS_CALLBACK_RECEIVE - wsi: %p len: %lu\n", wsi,
350 352
 					(unsigned long)len);
351 353
 #endif
354
+			ep = lwsc_get_endpoint_by_wsi(wsi);
355
+			if(ep==NULL) {
356
+				LM_ERR("no endpoint for wsi %p\n", wsi);
357
+				goto done;
358
+			}
359
+			pthread_mutex_lock(&ep->wslock);
352 360
 			if(len>0) {
353
-				ep = lwsc_get_endpoint_by_wsi(wsi);
354
-				if(ep==NULL) {
355
-					LM_ERR("no endpoint for wsi %p\n", wsi);
356
-					goto done;
357
-				}
358
-				rbuf.s = (char*)pkg_malloc(len + 1);
361
+				blen = ep->rbuf.len + len;
362
+				rbuf.s = (char*)pkg_malloc(blen + 1);
359 363
 				if(rbuf.s==NULL) {
360 364
 					PKG_MEM_ERROR;
361 365
 				} else {
362
-					memcpy(rbuf.s, in, len);
363
-					rbuf.len = len;
364
-					rbuf.s[rbuf.len] = '\0';
365
-					pthread_mutex_lock(&ep->wslock);
366 366
 					if(ep->rbuf.s!=NULL) {
367
-						LM_ERR("losing read buffer of %d bytes\n", ep->rbuf.len);
367
+						LM_DBG("append to read buffer of %d bytes more %d bytes\n",
368
+								ep->rbuf.len, (int)len);
369
+						memcpy(rbuf.s, ep->rbuf.s, ep->rbuf.len);
368 370
 						pkg_free(ep->rbuf.s);
371
+						ep->rbuf.s = NULL;
369 372
 					}
373
+					memcpy(rbuf.s + ep->rbuf.len, in, len);
374
+					rbuf.len = blen;
375
+					rbuf.s[rbuf.len] = '\0';
370 376
 					ep->rbuf = rbuf;
371
-					pthread_mutex_unlock(&ep->wslock);
372 377
 				}
373 378
 			}
379
+			if (lws_is_final_fragment(wsi)) {
380
+				ep->rdone = 1;
381
+			}
382
+			pthread_mutex_unlock(&ep->wslock);
374 383
 			break;
375 384
 
376 385
 		case LWS_CALLBACK_WS_PEER_INITIATED_CLOSE:
... ...
@@ -646,6 +655,7 @@ static int lwsc_api_request(str* wsurl, str *wsproto, str* sdata,
646 655
 		ep->rbuf.s = NULL;
647 656
 		ep->rbuf.len = 0;
648 657
 	}
658
+	ep->rdone = 0;
649 659
 	if(ep->wbuf.s!=NULL) {
650 660
 		LM_ERR("losing write buffer content of %d bytes\n", ep->wbuf.len);
651 661
 		pkg_free(ep->wbuf.s);
... ...
@@ -659,10 +669,13 @@ static int lwsc_api_request(str* wsurl, str *wsproto, str* sdata,
659 669
 
660 670
 	do {
661 671
 		pthread_mutex_lock(&ep->wslock);
662
-		if(ep->rbuf.s!=NULL) {
663
-			*rdata = ep->rbuf;
664
-			ep->rbuf.s = NULL;
665
-			ep->rbuf.len = 0;
672
+		if(ep->rdone==1) {
673
+			if(ep->rbuf.s!=NULL) {
674
+				*rdata = ep->rbuf;
675
+				ep->rbuf.s = NULL;
676
+				ep->rbuf.len = 0;
677
+			}
678
+			ep->rdone = 0;
666 679
 		}
667 680
 		pthread_mutex_unlock(&ep->wslock);
668 681
 		if(rdata->s==NULL) {