SD card webserver - not sending files

I'm experiencing a strange problem with the Arduino UNO & the ethernet shield. Once my sketch reaches a certain size, about 24k, the SD card stops working (i.e. SD.open() doesn't do anything it seems). If I comment out a bunch of the program and reduce the sketch size, it starts working again.

In the sketch, if I comment out the "else if..." portions of the code to see what file the browser is requesting, it starts working again. When I put them back in, it stops working.

Has anyone else experienced this problem? How do I fix it?

#include <Ethernet.h>
#include <SPI.h>
#include <SD.h>

byte mac[] = { 0x90, 0xA2, 0xDA, 0x0E, 0x08, 0xC0 }; // 90-A2-DA-0E-08-CO
IPAddress ip(192, 168, 1, 101);
EthernetServer server(80);  // create a server at port 80


String request;

void setup()
{
    Ethernet.begin(mac, ip);  // initialize Ethernet device
    server.begin();           // start to listen for clients
    Serial.begin(9600);       // for debugging
    
    // initialize SD card
    Serial.println("Initializing SD card...");
    SD.begin(4);
    Serial.println("SUCCESS - SD card initialized.");
    // check for index.htm file
    if (!SD.exists("index.htm")) {
        Serial.println("ERROR - Can't find index.htm file!");
        return;  // can't find index file
    }
    Serial.println("SUCCESS - Found index.htm file.");

}

void loop()
{
    File webFile;
    EthernetClient client = server.available();  // try to get client

    if (client) {  // got client?
        boolean currentLineIsBlank = true;
        while (client.connected()) {
            if (client.available()) {   // client data available to read
                char c = client.read(); // read 1 byte (character) from client
                Serial.print(c);
                request += c;
                // last line of client request is blank and ends with \n
                // respond to client only after last line received
                if (c == '\n' && currentLineIsBlank) {
                    // send a standard http response header
                    
                    if(request.indexOf("GET / H") > -1 || request.indexOf("GET /index.html") > -1)
                    {
                      client.println("HTTP/1.1 200 OK");
                      client.println("Content-Type: text/html");
                      client.println("Connection: keep-alive");
                      client.println();
                      Serial.println("sending index.htm");
                      // send web page
                      webFile = SD.open("index.htm");
                    }       // open web page file
                    else if(request.indexOf("GET /style.css") > -1)
                    {
                      client.println("HTTP/1.1 200 OK");
                      client.println("Content-Type: text/css");
                      client.println("Connection: keep-alive");
                      client.println();
                      // send web page
                      webFile = SD.open("style.css");
                    }
                    else if(request.indexOf("GET /gauge.js") > -1)
                    {
                      client.println("HTTP/1.1 200 OK");
                      client.println("Content-Type: script/javascript");
                      client.println("Connection: keep-alive");
                      client.println();
                      // send web page
                      webFile = SD.open("gauge.js");              
                    }
                    if (webFile) 
                      {
                        while(webFile.available()) 
                        {
                            client.write(webFile.read()); // send web page to client
                        }
                        webFile.close();
                      }
                    request = "";

                    break;
                }
                // every line of text received from the client ends with \r\n
                if (c == '\n') {
                    // last character on line of received text
                    // starting new line with next character read
                    currentLineIsBlank = true;
                } 
                else if (c != '\r') {
                    // a text character was received from client
                    currentLineIsBlank = false;
                }
            } // end if (client.available())
        } // end while (client.connected())
        delay(1);      // give the web browser time to receive the data
        client.stop(); // close the connection
    } // end if (client)
}

My SD card server code sends the files.
http://playground.arduino.cc/Code/WebServerST

It is still exposed to the internet for testing. No fancy files, but all is working. Nobody has been able to crash it yet, despite dozens of attacks. Here is a Mega2560 R2 with an R2 Ethernet shield.
http://68.99.58.119

I can confirm yours works. But I don't understand why mine doesn't. It appears there's a memory issue here (your's uses less RAM), but I only have the UNO, not the Mega so my question is, why doesn't my code work on the UNO?

You could be running out of SRAM. I tried to keep everything in program memory, but even at that, it may not have been enough to work on an Uno. I will try to check on the SRAM use in my Mega. The SRAM use is pretty even between the Uno and Mega, so if mine shows anywhere around 6000 bytes remaining, the Uno would be out of SRAM.

I presume the Uno would be out of SRAM. Mine shows only 5999 bytes remaining just before the file open call. :frowning:
Maybe I can get that down a little, but even then, there would not be much SRAM left for anything else. And I can't cut down the code too much without giving up a lot of fault tolerance.

I modified the code to reduce the SRAM use. It may run on an Uno now. I would like some user to check that.
http://playground.arduino.cc/Code/WebServerST
It displays an SRAM bytes remaining just before the file open. That value might help me.

Thanks, I'll give it a shot tonight and see how it works. Would love to get this working with some head-room on my Uno, but we'll see.

I reduced the SRAM use even more. I put the server check in its own function so the variable use would be released when the checkServer() function returns. Just don't add much to the checkServer() function as far as variables, and limit global variables to as few as you can get away with. You should have plenty of SRAM available in the myStuff() function.

Now the loop function looks like this.

void loop() {
  checkServer();
  myStuff();
}

It will still be close on the program memory also.