A Simple HTTP Server
We're now turning our board into a tiny web server that upon receiving a GET
request serves data from the internal temperature sensor.
Setup
You can find a prepared project skeleton in intro/http-server/
. It includes establishing a Wi-Fi connection, but you must configure it to use your network's credentials in cfg.toml
.
intro/http-server/examples/https-server.rs
contains a solution. You can run it with the following command:
cargo run --example http_server
Serving Requests
To connect to your board with your browser, you need to know the board's IP address.
✅ Run the skeleton code in intro/http-server
. The output should yield the board's IP address like this:
I (3862) esp_netif_handlers: sta ip: 192.168.178.54, mask: ...
...
Server awaiting connection
The sta ip
is the "station", the Wi-Fi term for an interface connected to an access point. This is the address you'll put in your browser (or other HTTP client like curl
).
🔎 ESP-IDF tries to register the hostname
espressif
in your local network, so oftenhttp://espressif/
instead ofhttp://<sta ip>/
will also work.You can change the hostname by setting
CONFIG_LWIP_LOCAL_HOSTNAME
insdkconfig.defaults
, e.g.:CONFIG_LWIP_LOCAL_HOSTNAME="esp32c3"
Sending HTTP data to a client involves:
- Creating an instance of
EspHttpServer
- Looping in the main function, so it doesn't terminate - termination would result in the server going out of scope and subsequently shutting down
- Setting a separate request
handler
function for each requested path you want to serve content. Any unconfigured path will result in a404
error. These handler functions are realized inline as Rust closures via:
#![allow(unused)] fn main() { server.fn_handler(path, Method::Get, |request| { // ... // construct a response let mut response = request.into_ok_response()?; // now you can write your desired data response.write_all(&some_buf)?; // once you're done the handler expects a `Completion` as result, // this is achieved via: Ok(()) }); }
✅ Create a EspHttpServer
instance using a default esp_idf_svc::http::server::Configuration
. The default configuration will cause it to listen on port 80 automatically.
✅ Verify that a connection to http://<sta ip>/
yields a 404
(not found) error stating This URI does not exist
.
✅ Write a request handler for requests to the root path ("/"
). The request handler sends a greeting message at http://<sta ip>/
, using the provided index_html()
function to generate the HTML String.
Dynamic Data
We can also report dynamic information to a client. The skeleton includes a configured temp_sensor
that measures the board's internal temperature.
✅ Write a second handler that reports the chip temperature at http://<sta ip>/temperature
, using the provided temperature(val: f32)
function to generate the HTML String.
💡 If you want to send a response string, it needs to be converted into a &[u8]
slice via a_string.as_bytes()
💡 The temperature sensor needs exclusive (mutable) access. Passing it as owned value into the handler will not work (since it would get dropped after the first invocation) - you can fix this by making the handler a move ||
closure, wrapping the sensor in an Arc<Mutex<_>>
, keeping one clone()
of this Arc
in your main function and moving the other into the closure.
Troubleshooting
httpd_txrx: httpd_resp_send_err
can be solved by restarting, orcargo clean
if nothing happens.- Make sure your computer and the Rust ESP Board are using the same Wi-Fi network.