Can't access a file in a folder in SD card using a web server

Hello everyone,
I have an Arduino web server and i create a file every day in the SD card. At first i had the file saved in the main SD directory (where i have also placed the .htm file) and everything worked perfectly. Using the address “/filename” would open the file. Then to have things more tidy i thought of adding some extra folders and so now i create e.g. this path: “LOGFILES/19/8-27.txt”. The code i use for this is as follows:

    m = rtc.getTime().mon;
    d = rtc.getTime().date;
    y = rtc.getTime().year-2000; // y-2000 will return only the last 2 digits of the year
    sprintf(path,"/%s/%d","LOGFILES",y);
    if (!SD.exists(path)) {
      SD.mkdir(path);
    }
    sprintf(filename, "/%s/%d/%d-%d.txt","LOGFILES", y, m, d);
    
    prev_log_time = current_time;
    // the log time has elapsed, so log another set of data
    logFile = SD.open(filename, FILE_WRITE);

The code works just fine, the path and the file are created in the SD card and everything looks good. But now if i type in the browser “/LOGFILES/19/8-27.txt” the file cant be opened but i know its there. Any ideas why this is happening?

wrong code snippet? how do you process the request?

Here is the part of the code that processes the requests:

bool ServiceClient(EthernetClient *client)
{
  static boolean currentLineIsBlank = true;
  char cl_char;
  File webFile;
  // file name from request including path + 1 of null terminator
  char file_name[FILE_NAME_LEN + 1] = {0};  // requested file name
  char http_req_type = 0;
  char req_file_type = FT_INVALID;
  const char *file_types[] = {"text/html", "image/x-icon", "text/css", "application/javascript", "image/jpeg", "image/png", "image/gif", "text/plain"};
  
  static char req_line_1[40] = {0};  // stores the first line of the HTTP request
  static unsigned char req_line_index = 0;
  static bool got_line_1 = false;

  if (client->available()) {   // client data available to read
    cl_char = client->read();
    
    if ((req_line_index < 39) && (got_line_1 == false)) {
      if ((cl_char != '\r') && (cl_char != '\n')) {
        req_line_1[req_line_index] = cl_char;
        req_line_index++;
      }
      else {
        got_line_1 = true;
        req_line_1[39] = 0;
      }
    }
    
    if ((cl_char == '\n') && currentLineIsBlank) {
      // get HTTP request type, file name and file extension type index
      http_req_type = GetRequestedHttpResource(req_line_1, file_name, &req_file_type);
      if (http_req_type == HTTP_GET) {         // HTTP GET request
        if (req_file_type < FT_INVALID) {      // valid file type
          webFile = SD.open(file_name);        // open requested file
          if (webFile) {
            // send a standard http response header
            client->println(F("HTTP/1.1 200 OK"));
            client->print(F("Content-Type: "));
            client->println(file_types[req_file_type]);
            client->println(F("Connection: close"));
            client->println();
            // send web page
            while(webFile.available()) {
              int num_bytes_read;
              char byte_buffer[64];
              // get bytes from requested file
              num_bytes_read = webFile.read(byte_buffer, 64);
              // send the file bytes to the client
              client->write(byte_buffer, num_bytes_read);
            }
            webFile.close();
          }
          else {
            // failed to open file
          }
        }
        else {
          // invalid file type
        }
      }
      else if (http_req_type == HTTP_POST) {
        // a POST HTTP request was received
      }
      else {
        // unsupported HTTP request received
      }
      req_line_1[0] = 0;
      req_line_index = 0;
      got_line_1 = false;
      // finished sending response and web page
      return 1;
    }
    if (cl_char == '\n') {
      currentLineIsBlank = true;
    }
    else if (cl_char != '\r') {
      currentLineIsBlank = false;
    }
  }  // if (client.available())
  return 0;
}

// extract file name from first line of HTTP request
char GetRequestedHttpResource(char *req_line, char *file_name, char *file_type)
{
  char request_type = HTTP_invalid;  // 1 = GET, 2 = POST. 0 = invalid
  char *str_token;
  
  *file_type = FT_INVALID;
  
  str_token =  strtok(req_line, " ");    // get the request type
  if (strcmp(str_token, "GET") == 0) {
    request_type = HTTP_GET;
    str_token =  strtok(NULL, " ");      // get the file name
    if (strcmp(str_token, "/") == 0) {
      strcpy(file_name, "index.htm");
      *file_type = FT_HTML;
    }
    else if (strlen(str_token) <= FILE_NAME_LEN) {
      // file name is within allowed length
      strcpy(file_name, str_token);
      // get the file extension
      str_token = strtok(str_token, ".");
      str_token = strtok(NULL, ".");
      
      if      (strcmp(str_token, "htm") == 0) {*file_type = 0;}
      else if (strcmp(str_token, "ico") == 0) {*file_type = 1;}
      else if (strcmp(str_token, "css") == 0) {*file_type = 2;}
      else if (strcmp(str_token, "js")  == 0) {*file_type = 3;}
      else if (strcmp(str_token, "jpg") == 0) {*file_type = 4;}
      else if (strcmp(str_token, "png") == 0) {*file_type = 5;}
      else if (strcmp(str_token, "gif") == 0) {*file_type = 6;}
      else if (strcmp(str_token, "txt") == 0) {*file_type = 7;}
      else {*file_type = 8;}
    }
    else {
      // file name too long
    }
  }
  else if (strcmp(str_token, "POST") == 0) {
    request_type = HTTP_POST;
  }

  return request_type;
}

That part was not made by me, so maybe i should make some tweaks?

do you read all the request bytes not only the first line? browsers abort the connection if the response arrives before the complete request is sent

is FILE_NAME_LEN large enough?

Maybe the issue is the FILE_NAME_LEN indeed. I had it set to 20 but now the full path is exactly 20 characters. I think i should make the length at least 21 for the '\0' character to fit as well right?

I tried a FILE_NAME_LEN value of 30 and now everything seems to work. Probably i missed some characters that were there. Thanks for your help!

I have 1 last question. Can i somehow enable viewing the contents of a folder inside the SD card on a browser? In this case the contents of the "LOGFILES" folder. I would like to be able to access any subfolders inside the "LOGFILES" folder and view all the saved log files on a browser.

fikos:
I have 1 last question. Can i somehow enable viewing the contents of a folder inside the SD card on a browser? In this case the contents of the "LOGFILES" folder. I would like to be able to access any subfolders inside the "LOGFILES" folder and view all the saved log files on a browser.

as you can see the server here does nothing. Everything must be coded. I have in my project a this kind of WebServer, but I think it is too complex for you.