Arduino Playground is read-only starting December 31st, 2018. For more info please look at this Forum Post

This snippet shows how to use Webduino's setUrlPathCommand to serve files from the root directory of an SD card.

It supports:

  • Listing: curl "192.168.1.80/fs"
  • Download: curl "192.168.1.80/fs/TESTFILE.INO"
  • Delete: curl -X DELETE "192.168.1.80/fs/TESTFILE.INO"

Add the following line to the Ethernet/Webduino initialization

webserver.setUrlPathCommand(&fsAccessCmd);

Make sure that the SD is initialized and root points to the root directory. Then copy this code

void httpNotFound(WebServer &server){
  P(failMsg) =
    "HTTP/1.0 404 Bad Request" CRLF
    WEBDUINO_SERVER_HEADER
    "Content-Type: text/html" CRLF
    CRLF
    "<h2>File Not Found !</h2>";
  server.printP(failMsg);
}

void fsAccessCmd(WebServer &server, WebServer::ConnectionType type, char **url_path, char *url_tail, bool tail_complete)
{
  /*
    Use the following to test
      curl "192.168.1.80/fs"
      curl "192.168.1.80/fs/TESTFILE.INO"
      curl -X DELETE "192.168.1.80/fs/TESTFILE.INO"
    Sources
     - https://www.ladyada.net/learn/arduino/ethfiles.html
    Improvements
     - Expose a WebDav interface https://blog.coralbits.com/2011/07/webdav-protocol-for-dummies.html
   */

  if(!tail_complete) server.httpServerError();
  //Only serve files under the "/fs" path
  if(strncmp(url_path[0],"fs",3)!=0){
    DEBUG_PRINT_PL("Path not found 404");
    httpNotFound(server);
    return;
  }
  if(url_path[1]==0){
    // do an ls
    server.httpSuccess();
    dir_t p;
    root.rewind();
    while (root.readDir(p) > 0) {
      // done if past last used entry
      if (p.name[0] == DIR_NAME_FREE) break;
      // skip deleted entry and entries for . and  ..
      if (p.name[0] == DIR_NAME_DELETED || p.name[0] == '.') continue;
      for (uint8_t i = 0; i < 11; i++) {
        if (p.name[i] == ' ') continue;
        if (i == 8) {
          server.print('.');
        }
        server.print((char)p.name[i]);
      }
      server.print(CRLF);
    }
  }
  else{
    // access a file
    SdFile file;
    if (! file.open(&root, url_path[1], O_READ)) {
      httpNotFound(server);
    }
    else {
      if(type==WebServer::GET){
        server.httpSuccess("text/plain");
        char buf[32];
        int16_t  readed;
        readed = file.read(buf,30);
        while( readed > 0) {
          webserver.write(buf,readed);
          readed = file.read(buf,30);
        }
      }
      else if(type==WebServer::DELETE){
        DEBUG_PRINT_PL("DELETE");
        server.httpSuccess();
        SD.remove(url_path[1]);
      }
      file.close();
    }
  }
}

This has been tested using an ArduinoMega 2560 with a Wiznet 5100 based ethernet shield.