From 877d44059ef05ccc6bfa794ea1e47802b0bedf67 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Holger=20M=C3=BCller?= Date: Sun, 24 Mar 2024 23:52:28 +0100 Subject: [PATCH] Add url redirect (#8970) * added getAvailableVersion(), moved _httpClientTimeout and _followRedirects to protected, added enum HTTPUpdateError * auto numbering of HTTPUpdateError enum * added getAvailableVersion(), debug output current current Sketch MD5 * Revert "added getAvailableVersion(), debug output current current Sketch MD5" This reverts commit 60d2c7762e7fb1fed7fae37fa99be149e12f125c. * Revert "auto numbering of HTTPUpdateError enum" This reverts commit 61785b27da3f2d42f8f95316d78ce22e5b00103a. * Revert "added getAvailableVersion(), moved _httpClientTimeout and _followRedirects to protected, added enum HTTPUpdateError" This reverts commit cec84ed17ab149d3e48082293f9e2723246b7d0b. * add redirect function * enhanced redirect() by cache control and client stop * updated redirect() comment * replaced redirect() API calls in examples * server.client().stop() not needed, redirect() does this --- .../CaptivePortalAdvanced/handleHttp.ino | 11 ++------- .../NAPTCaptivePortal/PortalRedirectHttp.ino | 4 +--- .../examples/WebServer/WebServer.ino | 3 +-- .../ESP8266WebServer/src/ESP8266WebServer.h | 24 +++++++++++++++++++ 4 files changed, 28 insertions(+), 14 deletions(-) diff --git a/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino b/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino index aec2556a48..c7380017d1 100644 --- a/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino +++ b/libraries/DNSServer/examples/CaptivePortalAdvanced/handleHttp.ino @@ -27,9 +27,7 @@ void handleRoot() { boolean captivePortal() { if (!isIp(server.hostHeader()) && server.hostHeader() != (String(myHostname) + ".local")) { Serial.println("Request redirected to captive portal"); - server.sendHeader("Location", String("http://") + toStringIp(server.client().localIP()), true); - server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - server.client().stop(); // Stop is needed because we sent no content length + server.redirect(String("http://") + toStringIp(server.client().localIP())); return true; } return false; @@ -91,12 +89,7 @@ void handleWifiSave() { Serial.println("wifi save"); server.arg("n").toCharArray(ssid, sizeof(ssid) - 1); server.arg("p").toCharArray(password, sizeof(password) - 1); - server.sendHeader("Location", "wifi", true); - server.sendHeader("Cache-Control", "no-cache, no-store, must-revalidate"); - server.sendHeader("Pragma", "no-cache"); - server.sendHeader("Expires", "-1"); - server.send(302, "text/plain", ""); // Empty content inhibits Content-length header so we have to close the socket ourselves. - server.client().stop(); // Stop is needed because we sent no content length + server.redirect("wifi"); saveCredentials(); connect = strlen(ssid) > 0; // Request WLAN connect with new credentials if there is a SSID } diff --git a/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino b/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino index 286490772d..5de12229a5 100644 --- a/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino +++ b/libraries/DNSServer/examples/NAPTCaptivePortal/PortalRedirectHttp.ino @@ -36,13 +36,11 @@ void sendPortalRedirect(String path, String targetName) { If the "Location" header element works the HTML stuff is never seen. */ // https://tools.ietf.org/html/rfc7231#section-6.4.3 - server.sendHeader("Location", path, true); - addNoCacheHeader(); String reply = FPSTR(portalRedirectHTML); reply.reserve(reply.length() + 2 * path.length() + 80); reply.replace("{t}", targetName); reply.replace("{1}", path); - server.send(302, "text/html", reply); + server.redirect(path, reply); } #endif // LWIP_FEATURES && !LWIP_IPV6 diff --git a/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino b/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino index 81a58478f9..ffadddcca4 100644 --- a/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino +++ b/libraries/ESP8266WebServer/examples/WebServer/WebServer.ino @@ -43,8 +43,7 @@ void handleRedirect() { if (!LittleFS.exists(url)) { url = "/$update.htm"; } - server.sendHeader("Location", url, true); - server.send(302); + server.redirect(url); } // handleRedirect() diff --git a/libraries/ESP8266WebServer/src/ESP8266WebServer.h b/libraries/ESP8266WebServer/src/ESP8266WebServer.h index 397132f161..9f2b8b19c3 100644 --- a/libraries/ESP8266WebServer/src/ESP8266WebServer.h +++ b/libraries/ESP8266WebServer/src/ESP8266WebServer.h @@ -207,6 +207,30 @@ class ESP8266WebServerTemplate sendContent(emptyString); } + /** + * @brief Redirect to another URL, e.g. + * webserver.on("/index.html", HTTP_GET, []() { webserver.redirect("/"); }); + * There are 3 points of redirection here: + * 1) "Location" element in the header + * 2) Disable client caching + * 3) HTML "content" element to redirect + * If the "Location" header element works the HTML content is never seen. + * https://tools.ietf.org/html/rfc7231#section-6.4.3 + * @param url URL to redirect to + * @param content Optional redirect content + */ + void redirect(const String& url, const String& content = emptyString) { + sendHeader(F("Location"), url, true); + sendHeader(F("Cache-Control"), F("no-cache, no-store, must-revalidate")); + sendHeader(F("Pragma"), F("no-cache")); + sendHeader(F("Expires"), F("-1")); + send(302, F("text/html"), content); // send 302: "Found" + if (content.isEmpty()) { + // Empty content inhibits Content-length header so we have to close the socket ourselves. + client().stop(); // Stop is needed because we sent no content length + } + } + // Whether other requests should be accepted from the client on the // same socket after a response is sent. // This will automatically configure the "Connection" header of the response.