copy html file from server to sd card

hi all
I am trying to copy a html file from a remote server to the sd card but when i do it adds

HTTP/1.1 200 OK
Date: Sun, 30 Nov 2014 08:48:37 GMT
Server: LiteSpeed
Accept-Ranges: bytes
Connection: close
Last-Modified: Sun, 30 Nov 2014 08:12:34 GMT
Content-Type: text/html
Content-Length: 1077

I have tried adding

while(client.findUntil("<html>", "</html>")){

but that just comes back empty at the moment I am only printing to serial but should be okay once a I can remove all that other stuff.

cheers in advanced

You could show us the whole sketch, or make a small test sketch.

I guess you use a GET to retrieve that page.
After that you receive the server information, and after that you will get a double new line \r\n\r\n (But my IP camera returns only \n\n ).
After that you read the number of bytes that are specified by the server with the "Content-Lenght". That results into the exact amout of data for the html file, but also for a jpg file or any other file.

This is the whole sketch. Im just looking for a way to copy a html file to the sd card from a server if you can suggest a better way Im keen to learn. Thank you for your prompt reply.

/*
  Web client
 
 This sketch connects to a website (http://www.google.com)
 using an Arduino Wiznet Ethernet shield. 
 
 Circuit:
 * Ethernet shield attached to pins 10, 11, 12, 13
 
 created 18 Dec 2009
 by David A. Mellis
 modified 9 Apr 2012
 by Tom Igoe, based on work by Adrian McEwen
 
 */

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

// Enter a MAC address for your controller below.
// Newer Ethernet shields have a MAC address printed on a sticker on the shield
byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
// if you don't want to use DNS (and reduce your sketch size)
// use the numeric IP instead of the name for the server:
//IPAddress server(74,125,232,128);  // numeric IP for Google (no DNS)
char server[] = "www.kinglait.com.au";    // name address for Google (using DNS)

// Set the static IP address to use if the DHCP fails to assign
IPAddress ip(10,1,1,186);

// Initialize the Ethernet client library
// with the IP address and port of the server 
// that you want to connect to (port 80 is default for HTTP):
EthernetClient client;

void setup() {
 // Open serial communications and wait for port to open:
  Serial.begin(9600);
   while (!Serial) {
    ; // wait for serial port to connect. Needed for Leonardo only
  }

  // start the Ethernet connection:
  if (Ethernet.begin(mac) == 0) {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    // try to congifure using IP address instead of DHCP:
    Ethernet.begin(mac, ip);
  }
  // give the Ethernet shield a second to initialize:
  delay(1000);
  Serial.println("connecting...");

  // if you get a connection, report back via serial:
  if (client.connect(server, 80)) {
    Serial.println("connected");
    // Make a HTTP request:
    client.println("GET /test/indexajaxtest.html HTTP/1.1");
    client.println("Host: www.kinglait.com.au");
    client.println("Connection: close");
    client.println();
  } 
  else {
    // kf you didn't get a connection to the server:
    Serial.println("connection failed");
  }
}

void loop()
{
  // if there are incoming bytes available 
  // from the server, read them and print them:
  if (client.available()) {    
    while(client.findUntil("<html>", "</html>")){
       char c = client.read();
       Serial.print(c);
    }    
  }

  // if the server's disconnected, stop the client:
  if (!client.connected()) {
    Serial.println();
    Serial.println("disconnecting.");
    client.stop();

    // do nothing forevermore:
    while(true);
  }
}

EthernetClient derives from Client which derives from Stream, which implements the findUntil method, with this signature:

  bool findUntil(char *target, char *terminator);   // as find but search ends if the terminator string is found

The code will look for the string defined as target. It will stop if the terminator string is found before the target string.

So, your code will return true or false only. It will return true if is found before (which it will be in a well formed html file). What good is that information?

You are not then storing anything to the SD card. Why not? Writing to the card seems more useful than writing to the serial port. Or at least as useful.

I do want it to write to the SD card but the serial seems a quick and easy way to test whats going on. I had found another script that had this and was working I am only very new to this and really struggling. The working script I found was this one

/*
 * WebServerParsing
 * Respond to requests in the URL to change digital and analog output ports
 * show the number of ports changed and the value of the analog input pins.
 * for example:
 *   sending http://192.168.1.177/?pinD2=1 turns digital pin 2 on
 *   sending http://192.168.1.177/?pinD2=0 turns pin 2 off. 
 * This sketch demonstrates text parsing using the 1.0 Stream class.
 */

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

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
byte ip[] = { 10,1,1,186 };

EthernetServer server(80);

void setup()
{
  Serial.begin(9600);
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.println("ready");
}

void loop()
{
  EthernetClient client = server.available();
  if (client) {
    while (client.connected()) {
      if (client.available()) {
        // counters to show the number of pin change requests
        int digitalRequests = 0;  
        int analogRequests = 0;
        if( client.find("GET /") ) {  // search for 'GET'
          // find tokens starting with "pin" and stop on the first blank line
          // search to the end of line for 'pin'
          while(client.findUntil("pin", "\n\r")){  
            char type = client.read(); // D or A
            // the next ascii integer value in the stream is the pin
            int pin = client.parseInt(); 
            int val = client.parseInt(); // the integer after that is the value
            if( type == 'D') {
              Serial.print("Digital pin ");
              pinMode(pin, OUTPUT);
              digitalWrite(pin, val);
              digitalRequests++;
            }
            else if( type == 'A'){
              Serial.print("Analog pin ");
              analogWrite(pin, val);
              analogRequests++;
            }
            else {
              Serial.print("Unexpected type ");
              Serial.print(type);
            }
            Serial.print(pin);
            Serial.print("=");
            Serial.println(val);
          }
        }
        Serial.println();

        // the findUntil has detected the blank line (a lf followed by cr)
        // so the http request has ended and we can send a reply
        // send a standard http response header
        client.println("HTTP/1.1 200 OK");
        client.println("Content-Type: text/html");
        client.println();

        // output the number of pins handled by the request
        client.print(digitalRequests);
        client.print(" digital pin(s) written");
        client.println("
");
        client.print(analogRequests);
        client.print(" analog pin(s) written");
        client.println("
");
        client.println("
");


        // output the value of each analog input pin
        for (int i = 0; i < 6; i++) {
          client.print("analog input ");
          client.print(i);
          client.print(" is ");
          client.print(analogRead(i));
          client.println("
");
        }
        break;
      }
    }
    // give the web browser time to receive the data
    delay(1);
    client.stop();
  }
}

That working example is a webserver, and you want to be a client to retrieve a file from a server, right ?

The setup function is to initialize things, and the loop() is for the normal working code.
Do you want to retrieve that file just once, then I would place that code in setup().
Do you want to retrieve that file every hour or every day, then I would place that code in loop().

I have a working sketch to retrieve a file, but it is in development, and has my passwords and everything.
I started with this: Read a text file from internet site - Project Guidance - Arduino Forum
My sketch below is a stripped-down version. Perhaps you can compare it step by step with your sketch. When your sketch will compile, show your new sketch to us.

//
// Getting a file from internet
// (Everything with passwords and other things are removed)
//
// Arduino IDE 1.5.8 BETA, Arduino Mega 2560 board + Ethernet Shield.
//

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

// Generated mac with : http://www.miniwebtool.com/mac-address-lookup/
byte mac[] = { 0xDE, 0x36, 0x5F, 0x0A, 0x19, 0x83 };      //physical mac address

EthernetClient client;

void setup()
{
  Serial.begin( 9600); 
  Serial.println(F( "\nGET'n a file from internet sketch"));
  
  // SPI
  // ---
  // Set SS (pin 53 on the Mega) as output.
  // Disable the SPI chip selects, by setting them high.
  // On the Arduino Mega, the SS pin is pin 53.
  // This must be an output for the SPI to work, although pin 53
  // is not used.
  pinMode( SS, OUTPUT);       // SS = 10 on Uno, SS = 53 on the Mega
  digitalWrite( SS, HIGH);    // disable anything at the default SS
 
  pinMode( 4, OUTPUT);
  digitalWrite( 4, HIGH);     // disable SD

  pinMode( 10, OUTPUT);
  digitalWrite(10, HIGH);     // disable W5100
  
  delay(1);

  if( Ethernet.begin(mac) == 0) 
  {
    Serial.println("Failed to configure Ethernet using DHCP");
    // no point in carrying on, so do nothing forevermore:
    while(true);
  }
  
  // print your local IP address.
  Serial.println(F( "Ethernet started."));
  Serial.print(F( "Local IP = "));
  Serial.println( Ethernet.localIP());
  
  // See if the card is present and can be initialized:
  if (!SD.begin( 4)) 
  {
    Serial.println("SD card failed, or not present");
    // don't do anything more:
    while(true);
  }
  Serial.println("SD card initialized.");
}

void loop() 
{
  // check for serial input
  if (Serial.available() > 0) //if something in serial buffer
  {
    byte inChar; // sets inChar as a byte
    inChar = Serial.read(); //gets byte from buffer
    if(inChar == 'i') // checks to see byte is an i
    {
      GetAndStore();
    }
  }  
} 

void GetAndStore() //client function for GET request data.
{
  if( !client.connect(<server_ip>,80)) 
  {
    Serial.println("connection failed"); //error message if no client connect
  }
  else
  {  
     //starts client connection
    Serial.println("connected");
    
    // It depends on the server how little or how much information is needed for the GET.
    client.println("GET /index.html HTTP/1.1");
    client.println("Connection: close");
    client.println();

    // The reponse is 5..12 lines, each with CR LF (0x0D, 0x0A) at the end.
    // An empty line indicates the start of the data.
   
    client.find("Content-Length: ");
    long len = client.parseInt();
    Serial.print("Content-Length=");
    Serial.println( len);
    
    // For normal servers, "\r\n\r\n" is the string to search for.
    client.find("\r\n\r\n");

    // The requested data has been read until the empty line.
    // The data that follows is the file that was requested.

    // Do a few tests before creating a file.
    if( client.connected() && client.available() > 0 && len > 0)
    {
      // Open a file (the name in 8.3 format)
      char fileName[16] = "myfile.htm"
      
      File dataFile = SD.open(fileName, FILE_WRITE);
  
      Serial.print("Writing file ");
      Serial.println( fileName);

      long fileSize = 0L;
      // if the file is available, write to it:
      if (dataFile) 
      {
        // Wait up to a total of 10 seconds to get the file.
        unsigned long previous = millis();
  
        // "len" is the "Content-Length".
        // Reading is done in chunks that are available.
        // fileSize keeps track of the read bytes.
        while( millis() - previous < 10000UL && client.connected() && fileSize < len)
        {
          int n = client.available();
          
          for( int i=0; i<n; i++)
          {
            byte c = client.read(); // get byte from ethernet buffer
            dataFile.write( c);     // write raw data
          }
          fileSize += n;
        }
        dataFile.close();
    
        Serial.print("Ready writing ");
        Serial.print( fileSize);
        Serial.println( " bytes");
      }  
      else 
      {
        // if the file isn't open, pop up an error:
        Serial.println(F("error opening file"));
      }
    }
    else
    {
      Serial.println(F( "Client was not connected or not available or len was zero."));
    }
  }
  client.stop(); //stop client
}

cheers will try it tonight.