http upload with path?
Posted: Sun Aug 21, 2016 11:15 pm
I'm trying to figure out how the upload functionality works in the ESP8266WebServer, but - sorry to say it - the documentation SUCKS.
I see there are two callbacks and the second one seems to be evoked more than once I'm assuming since it tests for three different states to decide whether to open a file/output handle, stream content to the handle, or close the handle. The other seems to be what is called when it's all finished.
Most of the examples I see just upload to the root of the SD card and don't check any other parameters. I wrote a function to check for a 'dir' parameter and then check to see if the 'dir' exists and is in fact a directory. I then managed to get the upload.filename concatenated to it. But When I try to put it somewhere in the handleUpload, I get crash after crash no matter how I try to place it.
So how in the hell do you parse a parameter in conjunction with the handleUpload functionality and still report errors and messages properly? i.e. if the directory doesn't exist, I want it to fail out due to that without even doing the upload. Otherwise, if it complete successfully, I want it to send a 200 with a little more user friendly message than a blank screen with a 200 code!
I tried something like this using the SD web server example. I added two String variables 'serverError' and 'serverMessage' globally and clear them out before starting each 'loop' call to handleClient. (I also clear them after running my returnFail or returnMessage calls)
In setup:
handleFileUpload:
getDirArg:
return with status functions:
I see there are two callbacks and the second one seems to be evoked more than once I'm assuming since it tests for three different states to decide whether to open a file/output handle, stream content to the handle, or close the handle. The other seems to be what is called when it's all finished.
Most of the examples I see just upload to the root of the SD card and don't check any other parameters. I wrote a function to check for a 'dir' parameter and then check to see if the 'dir' exists and is in fact a directory. I then managed to get the upload.filename concatenated to it. But When I try to put it somewhere in the handleUpload, I get crash after crash no matter how I try to place it.
So how in the hell do you parse a parameter in conjunction with the handleUpload functionality and still report errors and messages properly? i.e. if the directory doesn't exist, I want it to fail out due to that without even doing the upload. Otherwise, if it complete successfully, I want it to send a 200 with a little more user friendly message than a blank screen with a 200 code!
I tried something like this using the SD web server example. I added two String variables 'serverError' and 'serverMessage' globally and clear them out before starting each 'loop' call to handleClient. (I also clear them after running my returnFail or returnMessage calls)
In setup:
Code: Select all
server.on("/edit", HTTP_POST, []() {
if (serverError != "") {
returnFail(serverError);
} else if (serverMessage != "") {
returnMsg(serverMessage);
} else {
returnMsg("upload");
}
serverMessage = "";
serverError = "";
}, handleFileUpload);
handleFileUpload:
Code: Select all
void handleFileUpload() {
if (server.uri() != "/edit") return;
HTTPUpload& upload = server.upload();
if (upload.status == UPLOAD_FILE_START) {
String fn = getDirArg() + upload.filename;
if (serverError == "") {
serverMessage = "uploading";
DBG_OUTPUT_PORT.print("Upload: START, filename: ");
DBG_OUTPUT_PORT.println(fn);
if (SD.exists(fn)) {
serverMessage += " over";
DBG_OUTPUT_PORT.println("file exists, deleting!");
// todo check to make sure file isn't a directory
SD.remove(fn);
}
serverMessage += " " + fn;
uploadFile = SD.open(fn, FILE_WRITE);
DBG_OUTPUT_PORT.println("opened!");
}
} else if ((upload.status == UPLOAD_FILE_WRITE) && (serverError == "")) {
if (uploadFile) uploadFile.write(upload.buf, upload.currentSize);
DBG_OUTPUT_PORT.print("Upload: WRITE, Bytes: ");
DBG_OUTPUT_PORT.println(upload.currentSize);
} else if ((upload.status == UPLOAD_FILE_END) && (serverError == "")) {
if (uploadFile) uploadFile.close();
DBG_OUTPUT_PORT.print("Upload: END, Size: ");
DBG_OUTPUT_PORT.println(upload.totalSize);
}
}
getDirArg:
Code: Select all
String getDirArg() {
String d = (server.hasArg("dir")) ? server.arg("dir") : "";
d.trim();
char dChar[d.length() + 1];
d.toCharArray(dChar, d.length() + 1);
if ((d != "/") && (d != "")) {
if (SD.exists(dChar)) {
File df = SD.open(d);
if (df.isDirectory()) {
if (!(d.endsWith("/"))) d += "/"; // add trailing slash if needed
} else {
serverError = "GETPATH: PATH NOT DIR";
}
df.close();
} else {
serverError = "GETPATH: PATH NOT EXIST";
}
}
return d;
}
return with status functions:
Code: Select all
void returnOK() {
server.send(200, "text/plain", "");
}
void returnMsg(String msg) {
server.send(200, "text/plain", msg + " successful\r\n");
}
void returnFail(String msg) {
server.send(500, "text/plain", msg + "\r\n");
}