Webserver addition and TactilityC symbols (#451)

This commit is contained in:
Shadowtrance
2026-01-22 06:47:59 +10:00
committed by GitHub
parent c98cb2bf10
commit 01ffe420eb
22 changed files with 5006 additions and 21 deletions
+27 -7
View File
@@ -9,39 +9,58 @@ namespace tt::network {
static const auto LOGGER = Logger("HttpServer");
static constexpr size_t INTERNAL_URI_HANDLER_COUNT = 2;
bool HttpServer::startInternal() {
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.stack_size = stackSize;
config.server_port = port;
config.uri_match_fn = matchUri;
config.max_uri_handlers = handlers.size() + INTERNAL_URI_HANDLER_COUNT;
if (httpd_start(&server, &config) != ESP_OK) {
LOGGER.error("Failed to start http server on port {}", port);
return false;
}
bool allRegistered = true;
for (std::vector<httpd_uri_t>::reference handler : handlers) {
httpd_register_uri_handler(server, &handler);
if (httpd_register_uri_handler(server, &handler) != ESP_OK) {
LOGGER.error("Failed to register URI handler: {}", handler.uri);
allRegistered = false;
}
}
if (!allRegistered) {
httpd_stop(server);
server = nullptr;
return false;
}
LOGGER.info("Started on port {}", config.server_port);
return true;
}
void HttpServer::stopInternal() {
LOGGER.info("Stopping server");
if (server != nullptr && httpd_stop(server) != ESP_OK) {
LOGGER.warn("Error while stopping");
server = nullptr;
if (server != nullptr) {
if (httpd_stop(server) == ESP_OK) {
server = nullptr;
} else {
LOGGER.warn("Error while stopping");
}
}
}
void HttpServer::start() {
bool HttpServer::start() {
auto lock = mutex.asScopedLock();
lock.lock();
startInternal();
if (isStarted()) {
LOGGER.warn("Already started");
return true;
}
return startInternal();
}
void HttpServer::stop() {
@@ -50,6 +69,7 @@ void HttpServer::stop() {
if (!isStarted()) {
LOGGER.warn("Not started");
return;
}
stopInternal();
+22 -5
View File
@@ -83,18 +83,35 @@ std::unique_ptr<char[]> receiveByteArray(httpd_req_t* request, size_t length, si
return nullptr;
}
constexpr int MAX_TIMEOUT_RETRIES = 5;
int timeout_retries = 0;
while (bytesRead < length) {
size_t read_size = length - bytesRead;
size_t bytes_received = httpd_req_recv(request, buffer + bytesRead, read_size);
int bytes_received = httpd_req_recv(request, buffer + bytesRead, read_size);
if (bytes_received == HTTPD_SOCK_ERR_TIMEOUT) {
// Timeout - retry with backoff
timeout_retries++;
if (timeout_retries >= MAX_TIMEOUT_RETRIES) {
LOGGER.warn("Recv timeout after {} retries, read {}/{} bytes", timeout_retries, bytesRead, length);
free(buffer);
return nullptr;
}
LOGGER.warn("Recv timeout, retry {}/{}", timeout_retries, MAX_TIMEOUT_RETRIES);
vTaskDelay(pdMS_TO_TICKS(100 * timeout_retries)); // Exponential backoff
continue;
}
if (bytes_received <= 0) {
LOGGER.warn("Received error {} after reading {}/{} bytes", bytes_received, bytesRead, length);
free(buffer);
return nullptr;
}
// Successful read - reset timeout counter
timeout_retries = 0;
bytesRead += bytes_received;
}
return std::unique_ptr<char[]>(std::move(buffer));
return std::unique_ptr<char[]>(buffer);
}
std::string receiveTextUntil(httpd_req_t* request, const std::string& terminator) {
@@ -131,7 +148,7 @@ std::map<std::string, std::string> parseContentDisposition(const std::vector<std
auto parseable = content_disposition_header->substr(prefix.size());
auto parts = string::split(parseable, "; ");
for (auto part : parts) {
for (const auto& part : parts) {
auto key_value = string::split(part, "=");
if (key_value.size() == 2) {
// Trim trailing newlines
@@ -150,7 +167,7 @@ std::map<std::string, std::string> parseContentDisposition(const std::vector<std
bool readAndDiscardOrSendError(httpd_req_t* request, const std::string& toRead) {
size_t bytes_read;
auto buffer = receiveByteArray(request, toRead.length(), bytes_read);
if (bytes_read != toRead.length()) {
if (buffer == nullptr || bytes_read != toRead.length()) {
httpd_resp_send_err(request, HTTPD_400_BAD_REQUEST, "failed to read discardable data");
return false;
}
@@ -184,7 +201,7 @@ size_t receiveFile(httpd_req_t* request, size_t length, const std::string& fileP
LOGGER.error("Receive failed");
break;
}
if (fwrite(buffer, 1, receive_chunk_size, file) != receive_chunk_size) {
if (fwrite(buffer, 1, receive_chunk_size, file) != (size_t)receive_chunk_size) {
LOGGER.error("Failed to write all bytes");
break;
}