added handlers to file server
This commit is contained in:
parent
5ab7c053b9
commit
af7911277d
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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_ */
|
||||
|
|
|
|||
|
|
@ -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, "<!DOCTYPE html><html><body>");
|
||||
|
||||
|
|
@ -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 */
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
80
upload_script.html
Normal file
80
upload_script.html
Normal file
|
|
@ -0,0 +1,80 @@
|
|||
<table class="fixed" border="0">
|
||||
<col width="1000px" /><col width="500px" />
|
||||
<tr><td>
|
||||
<h2>ESP32 File Server</h2>
|
||||
</td><td>
|
||||
<table border="0">
|
||||
<tr>
|
||||
<td>
|
||||
<label for="newfile">Upload a file</label>
|
||||
</td>
|
||||
<td colspan="2">
|
||||
<input id="newfile" type="file" onchange="setpath()" style="width:100%;">
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>
|
||||
<label for="filepath">Set path on server</label>
|
||||
</td>
|
||||
<td>
|
||||
<input id="filepath" type="text" style="width:100%;">
|
||||
</td>
|
||||
<td>
|
||||
<button id="upload" type="button" onclick="upload()">Upload</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</td></tr>
|
||||
</table>
|
||||
<script>
|
||||
function setpath() {
|
||||
var default_path = document.getElementById("newfile").files[0].name;
|
||||
document.getElementById("filepath").value = default_path;
|
||||
}
|
||||
function upload() {
|
||||
var filePath = document.getElementById("filepath").value;
|
||||
var upload_path = "/upload/" + filePath;
|
||||
var fileInput = document.getElementById("newfile").files;
|
||||
|
||||
/* Max size of an individual file. Make sure this
|
||||
* value is same as that set in file_server.c */
|
||||
var MAX_FILE_SIZE = 200*1024;
|
||||
var MAX_FILE_SIZE_STR = "200KB";
|
||||
|
||||
if (fileInput.length == 0) {
|
||||
alert("No file selected!");
|
||||
} else if (filePath.length == 0) {
|
||||
alert("File path on server is not set!");
|
||||
} else if (filePath.indexOf(' ') >= 0) {
|
||||
alert("File path on server cannot have spaces!");
|
||||
} else if (filePath[filePath.length-1] == '/') {
|
||||
alert("File name not specified after path!");
|
||||
} else if (fileInput[0].size > 200*1024) {
|
||||
alert("File size must be less than 200KB!");
|
||||
} else {
|
||||
document.getElementById("newfile").disabled = true;
|
||||
document.getElementById("filepath").disabled = true;
|
||||
document.getElementById("upload").disabled = true;
|
||||
|
||||
var file = fileInput[0];
|
||||
var xhttp = new XMLHttpRequest();
|
||||
xhttp.onreadystatechange = function() {
|
||||
if (xhttp.readyState == 4) {
|
||||
if (xhttp.status == 200) {
|
||||
document.open();
|
||||
document.write(xhttp.responseText);
|
||||
document.close();
|
||||
} else if (xhttp.status == 0) {
|
||||
alert("Server closed the connection abruptly!");
|
||||
location.reload()
|
||||
} else {
|
||||
alert(xhttp.status + " Error!\n" + xhttp.responseText);
|
||||
location.reload()
|
||||
}
|
||||
}
|
||||
};
|
||||
xhttp.open("POST", upload_path, true);
|
||||
xhttp.send(file);
|
||||
}
|
||||
}
|
||||
</script>
|
||||
Loading…
Reference in New Issue
Block a user