Skip to content

Commit

Permalink
web_server: Skip chunks after the first send error.
Browse files Browse the repository at this point in the history
  • Loading branch information
rtrbt committed Nov 27, 2024
1 parent 6862d2d commit 6a0e4b9
Show file tree
Hide file tree
Showing 2 changed files with 55 additions and 0 deletions.
48 changes: 48 additions & 0 deletions software/src/modules/web_server/web_server.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -500,34 +500,82 @@ WebServerRequestReturnProtect WebServerRequest::send(uint16_t code, const char *

void WebServerRequest::beginChunkedResponse(uint16_t code, const char *content_type)
{
if (chunkedResponseState != ChunkedResponseState::NotStarted) {
// TODO: change this to esp_system_abort when 2.6.2 is released
logger.printfln("BUG: Multiple calls to beginChunkedResponse detected!");
chunkedResponseState = ChunkedResponseState::Failed;
return;
}

auto result = httpd_resp_set_type(req, content_type);
if (result != ESP_OK) {
chunkedResponseState = ChunkedResponseState::Failed;
printf("Failed to set response type: %s (0x%X)\n", esp_err_to_name(result), result);
return;
}

result = httpd_resp_set_status(req, httpStatusCodeToString(code));
if (result != ESP_OK) {
chunkedResponseState = ChunkedResponseState::Failed;
printf("Failed to set response status: %s (0x%X)\n", esp_err_to_name(result), result);
return;
}

chunkedResponseState = ChunkedResponseState::Started;
}

int WebServerRequest::sendChunk(const char *chunk, ssize_t chunk_len)
{
switch (chunkedResponseState) {
case ChunkedResponseState::Failed:
return ESP_FAIL;
case ChunkedResponseState::NotStarted:
chunkedResponseState = ChunkedResponseState::Failed;
// TODO: change this to esp_system_abort when 2.6.2 is released
logger.printfln("BUG: sendChunk was called before beginChunkedResponse!");
return ESP_FAIL;
case ChunkedResponseState::Ended:
chunkedResponseState = ChunkedResponseState::Failed;
// TODO: change this to esp_system_abort when 2.6.2 is released
logger.printfln("BUG: sendChunk was called after endChunkedResponse");
return ESP_FAIL;
case ChunkedResponseState::Started:
break;
}

auto result = httpd_resp_send_chunk(req, chunk, chunk_len);
if (result != ESP_OK) {
chunkedResponseState = ChunkedResponseState::Failed;
printf("Failed to send response chunk: %s (0x%X)\n", esp_err_to_name(result), result);
}
return result;
}

WebServerRequestReturnProtect WebServerRequest::endChunkedResponse()
{
switch (chunkedResponseState) {
case ChunkedResponseState::Failed:
return WebServerRequestReturnProtect{};
case ChunkedResponseState::NotStarted:
chunkedResponseState = ChunkedResponseState::Failed;
// TODO: change this to esp_system_abort when 2.6.2 is released
logger.printfln("BUG: endChunkedResponse was called before beginChunkedResponse!");
return this->send(500);
case ChunkedResponseState::Ended:
// TODO: change this to esp_system_abort when 2.6.2 is released
logger.printfln("BUG: endChunkedResponse was called twice!");
return WebServerRequestReturnProtect{};
case ChunkedResponseState::Started:
break;
}

auto result = httpd_resp_send_chunk(req, nullptr, 0);
if (result != ESP_OK) {
chunkedResponseState = ChunkedResponseState::Failed;
printf("Failed to end chunked response: %s (0x%X)\n", esp_err_to_name(result), result);
}

chunkedResponseState = ChunkedResponseState::Ended;
return WebServerRequestReturnProtect{};
}

Expand Down
7 changes: 7 additions & 0 deletions software/src/modules/web_server/web_server.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,13 @@ class WebServerRequest

private:
httpd_req_t *req;
enum class ChunkedResponseState {
NotStarted,
Started,
Failed,
Ended
};
ChunkedResponseState chunkedResponseState = ChunkedResponseState::NotStarted;
};

using wshCallback = std::function<WebServerRequestReturnProtect(WebServerRequest request)>;
Expand Down

0 comments on commit 6a0e4b9

Please sign in to comment.