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
     - http://www.ladyada.net/learn/arduino/ethfiles.html
    Improvements
     - Expose a WebDav interface http://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.

Share