So you're a Noob? Post your questions here until you graduate! Don't be shy.

User avatar
By MProx
#82398 Hi all,

I'm not really sure where the line between "newbie" and "advanced" is, so I'm just going to post this here - feel free to move it if inappropriate.

I'm setting up an ESP8266 web server, and I have a page wherein I can upload files to the server's SPIFFS file system. I would like to expand upon this, and also specify a text field whereby the user can specify the path of the destination file when it is saved (currently is it saved in the root of the file system, and uses the original file name of the source file).

I have some HTML with a simple form, that includes the file upload as before, as well as an accompanying text field wherein the user can specify the path. This is the relevant part of the HTML:

Code: Select all<form method="post" enctype="multipart/form-data" action='/upload'>
    <input type="file" name="name">
    <input type="text" placeholder="Destination file path" aria-label="path" name="file_path">
    <input type="submit" value="Upload">
</form>


For GET requests, I would be able to access the parameter "file_path" in my request handler by invoking the following:

Code: Select allSerial.println(server.arg("file_path"));


But for POST requests, this doesn't seem to work - the above print statement prints an empty string, i.e. only a newline character.

For now, my code just tries to print the value in the text as above but saves the file as before (i.e. in root, with the original file name). I tried compiling my code with the HTTP_SERVER debug flag enabled, and I upload a simple test file with the string "/test/test.txt" in the file_path field. I see the following at the end of theserial debug output for the request:

PostArg Name: file_path
PostArg Type: text/plain
PostArg Value: /test/text.txt


So my parameters are being received and parsed, but are not available using
Code: Select allserver.arg("file_path");
.

Does anyone have any ideas?

if relevant, my response handler function is here:
https://pastebin.com/LxkjNJUm

And the full output of the debugger for the request (not including the output for serving up the "success.html" response) is here:
https://pastebin.com/k3P5NhCZ

Matt
User avatar
By wlad
#82435 My code with POST method works well, but I use
Code: Select allString(server.arg("haslo"))
. I can't remember why I'm Using this, I wrote this code few months ago. Here is my function with gettings args using POST method:
Code: Select allvoid handleSettings() {
  digitalWrite(led, 0);

  if (server.hasArg("haslo"))
  {
  //DEBUG
    /*for(int i=0; i<haslo.length(); i++)
    {
      Serial.print(int(haslo[i]));
      Serial.print(" ");
    }
    Serial.print("\n");

    for(int i=0; i<server.arg("haslo").length(); i++)
    {
      Serial.print(int(server.arg("haslo")[i]));
     
      Serial.print(" ");
    }*/
    if (String(server.arg("haslo")) == haslo)
    {
      String html;
      SPIFFS.begin();
      File f = SPIFFS.open("/settings.html", "r");
      while (f.position() < f.size())
      {
        html += f.readStringUntil('\n');
        html += "\n";
      }

      html.replace("%timezone%", String(timezone));
      html.replace("%wifi-ssid%", String(ssid));
      html.replace("%wifi-pass%", String(password));
      html.replace("%password%", String(haslo));
      if(summer)
      {
        html.replace("%checked%", "checked");
      }
      else
      {
        html.replace("%checked%", "");
      }

      server.send(200, "text/html", html);
      digitalWrite(led, 1);
      return;
    }
    else
    {
      String html;
      SPIFFS.begin();
      File f = SPIFFS.open("/login-badpass.html", "r");
      while (f.position() < f.size())
      {
        html += f.readStringUntil('\n');
        html += "\n";
      }
      server.send(200, "text/html", html);
      digitalWrite(led, 1);
      return;
    }
  }
  else if (server.hasArg("haslo1"))
  {
    if(server.arg("haslo1")==haslo)
    {
      if(server.hasArg("summer"))
      {
        summer=true;
      }
      else
      {
        summer=false;
      }
      if(server.hasArg("wifi-ssid"))
      {
        ssid=server.arg("wifi-ssid");
      }
      if(server.hasArg("wifi-pass"))
      {
        password=server.arg("wifi-pass");
      }
      if(server.hasArg("password"))
      {
        haslo=server.arg("password");
      }

      SPIFFS.begin();
      File sett = SPIFFS.open("/settings.txt", "w");
      String settings;
      if(summer)
      {
        settings="summer=true\n";
      }
      else
      {
        settings="summer=false\n";
      }
      settings+= "wifi-ssid="+ssid+"\n";
      settings+= "wifi-pass="+password+"\n";
      settings+= "password="+haslo;
      sett.print(settings);
    }
  }

  String html;
  SPIFFS.begin();
  File f = SPIFFS.open("/login.html", "r");
  while (f.position() < f.size())
  {
    html += f.readStringUntil('\n');
    html += "\n";
  }
  server.send(200, "text/html", html);
  digitalWrite(led, 1);
}
User avatar
By MProx
#82516 (sorry for the late reply - I didn't get any kind of notification for it)

Interesting. In my case, server.hasArg("file_path") returns 0. I wonder if it isn't POST requests, or if it's rather html form or file transfers specifically that it's being stubborn about. I looked at the source code here and it does seem to treat forms and files differently to other POST requests. I suspect that this may be a bug.

Your code seems to deal with a form but does it include a file transfer? Can you show the html (or other code) that generates the POST request?
User avatar
By MProx
#82518 Never mind, I found the problem.

I didn't realize that file uploads have a different format when specifying the handler functions. Normal POST request handler are specified with something like this:
Code: Select allserver.on("/webpage", HTTP_POST, handler_function);


But file upload handlers have the following syntax:
Code: Select allserver.on("/webpage", HTTP_POST, handler_function, file_upload_handler);


Or you would otherwise spe

The function file_upload_handler handles the upload (obviously) but form arguments are handled in the handler_function AFTER the upload has been handled.

So I achieved what I wanted to do by downloading the file with its original name, and then renaming it in handler_function to whatever the user specified in the file_path argument.