@@ -139,6 +139,13 @@ static void mongoose_event_handler_web_server(
139
139
}
140
140
ESP_LOGD (tag, " Event: %s [%d]" , mongoose_eventToString (event).c_str (), mgConnection->sock );
141
141
switch (event) {
142
+ case MG_EV_SEND: {
143
+ struct WebServerUserData *pWebServerUserData = (struct WebServerUserData *)mgConnection->user_data ;
144
+ WebServer *pWebServer = pWebServerUserData->pWebServer ;
145
+ pWebServer->continueConnection (mgConnection);
146
+ break ;
147
+ }
148
+
142
149
case MG_EV_HTTP_REQUEST: {
143
150
struct http_message *message = (struct http_message *) eventData;
144
151
dumpHttpMessage (message);
@@ -315,9 +322,7 @@ void WebServer::addPathHandler(const std::string& method, const std::string& pat
315
322
m_pathHandlers.push_back (PathHandler (method, pathExpr, handler));
316
323
} // addPathHandler
317
324
318
- void WebServer::addPathHandler (std::string&& method, const std::string& pathExpr,
319
- void (* handler)(WebServer::HTTPRequest* pHttpRequest,
320
- WebServer::HTTPResponse* pHttpResponse)) {
325
+ void WebServer::addPathHandler (std::string&& method, const std::string& pathExpr, void (* handler)(WebServer::HTTPRequest* pHttpRequest, WebServer::HTTPResponse* pHttpResponse)) {
321
326
m_pathHandlers.push_back (PathHandler (std::move (method), pathExpr, handler));
322
327
} // addPathHandler
323
328
@@ -482,6 +487,27 @@ void WebServer::HTTPResponse::sendData(const char* pData, size_t length) {
482
487
sendData ((uint8_t *) pData, length);
483
488
} // sendData
484
489
490
+ void WebServer::HTTPResponse::sendChunkHead () {
491
+ if (m_dataSent) {
492
+ ESP_LOGE (tag, " HTTPResponse: Chunk headers already sent! Attempt to send again/more." );
493
+ }
494
+ m_dataSent = true ;
495
+ mg_send_head (m_nc, m_status, -1 , m_headers.c_str ());
496
+ }
497
+
498
+ void WebServer::HTTPResponse::sendChunk (const char * pData, size_t length) {
499
+ mg_send_http_chunk (m_nc, pData, length);
500
+ } // sendChunkHead
501
+
502
+ void WebServer::HTTPResponse::closeConnection () {
503
+ m_nc->flags |= MG_F_SEND_AND_CLOSE;
504
+ }
505
+
506
+
507
+ void WebServer::HTTPResponse::sendData (const char * pData, size_t length) {
508
+ sendData ((uint8_t *) pData, length);
509
+ }
510
+
485
511
/* *
486
512
* @brief Set the headers to be sent in the HTTP response.
487
513
* @param [in] headers The complete set of headers to send to the caller.
@@ -564,15 +590,20 @@ void WebServer::processRequest(struct mg_connection *mgConnection, struct http_m
564
590
filePath += httpResponse.getRootPath ();
565
591
filePath.append (message->uri .p , message->uri .len );
566
592
ESP_LOGD (tag, " Opening file: %s" , filePath.c_str ());
567
- FILE * file = fopen (filePath.c_str (), " rb" );
593
+ FILE* file = fopen (filePath.c_str (), " rb" );
568
594
if (file != nullptr ) {
569
- fseek (file, 0L , SEEK_END);
570
- size_t length = ftell (file);
571
- fseek (file, 0L , SEEK_SET);
572
- uint8_t *pData = (uint8_t *)malloc (length);
573
- fread (pData, length, 1 , file);
574
- fclose (file);
575
- httpResponse.sendData (pData, length);
595
+ auto pData = (uint8_t *)malloc (MAX_CHUNK_LENGTH);
596
+ size_t read = fread (pData, 1 , MAX_CHUNK_LENGTH, file);
597
+
598
+ if (read >= MAX_CHUNK_LENGTH) {
599
+ httpResponse.sendChunkHead ();
600
+ httpResponse.sendChunk ((char *)pData, read);
601
+ fclose (unfinishedConnection[mgConnection->sock ]);
602
+ unfinishedConnection[mgConnection->sock ] = file;
603
+ } else {
604
+ fclose (file);
605
+ httpResponse.sendData (pData, read);
606
+ }
576
607
free (pData);
577
608
} else {
578
609
// Handle unable to open file
@@ -581,6 +612,26 @@ void WebServer::processRequest(struct mg_connection *mgConnection, struct http_m
581
612
}
582
613
} // processRequest
583
614
615
+ void WebServer::continueConnection (struct mg_connection * mgConnection) {
616
+ if (unfinishedConnection.count (mgConnection->sock ) == 0 ) {
617
+ return ;
618
+ }
619
+
620
+ HTTPResponse httpResponse = HTTPResponse (mgConnection);
621
+
622
+ FILE* file = unfinishedConnection[mgConnection->sock ];
623
+ auto pData = (char *) malloc (MAX_CHUNK_LENGTH);
624
+ size_t length = fread (pData, MAX_CHUNK_LENGTH, 1 , file);
625
+
626
+ httpResponse.sendChunk (pData, length);
627
+ if (length < MAX_CHUNK_LENGTH) {
628
+ fclose (file);
629
+ httpResponse.closeConnection ();
630
+ unfinishedConnection.erase (mgConnection->sock );
631
+ }
632
+ free (pData);
633
+ }
634
+
584
635
585
636
/* *
586
637
* @brief Construct an instance of a PathHandler.
0 commit comments