//AsyncCallbackWebHandler& on(const char* uri, WebRequestMethodComposite method, ArRequestHandlerFunction onRequest, ArUploadHandlerFunction onUpload);
web_server.on("/flash_firmware", HTTP_POST,
[](AsyncWebServerRequest *request) {
Serial.println("in request handler");
//"update" is the name of the file input <input type='file' name='update'>
if (request->hasParam("update", true, true)) {
Serial.print("request handler - filesize: ");
Serial.println(String(request->getParam("update", true, true)->size()).c_str());
upload_file_size = request->getParam("update", true, true)->size();
}
},
[](AsyncWebServerRequest *request, const String &filename, size_t index, uint8_t *data, size_t len, bool final) {
Serial.println("in upload handler");
//"update" is the name of the file input <input type='file' name='update'>
if (request->hasParam("update", true, true)) {
Serial.print("(1) upload handler - filesize: ");
Serial.println(String(request->getParam("update", true, true)->size()).c_str());
upload_file_size = request->getParam("update", true, true)->size();
}
Serial.print("(2) upload handler - filesize: ");
Serial.println(upload_file_size);
//handle_flash_firmware(request, filename, index, data, len, final);
});
@me-no-dev I am trying to use `errorToString'
aClient->onError([](void * arg, AsyncClient * client, err_t error) {
ESP_LOGE( TAG, "aSyncClient error %i", error);
ESP_LOGE( TAG, "aSyncClient error code %s", errorToString(error)));
aClient = NULL;
delete client;
}, NULL);
but get this message:
In file included from /home/cellie/Arduino/hardware/espressif/esp32/cores/esp32/esp32-hal.h:45:0,
from /home/cellie/Arduino/hardware/espressif/esp32/cores/esp32/Arduino.h:35,
from /dev/shm/build/arduino/sketch/aSync_client.ino.cpp:1:
/home/cellie/Desktop/aSync_client/aSync_client.ino: In lambda function:
aSync_client:53:68: error: 'errorToString' was not declared in this scope
ESP_LOGE( TAG, "aSyncClient error code %s", errorToString(error)));
aClient->onError([](void * arg, AsyncClient * client, err_t error) {
ESP_LOGE( TAG, "aSyncClient error %i", error);
ESP_LOGE( TAG, "aSyncClient error code %s", client->errorToString(error));
aClient = NULL;
delete client;
}, NULL);
<form id='flash' method='POST' action='/flash_firmware' enctype='multipart/form-data'>
<!--need to upload filesize first because Content-Length [request->contentLength()] isn't the actual file size-->
<input id='filesize' name="filesize" value="0" style="display:none">
<input id='file' type='file' name='update'>
<p></p>
<input id='flash_btn' type='submit' value='Flash'>
</form>
<script>
document.querySelector('form').addEventListener('submit', (e) => {
document.getElementById('filesize').value = document.getElementById('file').files[0].size;
});
</script>
Hi!
I want to write a file upload handler class.
My current class is
class UpdateMasterRequestHandler : public AsyncWebHandler {
public:
UpdateMasterRequestHandler(/* args */) { }
virtual ~UpdateMasterRequestHandler() { }
bool canHandle(AsyncWebServerRequest *request);
void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final);
};
canHandle
returns true, but handleUpload
never gets called.
What am I doing wrong?
bool UpdateMasterRequestHandler::canHandle(AsyncWebServerRequest *request) {
bool forMe = request->url() == "/api/UpdateMaster"
&& request->method() == HTTP_POST
&& request->multipart();
if (forMe) logDebugln("UpdateMasterRequestHandler!");
return forMe;
}
void UpdateMasterRequestHandler::handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) {
if (index == 0) {
logDebug("UploadStart: ");
logDebugln(filename);
request->_tempFile = SPIFFS.open("master.hex", "w");
}
if (len > 0) {
request->_tempFile.write(data, len);
}
if (final) {
logDebug("UploadEnd: ");
logDebugln(filename);
request->_tempFile.close();
request->send(200, MIME_TYPE_PLAIN_TEXT, "Upload complete!");
}
}
HTML:<form id="masterUpdateForm" action="/api/UpdateMaster" method="POST" enctype="multipart/form-data">
Firmware: <input type="file" name="file" accept="*.hex">
<button type="submit">Update</button>
</form>
class UpdateMasterRequestHandler : public AsyncWebHandler {
public:
UpdateMasterRequestHandler(/* args */) { }
virtual ~UpdateMasterRequestHandler() { }
virtual bool canHandle(AsyncWebServerRequest *request) override final;
virtual void handleRequest(AsyncWebServerRequest *request) override final;
virtual void handleUpload(AsyncWebServerRequest *request, const String& filename, size_t index, uint8_t *data, size_t len, bool final) override final;
};
Backtrace: 0x4000c3f0:0x3ffd1380 0x400db076:0x3ffd13a0 0x400db192:0x3ffd13c0 0x400d7ad1:0x3ffd13e0 0x400d6192:0x3ffd1450 0x400d60f5:0x3ffd1490 0x400d145d:0x3ffd14b0 0x4015188f:0x3ffd14f0 0x400d9309:0x3ffd1510 0x400d6df1:0x3ffd1560 0x400d6eb5:0x3ffd15a0 0x400d7105:0x3ffd15f0 0x4014b7b1:0x3ffd1610 0x4014b82d:0x3ffd1650 0x4014bed6:0x3ffd1670 0x4008a286:0x3ffd16a0
#0 0x4000c3f0:0x3ffd1380 in ?? ??:0
#1 0x400db076:0x3ffd13a0 in String::move(String&) at C:\Users\OnurNP.platformio\packages\framework-arduinoespressif32\cores\esp32/WString.cpp:857
#2 0x400db192:0x3ffd13c0 in String::operator=(String&&) at C:\Users\OnurNP.platformio\packages\framework-arduinoespressif32\cores\esp32/WString.cpp:857
#3 0x400d7ad1:0x3ffd13e0 in AsyncBasicResponse::_respond(AsyncWebServerRequest) at lib\ESPAsyncWebServer\src/WebResponses.cpp:699
#4 0x400d6192:0x3ffd1450 in AsyncWebServerRequest::send(AsyncWebServerResponse) at lib\ESPAsyncWebServer\src/WebRequest.cpp:797
#5 0x400d60f5:0x3ffd1490 in AsyncWebServerRequest::send(int, String const&, String const&) at lib\ESPAsyncWebServer\src/WebRequest.cpp:797
#6 0x400d145d:0x3ffd14b0 in handleRoot(AsyncWebServerRequest) at src/main.cpp:289
#7 0x4015188f:0x3ffd14f0 in std::_Function_handler<void (AsyncWebServerRequest), void ()(AsyncWebServerRequest)>::_M_invoke(std::_Any_data const&,
AsyncWebServerRequest*&&) at c:\users\onurnp.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0/functional:1871
#8 0x400d9309:0x3ffd1510 in std::function<void (AsyncWebServerRequest*)>::operator()(AsyncWebServerRequest*) const at lib\ESPAsyncWebServer\src/StringArray.h:73
(inlined by) AsyncCallbackWebHandler::handleRequest(AsyncWebServerRequest*) at lib\ESPAsyncWebServer\src/WebHandlerImpl.h:132
#9 0x400d6df1:0x3ffd1560 in AsyncWebServerRequest::_parseLine() at lib\ESPAsyncWebServer\src/WebRequest.cpp:797
#10 0x400d6eb5:0x3ffd15a0 in AsyncWebServerRequest::_onData(void, unsigned int) at lib\ESPAsyncWebServer\src/WebRequest.cpp:797
#11 0x400d7105:0x3ffd15f0 in std::_Function_handler<void (void, AsyncClient, void, unsigned int), AsyncWebServerRequest::AsyncWebServerRequest(AsyncWebServer, AsyncClient)::{lambda(void, AsyncClient, void, unsigned int)#8}>::_M_invoke(std::_Any_data const&, void&&, AsyncClient*&&, std::_Any_data const&, unsigned int&&) at lib\ESPAsyncWebServer\src/WebRequest.cpp:797
(inlined by) _M_invoke at c:\users\onurnp\.platformio\packages\toolchain-xtensa32@2.50200.97\xtensa-esp32-elf\include\c++\5.2.0/functional:1871
#12 0x4014b7b1:0x3ffd1610 in std::function<void (void*, AsyncClient*, void*, unsigned int)>::operator()(void, AsyncClient, void*, unsigned int) const at lib\AsyncTCP\src/AsyncTCP.cpp:1039
(inlined by) AsyncClient::_recv(tcp_pcb*, pbuf*, signed char) at lib\AsyncTCP\src/AsyncTCP.cpp:934
#13 0x4014b82d:0x3ffd1650 in AsyncClient::_s_recv(void, tcp_pcb, pbuf, signed char) at lib\AsyncTCP\src/AsyncTCP.cpp:1039
#14 0x4014bed6:0x3ffd1670 in _async_service_task(void) at lib\AsyncTCP\src/AsyncTCP.cpp:1039
(inlined by) _async_service_task at lib\AsyncTCP\src/AsyncTCP.cpp:197
#15 0x4008a286:0x3ffd16a0 in vPortTaskWrapper at
/home/runner/work/esp32-arduino-lib-builder/esp32-arduino-lib-builder/esp-idf/components/freertos/port.c:355 (discriminator 1)