@@ -132,6 +132,94 @@ void webSocketsCreateFirmwareVersionString(char *firmwareString)
132132 strcat (firmwareString, " \0 " );
133133}
134134
135+ // ----------------------------------------
136+ // Display the request
137+ // ----------------------------------------
138+ void webSocketsDisplayRequest (httpd_req_t *req)
139+ {
140+ // Display the request and response
141+ if (settings.debugWebServer == true )
142+ {
143+ char ipAddress[80 ];
144+
145+ webSocketsGetClientIpAddressAndPort (req, ipAddress, sizeof (ipAddress));
146+ systemPrintf (" WebServer Client: %s%s\r\n " , ipAddress, req->uri );
147+ }
148+ }
149+
150+ // ----------------------------------------
151+ // Get the client IP address
152+ // ----------------------------------------
153+ void webSocketsGetClientIpAddressAndPort (httpd_req_t *req,
154+ char * ipAddress,
155+ size_t ipAddressBytes)
156+ {
157+ socklen_t addrBytes;
158+ const uint8_t ip4Address[12 ] =
159+ {
160+ 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 , 0xff , 0xff
161+ };
162+ struct sockaddr_in6 ip6Address;
163+ bool isIp6Address;
164+ size_t requiredStringLength;
165+ int socketFD;
166+ char temp[32 + 7 + 1 ];
167+
168+ // Validate the parameters
169+ if (ipAddress == nullptr )
170+ {
171+ systemPrintf (" ERROR: ipAddress must be specified in WebSockets\r\n " );
172+ return ;
173+ }
174+ if (ipAddressBytes == 0 )
175+ {
176+ systemPrintf (" ERROR: ipAddressBytes must be > 0 in WebSockets\r\n " );
177+ return ;
178+ }
179+ ipAddress[0 ] = 0 ;
180+
181+ // Get the socket's file descriptor
182+ socketFD = httpd_req_to_sockfd (req);
183+
184+ // Get the IP6 address of the client from the httpd server
185+ addrBytes = sizeof (ip6Address);
186+ if (getpeername (socketFD, (struct sockaddr *)&ip6Address, &addrBytes) < 0 )
187+ {
188+ if (settings.debugWebServer == true )
189+ systemPrintf (" ERROR: WebSockets failed to get client IP address\r\n " );
190+ return ;
191+ }
192+
193+ // Determine the type of IP address
194+ isIp6Address = (memcmp (&ip6Address.sin6_addr , &ip4Address, sizeof (ip4Address)) != 0 );
195+
196+ // Convert the IPv6 address into a string
197+ if (isIp6Address)
198+ inet_ntop (AF_INET6, &ip6Address.sin6_addr , temp, sizeof (temp));
199+ else
200+ inet_ntop (AF_INET, &ip6Address.sin6_addr .un .u8_addr [12 ], temp, sizeof (temp));
201+
202+ // Verify the length of the output buffer
203+ requiredStringLength = (isIp6Address ? 1 : 0 ) // Left bracket (IP6 only)
204+ + strlen (temp) // IP address
205+ + (isIp6Address ? 1 : 0 ) // Right bracket (IP6 only)
206+ + 1 // Colon
207+ + 5 // Port number
208+ + 1 ; // Zero termination
209+ if (ipAddressBytes < requiredStringLength)
210+ {
211+ if (settings.debugWebServer == true )
212+ systemPrintf (" ERROR: WebSockets failed to get client IP address\r\n " );
213+ return ;
214+ }
215+
216+ // Build the IP address string
217+ if (isIp6Address)
218+ sprintf (ipAddress, " [%s]:%d" , temp, ip6Address.sin6_port );
219+ else
220+ sprintf (ipAddress, " %s:%d" , temp, ip6Address.sin6_port );
221+ }
222+
135223// ----------------------------------------
136224// Handler for web sockets requests
137225// ----------------------------------------
@@ -293,6 +381,56 @@ static esp_err_t webSocketsHandler(httpd_req_t *req)
293381 return ret;
294382}
295383
384+ // ----------------------------------------
385+ // Generate the Not Found page
386+ // ----------------------------------------
387+ esp_err_t webSocketsHandlerPageNotFound (httpd_req_t *req, httpd_err_code_t err)
388+ {
389+ char ipAddress[80 ];
390+ String logMessage;
391+
392+ // Display an error
393+ webSocketsGetClientIpAddressAndPort (req, ipAddress, sizeof (ipAddress));
394+ logMessage = " WebSockets, Page " ;
395+ logMessage += req->uri ;
396+ logMessage += " not found, cliient: " ;
397+ logMessage += ipAddress;
398+ systemPrintln (logMessage);
399+
400+ /*
401+ if (settings.enableCaptivePortal == true && knownCaptiveUrl(webServer->uri()) == true)
402+ {
403+ if (settings.debugWebServer == true)
404+ {
405+ String logmessage =
406+ "Known captive URI: " + webServer->client().remoteIP().toString() + " " + webServer->uri();
407+ systemPrintln(logmessage);
408+ }
409+ webServer->sendHeader("Location", "/");
410+ webServer->send(302, "text/plain", "Redirect to Web Config");
411+ return;
412+ }
413+ */
414+
415+ // Set the 404 status code
416+ const char * statusText = " Error 404, page not found" ;
417+ httpd_resp_set_status (req, statusText);
418+
419+ // Set the content type
420+ httpd_resp_set_type (req, " text/html" );
421+
422+ // Send the response
423+ String htmlResponse = " <h1>" ;
424+ htmlResponse += statusText;
425+ htmlResponse += " </h1><p>The requested page (" ;
426+ htmlResponse += req->uri ;
427+ htmlResponse += " ) was not found.</p>" ;
428+ httpd_resp_send (req, htmlResponse.c_str (), htmlResponse.length ());
429+
430+ // Return ESP_OK to indicate the error was handled successfully
431+ return ESP_OK;
432+ }
433+
296434// ----------------------------------------
297435// Determine if webSockets is connected to a client
298436// ----------------------------------------
@@ -301,6 +439,26 @@ bool webSocketsIsConnected()
301439 return (webSocketsClientListHead != nullptr );
302440}
303441
442+ // ----------------------------------------
443+ // Register an error handler
444+ // ----------------------------------------
445+ bool webSocketsRegisterErrorHandler (httpd_err_code_t error,
446+ httpd_err_handler_func_t handler)
447+ {
448+ esp_err_t status;
449+
450+ // Register the error handler
451+ status = httpd_register_err_handler (webSocketsHandle, error, handler);
452+ if (settings.debugWebServer == true )
453+ {
454+ if (status == ESP_OK)
455+ systemPrintf (" webSockets registered %d error handler\r\n " , error);
456+ else
457+ systemPrintf (" webSockets Failed to register %d error handler!\r\n " , error);
458+ }
459+ return (status == ESP_OK);
460+ }
461+
304462// ----------------------------------------
305463// Send the formware version via web sockets
306464// ----------------------------------------
@@ -460,11 +618,29 @@ bool webSocketsStart(void)
460618 status = httpd_start (&webSocketsHandle, &config);
461619 if (status == ESP_OK)
462620 {
463- // Registering the ws handler
464- if (settings.debugWebServer == true )
465- systemPrintln (" webSockets registering URI handlers" );
466- httpd_register_uri_handler (webSocketsHandle, &webSocketsPage);
467- return true ;
621+ do
622+ {
623+ if (settings.debugWebServer == true )
624+ systemPrintln (" webSockets registering page handlers" );
625+
626+ // Register the page not found (404) error handler
627+ if (!webSocketsRegisterErrorHandler (HTTPD_404_NOT_FOUND,
628+ webSocketsHandlerPageNotFound))
629+ break ;
630+
631+ // Registering the ws handler
632+ if (settings.debugWebServer == true )
633+ systemPrintln (" webSockets registering URI handlers" );
634+ httpd_register_uri_handler (webSocketsHandle, &webSocketsPage);
635+
636+ // The web server is ready to handle incoming requests
637+ if (settings.debugWebServer )
638+ systemPrintf (" webSockets successfully started\r\n " );
639+ return true ;
640+ } while (0 );
641+
642+ // Stop the web server
643+ httpd_stop (webSocketsHandle);
468644 }
469645
470646 // Display the failure to start
0 commit comments