server.rs
1 /// HTTP server initialization and routing 2 use anyhow::Result; 3 use esp_idf_svc::http::server::{Configuration, EspHttpServer}; 4 use log::info; 5 use std::sync::Arc; 6 7 use super::handlers::*; 8 use super::state::WebServerState; 9 10 /// Initialize and start the HTTP server 11 pub fn start_web_server(state: Arc<WebServerState>) -> Result<EspHttpServer<'static>> { 12 let config = Configuration { 13 stack_size: 10240, // Increased from 8192 for safer operation with complex handlers 14 max_sessions: 5, // Increased from 3 to allow more concurrent users 15 max_open_sockets: 5, // Match max_sessions for optimal performance 16 ..Default::default() 17 }; 18 19 let mut server = EspHttpServer::new(&config)?; 20 21 // Clone state for each handler 22 let state_login_get = state.clone(); 23 let state_login_post = state.clone(); 24 let state_admin = state.clone(); 25 let state_update = state.clone(); 26 let state_logout = state.clone(); 27 let state_reboot = state.clone(); 28 let state_relay_on = state.clone(); 29 let state_relay_off = state.clone(); 30 let state_ota_check = state.clone(); 31 let state_ota_upload = state.clone(); 32 let state_stats_api = state.clone(); 33 let state_alarm_clear = state.clone(); 34 let state_download_settings = state.clone(); 35 let state_upload_settings = state.clone(); 36 37 // Route: GET / 38 server.fn_handler("/", embedded_svc::http::Method::Get, move |req| { 39 redirect_to_admin(req) 40 })?; 41 42 // Route: GET /login 43 server.fn_handler("/login", embedded_svc::http::Method::Get, move |req| { 44 handle_login_page(req, &state_login_get, None) 45 })?; 46 47 // Route: POST /login 48 server.fn_handler("/login", embedded_svc::http::Method::Post, move |req| { 49 handle_login_submit(req, &state_login_post) 50 })?; 51 52 // Route: GET /admin 53 server.fn_handler("/admin", embedded_svc::http::Method::Get, move |req| { 54 handle_admin_panel(req, &state_admin, None) 55 })?; 56 57 // Route: POST /update-settings 58 server.fn_handler( 59 "/update-settings", 60 embedded_svc::http::Method::Post, 61 move |req| handle_update_settings(req, &state_update), 62 )?; 63 64 // Route: GET /logout 65 server.fn_handler("/logout", embedded_svc::http::Method::Get, move |req| { 66 handle_logout(req, &state_logout) 67 })?; 68 69 // Route: GET /reboot 70 server.fn_handler("/reboot", embedded_svc::http::Method::Get, move |req| { 71 handle_reboot(req, &state_reboot) 72 })?; 73 74 // Route: POST /relay/on 75 server.fn_handler("/relay/on", embedded_svc::http::Method::Post, move |req| { 76 handle_relay_control(req, &state_relay_on, true) 77 })?; 78 79 // Route: POST /relay/off 80 server.fn_handler("/relay/off", embedded_svc::http::Method::Post, move |req| { 81 handle_relay_control(req, &state_relay_off, false) 82 })?; 83 84 // Route: GET /ota/check - Check for OTA updates 85 server.fn_handler("/ota/check", embedded_svc::http::Method::Get, move |req| { 86 handle_ota_check(req, &state_ota_check) 87 })?; 88 89 // Route: POST /ota/upload - Upload firmware 90 server.fn_handler( 91 "/ota/upload", 92 embedded_svc::http::Method::Post, 93 move |req| handle_ota_upload(req, &state_ota_upload), 94 )?; 95 96 // Route: GET /api/stats - Live statistics JSON API 97 server.fn_handler("/api/stats", embedded_svc::http::Method::Get, move |req| { 98 handle_stats_api(req, &state_stats_api) 99 })?; 100 101 // Route: POST /alarm/clear - Clear all alarm conditions 102 server.fn_handler( 103 "/alarm/clear", 104 embedded_svc::http::Method::Post, 105 move |req| handle_alarm_clear(req, &state_alarm_clear), 106 )?; 107 108 // Route: GET /download-settings - Download settings as TOML file 109 server.fn_handler( 110 "/download-settings", 111 embedded_svc::http::Method::Get, 112 move |req| handle_download_settings(req, &state_download_settings), 113 )?; 114 115 // Route: POST /upload-settings - Upload and restore settings from TOML file 116 server.fn_handler( 117 "/upload-settings", 118 embedded_svc::http::Method::Post, 119 move |req| handle_upload_settings(req, &state_upload_settings), 120 )?; 121 122 // New advanced device management endpoints 123 let state_device_status = state.clone(); 124 let state_ota_rollback = state.clone(); 125 let state_ota_mark_valid = state.clone(); 126 127 // Route: GET /api/device/status - Get device diagnostics 128 server.fn_handler( 129 "/api/device/status", 130 embedded_svc::http::Method::Get, 131 move |req| handle_device_status(req, &state_device_status), 132 )?; 133 134 // Route: POST /api/ota/rollback - Rollback to previous firmware 135 server.fn_handler( 136 "/api/ota/rollback", 137 embedded_svc::http::Method::Post, 138 move |req| handle_ota_rollback(req, &state_ota_rollback), 139 )?; 140 141 // Route: POST /api/ota/mark-valid - Mark current firmware as valid 142 server.fn_handler( 143 "/api/ota/mark-valid", 144 embedded_svc::http::Method::Post, 145 move |req| handle_ota_mark_valid(req, &state_ota_mark_valid), 146 )?; 147 148 info!("Web server started successfully"); 149 Ok(server) 150 }