Skip to content

Commit

Permalink
Proposal of API change for v2 Feature: Middleware / Filters #161
Browse files Browse the repository at this point in the history
  • Loading branch information
mathieucarbou committed Aug 14, 2024
1 parent 483dbad commit ed921a8
Show file tree
Hide file tree
Showing 39 changed files with 457 additions and 462 deletions.
20 changes: 10 additions & 10 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ If you have existing code using ESPAsyncWebserver, you will feel right at home w

## Requests / Responses

* request->send is now request->reply()
* request->send is now response->send()
* if you create a response, call response->send() directly, not request->send(reply)
* request->headers() is not supported by ESP-IDF, you have to just check for the header you need.
* No AsyncCallbackJsonWebHandler (for now... can add if needed)
Expand Down Expand Up @@ -195,7 +195,7 @@ The ```server.on(...)``` returns a pointer to the endpoint, which can be used to

```cpp
//respond to /url only from requests to the AP
server.on("/url", HTTP_GET, request_callback)->setFilter(ON_AP_FILTER);
server.on("/url", HTTP_GET, request_callback)->addFilter(ON_AP_FILTER);

//require authentication on /url
server.on("/url", HTTP_GET, request_callback)->setAuthentication("user", "pass");
Expand All @@ -209,7 +209,7 @@ server.on("/ws")->attachHandler(&websocketHandler);
The ```PsychicWebHandler``` class is for handling standard web requests. It provides a single callback: ```onRequest()```. This callback is called when the handler receives a valid HTTP request.
One major difference from ESPAsyncWebserver is that this callback needs to return an esp_err_t variable to let the server know the result of processing the request. The ```response->reply()``` and ```request->send()``` functions will return this. It is a good habit to return the result of these functions as sending the response will close the connection.
One major difference from ESPAsyncWebserver is that this callback needs to return an esp_err_t variable to let the server know the result of processing the request. The ```response->send()``` and ```request->send()``` functions will return this. It is a good habit to return the result of these functions as sending the response will close the connection.
The function definition for the onRequest callback is:
Expand All @@ -223,7 +223,7 @@ Here is a simple example that sends back the client's IP on the URL /ip
server.on("/ip", [](PsychicRequest *request)
{
String output = "Your IP is: " + request->client()->remoteIP().toString();
return request->reply(output.c_str());
return response->send(output.c_str());
});
```

Expand Down Expand Up @@ -291,7 +291,7 @@ It's worth noting that there is no standard way of passing in a filename for thi
String url = "/" + request->getFilename();
String output = "<a href=\"" + url + "\">" + url + "</a>";
return request->reply(output.c_str());
return response->send(output.c_str());
});
//wildcard basic file upload - POST to /upload/filename.ext
Expand Down Expand Up @@ -349,7 +349,7 @@ Very similar to the basic upload, with 2 key differences:
output += "Param 1: " + request->getParam("param1")->value() + "<br/>\n";
output += "Param 2: " + request->getParam("param2")->value() + "<br/>\n";

return request->reply(output.c_str());
return response->send(output.c_str());
});

//upload to /multipart url
Expand All @@ -371,11 +371,11 @@ The ```server.serveStatic()``` function handles creating the handler and assigni
```cpp
//serve static files from LittleFS/www on / only to clients on same wifi network
//this is where our /index.html file lives
server.serveStatic("/", LittleFS, "/www/")->setFilter(ON_STA_FILTER);
server.serveStatic("/", LittleFS, "/www/")->addFilter(ON_STA_FILTER);
//serve static files from LittleFS/www-ap on / only to clients on SoftAP
//this is where our /index.html file lives
server.serveStatic("/", LittleFS, "/www-ap/")->setFilter(ON_AP_FILTER);
server.serveStatic("/", LittleFS, "/www-ap/")->addFilter(ON_AP_FILTER);
//serve static files from LittleFS/img on /img
//it's more efficient to serve everything from a single www directory, but this is also possible.
Expand Down Expand Up @@ -429,7 +429,7 @@ Here is a basic example of using WebSockets:

websocketHandler.onFrame([](PsychicWebSocketRequest *request, httpd_ws_frame *frame) {
Serial.printf("[socket] #%d sent: %s\n", request->client()->socket(), (char *)frame->payload);
return request->reply(frame);
return response->send(frame);
});

websocketHandler.onClose([](PsychicWebSocketClient *client) {
Expand All @@ -449,7 +449,7 @@ The onFrame() callback has 2 parameters:
For sending data on the websocket connection, there are 3 methods:
* ```request->reply()``` - only available in the onFrame() callback context.
* ```response->send()``` - only available in the onFrame() callback context.
* ```webSocketHandler.sendAll()``` - can be used anywhere to send websocket messages to all connected clients.
* ```client->send()``` - can be used anywhere* to send a websocket message to a specific client
Expand Down
8 changes: 4 additions & 4 deletions benchmark/psychichttp/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -170,7 +170,7 @@ void setup()
}

// our index
server.on("/", HTTP_GET, [](PsychicRequest* request) { return request->reply(200, "text/html", htmlContent); });
server.on("/", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) { return response->send(200, "text/html", htmlContent); });

// serve static files from LittleFS/www on /
server.serveStatic("/", LittleFS, "/www/");
Expand All @@ -180,7 +180,7 @@ void setup()
// client->sendMessage("Hello!");
});
websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame) {
request->reply(frame);
response->send(frame);
return ESP_OK; });
server.on("/ws", &websocketHandler);

Expand All @@ -189,7 +189,7 @@ void setup()
server.on("/events", &eventSource);

// api - parameters passed in via query eg. /api/endpoint?foo=bar
server.on("/api", HTTP_GET, [](PsychicRequest* request) {
server.on("/api", HTTP_GET, [](PsychicRequest* request, PsychicResponse* response) {
//create a response object
JsonDocument output;
output["msg"] = "status";
Expand All @@ -206,7 +206,7 @@ void setup()
//serialize and return
String jsonBuffer;
serializeJson(output, jsonBuffer);
return request->reply(200, "application/json", jsonBuffer.c_str()); });
return response->send(200, "application/json", jsonBuffer.c_str()); });

server.begin();
}
Expand Down
6 changes: 3 additions & 3 deletions benchmark/psychichttps/src/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -196,15 +196,15 @@ void setup()

// our index
server.on("/", HTTP_GET, [](PsychicRequest* request)
{ return request->reply(200, "text/html", htmlContent); });
{ return response->send(200, "text/html", htmlContent); });

// serve static files from LittleFS/www on /
server.serveStatic("/", LittleFS, "/www/");

// a websocket echo server
websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame)
{
request->reply(frame);
response->send(frame);
return ESP_OK; });
server.on("/ws", &websocketHandler);

Expand All @@ -227,7 +227,7 @@ void setup()
//serialize and return
String jsonBuffer;
serializeJson(output, jsonBuffer);
return request->reply(200, "application/json", jsonBuffer.c_str()); });
return response->send(200, "application/json", jsonBuffer.c_str()); });
}
}

Expand Down
24 changes: 12 additions & 12 deletions examples/arduino/arduino.ino
Original file line number Diff line number Diff line change
Expand Up @@ -220,11 +220,11 @@ void setup()

//serve static files from LittleFS/www on / only to clients on same wifi network
//this is where our /index.html file lives
server.serveStatic("/", LittleFS, "/www/")->setFilter(ON_STA_FILTER);
server.serveStatic("/", LittleFS, "/www/")->addFilter(ON_STA_FILTER);

//serve static files from LittleFS/www-ap on / only to clients on SoftAP
//this is where our /index.html file lives
server.serveStatic("/", LittleFS, "/www-ap/")->setFilter(ON_AP_FILTER);
server.serveStatic("/", LittleFS, "/www-ap/")->addFilter(ON_AP_FILTER);

//serve static files from LittleFS/img on /img
//it's more efficient to serve everything from a single www directory, but this is also possible.
Expand Down Expand Up @@ -267,14 +267,14 @@ void setup()
//serialize and return
String jsonBuffer;
serializeJson(output, jsonBuffer);
return request->reply(200, "application/json", jsonBuffer.c_str());
return response->send(200, "application/json", jsonBuffer.c_str());
});

//api - parameters passed in via query eg. /api/endpoint?foo=bar
server.on("/ip", HTTP_GET, [](PsychicRequest *request)
{
String output = "Your IP is: " + request->client()->remoteIP().toString();
return request->reply(output.c_str());
return response->send(output.c_str());
});

//api - parameters passed in via query eg. /api/endpoint?foo=bar
Expand All @@ -296,7 +296,7 @@ void setup()
//serialize and return
String jsonBuffer;
serializeJson(output, jsonBuffer);
return request->reply(200, "application/json", jsonBuffer.c_str());
return response->send(200, "application/json", jsonBuffer.c_str());
});

//how to redirect a request
Expand All @@ -310,15 +310,15 @@ void setup()
{
if (!request->authenticate(app_user, app_pass))
return request->requestAuthentication(BASIC_AUTH, app_name, "You must log in.");
return request->reply("Auth Basic Success!");
return response->send("Auth Basic Success!");
});

//how to do digest auth
server.on("/auth-digest", HTTP_GET, [](PsychicRequest *request)
{
if (!request->authenticate(app_user, app_pass))
return request->requestAuthentication(DIGEST_AUTH, app_name, "You must log in.");
return request->reply("Auth Digest Success!");
return response->send("Auth Digest Success!");
});

//example of getting / setting cookies
Expand Down Expand Up @@ -349,13 +349,13 @@ void setup()
output += "Param 1: " + request->getParam("param1")->value() + "<br/>\n";
output += "Param 2: " + request->getParam("param2")->value() + "<br/>\n";

return request->reply(output.c_str());
return response->send(output.c_str());
});

//you can set up a custom 404 handler.
server.onNotFound([](PsychicRequest *request)
{
return request->reply(404, "text/html", "Custom 404 Handler");
return response->send(404, "text/html", "Custom 404 Handler");
});

//handle a very basic upload as post body
Expand Down Expand Up @@ -394,7 +394,7 @@ void setup()
String url = "/" + request->getFilename();
String output = "<a href=\"" + url + "\">" + url + "</a>";

return request->reply(output.c_str());
return response->send(output.c_str());
});

//wildcard basic file upload - POST to /upload/filename.ext
Expand Down Expand Up @@ -443,7 +443,7 @@ void setup()
output += "Param 1: " + request->getParam("param1")->value() + "<br/>\n";
output += "Param 2: " + request->getParam("param2")->value() + "<br/>\n";

return request->reply(output.c_str());
return response->send(output.c_str());
});

//wildcard basic file upload - POST to /upload/filename.ext
Expand All @@ -456,7 +456,7 @@ void setup()
});
websocketHandler.onFrame([](PsychicWebSocketRequest *request, httpd_ws_frame *frame) {
Serial.printf("[socket] #%d sent: %s\n", request->client()->socket(), (char *)frame->payload);
return request->reply(frame);
return response->send(frame);
});
websocketHandler.onClose([](PsychicWebSocketClient *client) {
Serial.printf("[socket] connection #%u closed from %s\n", client->socket(), client->localIP().toString());
Expand Down
2 changes: 1 addition & 1 deletion examples/arduino/arduino_captive_portal/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public:
esp_err_t handleRequest(PsychicRequest *request) {
//PsychicFileResponse response(request, LittleFS, "/captiveportal.html"); // uncomment : for captive portal page, if any, eg "captiveportal.html"
//return response.send(); // uncomment : return captive portal page
return request->reply(200,"text/html","Welcome to captive portal !"); // simple text, comment if captive portal page
return response->send(200,"text/html","Welcome to captive portal !"); // simple text, comment if captive portal page
}
};
CaptiveRequestHandler *captivehandler=NULL; // handler for captive portal
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public:
esp_err_t handleRequest(PsychicRequest *request) {
//PsychicFileResponse response(request, LittleFS, "/captiveportal.html"); // uncomment : for captive portal page, if any, eg "captiveportal.html"
//return response.send(); // uncomment : return captive portal page
return request->reply(200,"text/html","Welcome to captive portal !"); // simple text, comment if captive portal page
return response->send(200,"text/html","Welcome to captive portal !"); // simple text, comment if captive portal page
}
};
CaptiveRequestHandler *captivehandler=NULL; // handler for captive portal
Expand Down
8 changes: 4 additions & 4 deletions examples/arduino/arduino_ota/arduino_ota.ino
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ void setup()
//you can set up a custom 404 handler.
// curl -i http://psychic.local/404
server.onNotFound([](PsychicRequest *request) {
return request->reply(404, "text/html", "Custom 404 Handler");
return response->send(404, "text/html", "Custom 404 Handler");
});

// OTA
Expand Down Expand Up @@ -182,13 +182,13 @@ void setup()
if (!Update.hasError()) { // update is OK
ESP_LOGI(TAG,"Update code or data OK Update.errorString() %s", Update.errorString());
result = "<b style='color:green'>Update done for file.</b>";
return request->reply(200,"text/html",result.c_str());
return response->send(200,"text/html",result.c_str());
// ESP.restart(); // restart ESP if needed
} // end update is OK
else { // update is KO, send request with pretty print error
result = " Update.errorString() " + String(Update.errorString());
ESP_LOGE(TAG,"ERROR : error %s",result.c_str());
return request->reply(500, "text/html", result.c_str());
return response->send(500, "text/html", result.c_str());
} // end update is KO
});

Expand All @@ -203,7 +203,7 @@ void setup()
String output = "<b style='color:green'>Restarting ...</b>";
ESP_LOGI(TAG,"%s",output.c_str());
esprestart=true;
return request->reply(output.c_str());
return response->send(output.c_str());
});
} // end onRequest

Expand Down
24 changes: 12 additions & 12 deletions examples/esp-idf/main/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -223,11 +223,11 @@ void setup()

// serve static files from LittleFS/www on / only to clients on same wifi network
// this is where our /index.html file lives
server.serveStatic("/", LittleFS, "/www/")->setFilter(ON_STA_FILTER);
server.serveStatic("/", LittleFS, "/www/")->addFilter(ON_STA_FILTER);

// serve static files from LittleFS/www-ap on / only to clients on SoftAP
// this is where our /index.html file lives
server.serveStatic("/", LittleFS, "/www-ap/")->setFilter(ON_AP_FILTER);
server.serveStatic("/", LittleFS, "/www-ap/")->addFilter(ON_AP_FILTER);

// serve static files from LittleFS/img on /img
// it's more efficient to serve everything from a single www directory, but this is also possible.
Expand Down Expand Up @@ -278,13 +278,13 @@ void setup()
//serialize and return
String jsonBuffer;
serializeJson(output, jsonBuffer);
return request->reply(200, "application/json", jsonBuffer.c_str()); });
return response->send(200, "application/json", jsonBuffer.c_str()); });

// api - parameters passed in via query eg. /api/endpoint?foo=bar
server.on("/ip", HTTP_GET, [](PsychicRequest* request)
{
String output = "Your IP is: " + request->client()->remoteIP().toString();
return request->reply(output.c_str()); });
return response->send(output.c_str()); });

// api - parameters passed in via query eg. /api/endpoint?foo=bar
server.on("/api", HTTP_GET, [](PsychicRequest* request)
Expand All @@ -305,7 +305,7 @@ void setup()
//serialize and return
String jsonBuffer;
serializeJson(output, jsonBuffer);
return request->reply(200, "application/json", jsonBuffer.c_str()); });
return response->send(200, "application/json", jsonBuffer.c_str()); });

// how to redirect a request
server.on("/redirect", HTTP_GET, [](PsychicRequest* request)
Expand All @@ -316,14 +316,14 @@ void setup()
{
if (!request->authenticate(app_user, app_pass))
return request->requestAuthentication(BASIC_AUTH, app_name, "You must log in.");
return request->reply("Auth Basic Success!"); });
return response->send("Auth Basic Success!"); });

// how to do digest auth
server.on("/auth-digest", HTTP_GET, [](PsychicRequest* request)
{
if (!request->authenticate(app_user, app_pass))
return request->requestAuthentication(DIGEST_AUTH, app_name, "You must log in.");
return request->reply("Auth Digest Success!"); });
return response->send("Auth Digest Success!"); });

// example of getting / setting cookies
server.on("/cookies", HTTP_GET, [](PsychicRequest* request)
Expand Down Expand Up @@ -352,11 +352,11 @@ void setup()
output += "Param 1: " + request->getParam("param1")->value() + "<br/>\n";
output += "Param 2: " + request->getParam("param2")->value() + "<br/>\n";

return request->reply(output.c_str()); });
return response->send(output.c_str()); });

// you can set up a custom 404 handler.
server.onNotFound([](PsychicRequest* request)
{ return request->reply(404, "text/html", "Custom 404 Handler"); });
{ return response->send(404, "text/html", "Custom 404 Handler"); });

// handle a very basic upload as post body
PsychicUploadHandler* uploadHandler = new PsychicUploadHandler();
Expand Down Expand Up @@ -394,7 +394,7 @@ void setup()
String url = "/" + request->getFilename();
String output = "<a href=\"" + url + "\">" + url + "</a>";

return request->reply(output.c_str()); });
return response->send(output.c_str()); });

// wildcard basic file upload - POST to /upload/filename.ext
server.on("/upload/*", HTTP_POST, uploadHandler);
Expand Down Expand Up @@ -442,7 +442,7 @@ void setup()
output += "Param 1: " + request->getParam("param1")->value() + "<br/>\n";
output += "Param 2: " + request->getParam("param2")->value() + "<br/>\n";

return request->reply(output.c_str()); });
return response->send(output.c_str()); });

// wildcard basic file upload - POST to /upload/filename.ext
server.on("/multipart", HTTP_POST, multipartHandler);
Expand All @@ -455,7 +455,7 @@ void setup()
websocketHandler.onFrame([](PsychicWebSocketRequest* request, httpd_ws_frame* frame)
{
Serial.printf("[socket] #%d sent: %s\n", request->client()->socket(), (char *)frame->payload);
return request->reply(frame); });
return response->send(frame); });
websocketHandler.onClose([](PsychicWebSocketClient* client)
{ Serial.printf("[socket] connection #%u closed from %s\n", client->socket(), client->localIP().toString().c_str()); });
server.on("/ws", &websocketHandler);
Expand Down
Loading

0 comments on commit ed921a8

Please sign in to comment.