diff --git a/CMakeLists.txt b/CMakeLists.txt
index 7aa6080..c8a30b3 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -3,6 +3,7 @@ idf_component_register(
"src/romfs.c"
"src/spifs.c"
"src/HTTPServer.c"
+ "src/FileServer.c"
"src/HTTPPrintSystem.c"
"src/HTTPPostSystem.c"
"src/Helpers.c"
@@ -18,6 +19,8 @@ idf_component_register(
INCLUDE_DIRS "."
"include"
"src"
+
+ EMBED_FILES "upload_script.html"
REQUIRES nvs_flash
libespfs
diff --git a/include/HTTPServer.h b/include/HTTPServer.h
index ad7131a..2edfcab 100644
--- a/include/HTTPServer.h
+++ b/include/HTTPServer.h
@@ -67,6 +67,18 @@ typedef enum
HTTP_IO_DONE_NOREFRESH
} HTTP_IO_RESULT;
+
+
+struct file_server_data
+{
+ /* Base path of file storage */
+ char base_path[ESP_VFS_PATH_MAX + 1];
+ char base_path2[ESP_VFS_PATH_MAX + 1];
+ /* Scratch buffer for temporary storage during file transfer */
+ char scratch[SCRATCH_BUFSIZE];
+/* Pointer to external POST handler*/
+};
+
typedef struct
{
const char tag[16];
@@ -81,4 +93,9 @@ esp_err_t start_file_server(void);
HTTP_IO_RESULT HTTPPostApp(httpd_req_t *req, const char *filename, char *PostData);
int HTTPPrint(httpd_req_t *req, char* buf, char* var);
+
+esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath);
+esp_err_t upload_post_handler(httpd_req_t *req);
+esp_err_t delete_post_handler(httpd_req_t *req);
+
#endif /* COMPONENTS_WEB_GUI_APPLICATION_INCLUDE_HTTPSERVER_H_ */
diff --git a/src/FileServer.c b/src/FileServer.c
index 3213230..4fe25c6 100644
--- a/src/FileServer.c
+++ b/src/FileServer.c
@@ -24,13 +24,47 @@
#include "HTTPServer.h"
-static const char *TAG = "HTTPServer";
+static const char *TAG = "FileServer";
+
+/* Copies the full path into destination buffer and returns
+ * pointer to path (skipping the preceding base path) */
+static const char* get_path_from_uri(char *dest, const char *base_path,
+ const char *uri,
+ size_t destsize)
+{
+ const size_t base_pathlen = strlen(base_path);
+ size_t pathlen = strlen(uri);
+
+ const char *quest = strchr(uri, '?');
+ if (quest)
+ {
+ pathlen = MIN(pathlen, quest - uri);
+ }
+ const char *hash = strchr(uri, '#');
+ if (hash)
+ {
+ pathlen = MIN(pathlen, hash - uri);
+ }
+
+ if (base_pathlen + pathlen + 1 > destsize)
+ {
+ /* Full path string won't fit into destination buffer */
+ return NULL;
+ }
+
+ /* Construct full path (base + path) */
+ strcpy(dest, base_path);
+ strlcpy(dest + base_pathlen, uri, pathlen + 1);
+
+ /* Return pointer to path, skipping the base */
+ return dest + base_pathlen;
+}
/* Send HTTP response with a run-time generated html consisting of
* a list of all files and folders under the requested path.
* In case of SPIFFS this returns empty list when path is any
* string other than '/', since SPIFFS doesn't support directories */
-static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
+esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
{
char entrypath[FILE_PATH_MAX];
char entrysize[16];
@@ -52,6 +86,8 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
return ESP_FAIL;
}
+
+
/* Send HTML file header */
httpd_resp_sendstr_chunk(req, "
");
@@ -116,7 +152,7 @@ static esp_err_t http_resp_dir_html(httpd_req_t *req, const char *dirpath)
}
/* Handler to upload a file onto the server */
-static esp_err_t upload_post_handler(httpd_req_t *req)
+esp_err_t upload_post_handler(httpd_req_t *req)
{
char filepath[FILE_PATH_MAX];
FILE *fd = NULL;
@@ -124,7 +160,7 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
/* Skip leading "/upload" from URI to get filename */
/* Note sizeof() counts NULL termination hence the -1 */
- const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
+ const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path2,
req->uri + sizeof("/upload") - 1, sizeof(filepath));
if (!filename) {
/* Respond with 500 Internal Server Error */
@@ -230,14 +266,14 @@ static esp_err_t upload_post_handler(httpd_req_t *req)
}
/* Handler to delete a file from the server */
-static esp_err_t delete_post_handler(httpd_req_t *req)
+esp_err_t delete_post_handler(httpd_req_t *req)
{
char filepath[FILE_PATH_MAX];
struct stat file_stat;
/* Skip leading "/delete" from URI to get filename */
/* Note sizeof() counts NULL termination hence the -1 */
- const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path,
+ const char *filename = get_path_from_uri(filepath, ((struct file_server_data *)req->user_ctx)->base_path2,
req->uri + sizeof("/delete") - 1, sizeof(filepath));
if (!filename) {
/* Respond with 500 Internal Server Error */
diff --git a/src/HTTPServer.c b/src/HTTPServer.c
index 582d8e0..9c90587 100644
--- a/src/HTTPServer.c
+++ b/src/HTTPServer.c
@@ -29,16 +29,6 @@ const char GZIP_SIGN[] = { 0x1f, 0x8b, 0x08 };
static esp_err_t GETHandler(httpd_req_t *req);
static esp_err_t CheckAuth(httpd_req_t *req);
-
-
-struct file_server_data
-{
- /* Base path of file storage */
- char base_path[ESP_VFS_PATH_MAX + 1];
- /* Scratch buffer for temporary storage during file transfer */
- char scratch[SCRATCH_BUFSIZE];
-/* Pointer to external POST handler*/
-};
struct file_server_data *server_data = NULL;
httpd_handle_t server = NULL;
static const char *TAG = "HTTPServer";
@@ -183,6 +173,7 @@ static esp_err_t POSTHandler(httpd_req_t *req)
#if HTTP_SERVER_DEBUG_LEVEL > 0
ESP_LOGI(TAG, "POST request handle");
#endif
+
char *buf = ((struct file_server_data*) req->user_ctx)->scratch;
int received;
int remaining = req->content_len;
@@ -215,10 +206,20 @@ static esp_err_t POSTHandler(httpd_req_t *req)
if (received)
{
char filepath[FILE_PATH_MAX];
+
const char *filename = get_path_from_uri(filepath,
((struct file_server_data*) req->user_ctx)->base_path,
req->uri,
sizeof(filepath));
+ ESP_LOGW(TAG, "filepath %s", filepath);
+
+ filename = get_path_from_uri(filepath,
+ ((struct file_server_data*) req->user_ctx)->base_path,
+ req->uri,
+ sizeof(filepath));
+
+
+
if (!memcmp(filename, "/api", 4))
{
@@ -295,6 +296,13 @@ static esp_err_t GETHandler(httpd_req_t *req)
return ESP_OK;
}
+
+ if (!strcmp(filename, "/files.html"))
+ {
+ return http_resp_dir_html(req, "/data");
+ }
+
+
//check auth for all files except status.json
if (strcmp(filename, "/status.json"))
{
@@ -528,6 +536,7 @@ esp_err_t start_file_server(void)
return ESP_ERR_NO_MEM;
}
strlcpy(server_data->base_path, "/", sizeof("/"));
+ strlcpy(server_data->base_path2, "/data", sizeof("/data"));
server = start_webserver();
return ESP_OK;
}
diff --git a/upload_script.html b/upload_script.html
new file mode 100644
index 0000000..5513ee8
--- /dev/null
+++ b/upload_script.html
@@ -0,0 +1,80 @@
+
+
+
+ ESP32 File Server
+ |
+
+ |
+
+