I see there is a new http_server module now in the ESP-IDF.
It looks interesting. What are it's features/benefits over some of the other servers available? (I've been using libesphttpd. Also I see nghttp module in the idf.)
The documentation is here: https://docs.espressif.com/projects/esp ... erver.html
But I don't see an example of serving static files from the filesystem. Does anyone have an example project showing how to do that?
Thanks.
http_server filesystem handler example?
Re: http_server filesystem handler example?
I am assuming you are talking about serving web pages. I have something similar it serves up web pages stored in program memory, added as header files. Her are som code snippets
You also need a shell script to convert the html files (or any other type of file) to a header to be included in the project. Note that the files are gzipped so they use less program memory.
Code: Select all
// include your web page a header file
#include "web_index.h"
// code to pass character pointer and size of web page
typedef struct {
const unsigned char *resp;
size_t *resp_len;
} WEBKIT_RESPONSE_ARGS;
WEBKIT_RESPONSE_ARGS webkit_index_args = { index_htm_gz, &index_htm_gz_len };
// function prototype
esp_err_t webkit_request_handler(httpd_req_t *req);
// structure for registering callback for browser index request.
httpd_uri_t webkit_index_req = { .uri = "/", .method = HTTP_GET, .handler = webkit_request_handler, .user_ctx = (void *)&webkit_index_args };
// Function to send back web page
esp_err_t webkit_request_handler(httpd_req_t *req)
{
WEBKIT_RESPONSE_ARGS* args = (WEBKIT_RESPONSE_ARGS *)(req->user_ctx);
httpd_resp_set_type(req, HTTPD_TYPE_TEXT);
httpd_resp_set_hdr(req, "Content-Encoding", "gzip");
httpd_resp_send(req, (const char*)args->resp, *(args->resp_len));
return ESP_OK;
}
// function to start web server and register callback for index page
httpd_handle_t start_webserver(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
config.max_uri_handlers = 20;
if (httpd_start(&server, &config) == ESP_OK) {
httpd_register_uri_handler(server, &webkit_index_req);
return server;
}
return NULL;
}
Code: Select all
#!/bin/bash
gzip -k index.htm
xxd -i index.htm.gz ../main/web_index.h
rm *.gz
-
- Posts: 19
- Joined: Fri Aug 31, 2018 5:37 am
Re: http_server filesystem handler example?
Presently there is no out of the box support for file sharing, though it is something desirable and will be made available in future. Till then, implementing a simple file server should not be difficult. Take for this as an example :
So in order to download a file one can run something like this :
Assuming "10.0.0.152" is the IP assigned to ESP32, and there is a file "music/song.mp3" in the FAT formatted sdcard.
Code: Select all
/* HTTP GET handler for downloading files */
esp_err_t file_get_handler(httpd_req_t *req)
{
/* Assuming that the sdcard has been initialized (formatted to FAT) and loaded with some files.
* Refer to sd_card_example to to know how to initialize the sd card */
const char *filepath_prefix = "/sdcard/";
char *filename = NULL;
size_t filename_len = httpd_req_get_url_query_len(req);
if (filename_len == 0) {
const char * resp_str = "Please specify a filename. eg. file?somefile.txt";
httpd_resp_send(req, resp_str, strlen(resp_str));
return ESP_OK;
}
filename = malloc(strlen(filepath_prefix) + filename_len + 1); // extra 1 byte for null termination
strncpy(filename, filepath_prefix, strlen(filepath_prefix));
// Get null terminated filename
httpd_req_get_url_query_str(req, filename + strlen(filepath_prefix), filename_len + 1);
ESP_LOGI(TAG, "Reading file : %s", filename + strlen(filepath_prefix));
FILE *f = fopen(filename, "r");
free(filename);
if (f == NULL) {
const char * resp_str = "File doesn't exist";
httpd_resp_send(req, resp_str, strlen(resp_str));
return ESP_OK;
}
/* Read file in chunks (relaxes any constraint due to large file sizes)
* and send HTTP response in chunked encoding */
char chunk[1024];
size_t chunksize;
do {
chunksize = fread(chunk, 1, sizeof(chunk), f);
if (httpd_resp_send_chunk(req, chunk, chunksize) != ESP_OK) {
fclose(f);
return ESP_FAIL;
}
} while (chunksize != 0);
httpd_resp_send_chunk(req, NULL, 0);
fclose(f);
return ESP_OK;
}
httpd_handle_t start_file_server(void)
{
httpd_handle_t server = NULL;
httpd_config_t config = HTTPD_DEFAULT_CONFIG();
httpd_uri_t file_serve = {
.uri = "/file",
.method = HTTP_GET,
.handler = file_get_handler,
.user_ctx = NULL
};
// Start the httpd server
ESP_LOGI(TAG, "Starting server on port: %d", config.server_port);
if (httpd_start(&server, &config) == ESP_OK) {
// Set URI handlers
ESP_LOGI(TAG, "Registering URI handlers");
httpd_register_uri_handler(server, &file_serve);
return server;
}
ESP_LOGI(TAG, "Error starting server!");
return NULL;
}
Code: Select all
curl http://10.0.0.152:80/file?music/song.mp3 > song.mp3
Who is online
Users browsing this forum: noweare and 134 guests