Problems converting from ESPAsyncWebserver
Hello
I am having some issues converting from ESPAsyncWebserver and what calls to use to send files on the file system using the request->reply().
Currently I setup the server for root as follows:
server->on("/", HTTP_GET, handle_root);
server->begin();
which handles the root file as follows:
void handle_root(AsyncWebServerRequest *request)
{
// Redirect to index.html
request->send(SPIFFS, "/index.html", "text/html");
}
For Psychic I have changed this to:
server.config.max_uri_handlers = 20;
server.listen(80);
server.on("/", HTTP_GET, [](PsychicRequest *request) {
request->reply(200);
}, handle_root);
but I cannot find an example for sending a file using request->reply(), only a pre-configured file using the server.serveStatic(). As I would like to use this call to send differnet files and file types how can this be done ?
Regards David
What version of ESPAsnycWebserver are you migrating from? Because it just got a massive rework from @mathieucarbou and @me_no_dev and it is better than ever. I recommend to not migrate to Psychic because it has some bugs and @hoeken is pretty far away now to maintain this repo.
Check it out: https://github.com/ESP32Async/ESPAsyncWebServer/releases/tag/v3.7.2
What version of ESPAsnycWebserver are you migrating from? Because it just got a massive rework from @mathieucarbou and @me_no_dev and it is better than ever. I recommend to not migrate to Psychic because it has some bugs and @hoeken is pretty far away now to maintain this repo.
My understanding is that he needs SSL ;-)
My understanding is that he needs SSL ;-)
SSL is the ultimate goal, and ESPAsyncWebserver does not support that functionality, hence the need to move to Psychic.
What version of ESPAsnycWebserver are you migrating from? Because it just got a massive rework from @mathieucarbou and @me_no_dev and it is better than ever. I recommend to not migrate to Psychic because it has some bugs and @hoeken is pretty far away now to maintain this repo.
We are using the latest repros of ESPAsyncWebserver, which is great for HTTP, but HTTPS still seems a long way off.
If anyone can help with the above it would be appreciated.
I have implemented https and I do not recommend it. It is slow and unreliable but yes I can help you with that. As soon as iam at my desk i will write the solution
This is for Psychic V2
server.on("/", HTTP_GET, [](PsychicRequest *req, PsychicResponse *res) {
PsychicFileResponse response(
res, // The PsychicResponse object
LittleFS, // Preferred FS like SPIFFS or LitleFS
"pathToYourFile",
"text/html", // content type of the file
false // set it to true to make the client download the file and not render it
);
return response.send();
});
Hi @zekageri I will give that a try, thank you for your help so far.
@zekageri started with just your example code but cannot get that to compile:
no instance of constructor "PsychicFileResponse::PsychicFileResponse" matches the argument listC/C++(289)
Does not like the 'res' object:
Are you on V2?
V2 of what, latest version of PsychicWebserver is V1.2.1.
ESP packages:
PACKAGES:
- framework-arduinoespressif32 @ 3.1.3
- framework-arduinoespressif32-libs @ 5.3.0+sha.489d7a2b3a
- tool-esptoolpy @ 4.8.6
- tool-mklittlefs @ 3.2.0
- tool-riscv32-esp-elf-gdb @ 14.2.0+20240403
- tool-xtensa-esp-elf-gdb @ 14.2.0+20240403
- toolchain-xtensa-esp-elf @ 13.2.0+20240530
Sorry, there is a V2 branch which is not published. https://github.com/hoeken/PsychicHttp/tree/v2-dev
I have cloned the v2-dev branch using https://github.com/hoeken/PsychicHttp.git#v2-dev and everything is now compiling and I am able to see a very basic indelx.html page, thank you for the help.
Also, tried the SSL and although there are a number of errors being returned at the moment its definately somthing to builld on.
You can optimise it but it will be slow and the errors will not go away. :D i have tried optimising the hell out of it but eventually dropped the ssl thing
Glad it works hovewer!
I have added in the other file parser ie. css, js, jpg, xml etc. and most of the page is working now apart from the CSS stylesheet.
I am getting a few of the following errors on each page load:
[xxxx][E][PsychicResponse.cpp:114] send(): [psychic] Send response failed (ESP_ERR_HTTPD_RESP_SEND)
My load_file() process is modified from the original ESPAsyncWebserver and looks like this:
bool load_file(PsychicRequest *request, PsychicResponse *response)
{
String dataType = "text/plain";
String path = request->url();
// Process file type requested and set data type
if(path.endsWith("/")) path += "index.htm";
if(path.endsWith(".src")) path = path.substring(0, path.lastIndexOf("."));
else if(path.endsWith(".html")) dataType = "text/html";
else if(path.endsWith(".htm")) dataType = "text/html";
else if(path.endsWith(".css")) dataType = "text/css";
else if(path.endsWith(".js")) dataType = "application/javascript";
else if(path.endsWith(".png")) dataType = "image/png";
else if(path.endsWith(".gif")) dataType = "image/gif";
else if(path.endsWith(".jpg")) dataType = "image/jpeg";
else if(path.endsWith(".ico")) dataType = "image/x-icon";
else if(path.endsWith(".xml")) dataType = "text/xml";
else if(path.endsWith(".pdf")) dataType = "application/pdf";
else if(path.endsWith(".zip")) dataType = "application/zip";
// Open file and transfer to server
PsychicFileResponse response_send(
response,
SPIFFS,
path,
dataType,
false
);
response_send.send();
return true;
}
So not sure why the style sheet is not being used as the files are loading:
Loading the individual CSS files it looks like its the 'style.css' that is causing the error, I think because its being delivered to the page as 'chunked', whereas the other files just show a the content length.
I'm on an early development of something that are currently using ESP32AsyncWebServer and as I also need SSL (primary for websocket), does it work really well ? I read some comment above and still have no idea if they're working stable
It works up to a point. If you are serving small HTML files then it will work but very slowly and with lots of errors.
Even with psram enabled, mbedtls needs internal ram for some things so the browser will repeat a couple of requests on each page load because the esp fails to allocate memory for the tls handshake process. Also it is slow to serve pages anyway, again because of the tls allocations.
And it is not implementation or library problem. It's just too much for the esp to use it in prod. Ram is limited in both space and speed. If you manage to use the psram for most things, it is even slower especially if you use the flash meanwhile. Psram and flash shares the same spi bus so they slow each other down.
In an internal network, even webservers written for a raspberry pi will use regular http.
what if the esp does not have to serve site but only handing secure websocket, with esp32webserver I can archive that with quite low latency
Wss is working. Iam doing that with the official esp websocket client implementation. As wss server, i dont know. In theory it would be more lightweight since it have to do the handshake only once on initial connection/client
Also a dump question, in websocketHandler.onFrame, is there a way to not having return anything to the client at all ?
Well, idk. I think it requires you to return an esp_err type. Don't remember the cb. Will check it.
@designer-systems-ltd : (little off-topic): by the way, what use case do you have that really required to setup an SSL server certificate on a MCU, which will highly probably be self-signed and not recognised by any browser, and which will then prevent anyone from browsing ? Besides causing many issus (slowdown, memory and flash space, etc).
If this is to protect creds, client web UI could use a MCU public key to encrypt them, then pass them to the MCU which will be able to decrypt them with its private key. Could be done as JWT token.
on my case specifically, I'm trying to develop a web application which is PWA that allow controlling robot with gamepad,... (a.k.a FtcRobotController but for ESP32). To make them "installable", it's required that the site must be served via https, which lead to websocket connection must also be secure. atm I have to make a workaround that to install public cert into device and trust it, but as long as I only need to do it once, it's worth the trade-off.
Ok! You are in total control of who connects and with which device.
on my case specifically, I'm trying to develop a web application which is PWA that allow controlling robot with gamepad,... (a.k.a FtcRobotController but for ESP32). To make them "installable", it's required that the site must be served via https, which lead to websocket connection must also be secure. atm I have to make a workaround that to install public cert into device and trust it, but as long as I only need to do it once, it's worth the trade-off.
I went to hell and back with this. You can't automate the cert install. I have tried a dozen different ways to make it understandable to the user and convinient but it's just not possible. Every possible platform and os implements it differently. It sucks. I also wanted to install PWA which the esp serves. It can work but really complicated for the user.
Yes it's a pity that there is no easy way to automate those, I even tried to find a way for websocket client to "skip cert validation" but apparently there is none
beside if you managed to use PWA, then I believe there's no point serving site via ESP32, just reduce huge load on esp and make the app as large as you want it to