client.Print(F not displaying web page

I am trying to make use of client.print(F to reduced my memory usage but can't seem to get my web page to load. It just displays a blank white page.

I also want to display variables on my web page, but unsure if what I did would work, as my web page isn't displaying at all.

I made use of the web server tutorial and some code that I modified to use Basic Authentication.
This program and web page did display when I used client.println.

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

int tempPin = A1;
int TEMP;
int led = 4;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 10, 0, 0, 100 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 10, 0 , 0 , 2 };                  // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port
String readString;

void setup() {

  Serial.begin(9600);
  pinMode(TEMP, INPUT);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void SendOKpage(EthernetClient &client)
{

  client.print(F(

                 "HTTP/1.1 200 OK"
                 "Content-Type: text/html"
                 "<HTML>"
                 "<HEAD>"
                 "<TITLE>Home Server</TITLE>"
                 "</HEAD>"
                 "<BODY>"
                 "<H1>Home Server</H1>"
                 "<hr />"
                 "
"
                 "<H2>System Control</H2>"
                 "
"
                 "<a href=\"/?button1on\"\">Rotate Right</a>"
                 "<a href=\"/?button2on\"\">Rotate Left</a>"
                 "
"
               ));

  client.println ("Current temperature is: ");
  client.print (TEMP);
  client.println("
");

  client.print(F(

                 "
"
                 "</BODY>"
                 "</HTML>"
               ));

}


void SendAuthentificationpage(EthernetClient &client)
{


  client.print(F(
                 "HTTP/1.1 401 Authorization Required"
                 "WWW-Authenticate: Basic realm=\"Secure Area\""
                 "Content-Type: text/html"
                 "Connnection: close"
                 "<!DOCTYPE HTML>"
                 "<HTML>  <HEAD>   <TITLE>Error</TITLE>"
                 " </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>"

               ));
}

char linebuf[80];
int charcount = 0;
boolean authentificated = false;

int readTemp() {  // get the temperature and convert it to celsius
  TEMP = analogRead(tempPin);
  return TEMP * 0.48828125;
}


void loop() {

  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    memset(linebuf, 0, sizeof(linebuf));
    charcount = 0;
    authentificated = false;
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          Serial.print(c);
        }

        linebuf[charcount] = c;
        if (charcount < sizeof(linebuf) - 1) charcount++;
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply

        if (c == '\n' && currentLineIsBlank) {
          if (authentificated)
            SendOKpage(client);
          else
            SendAuthentificationpage(client);
          break;
        }

        if (c == '\n') {       // you're starting a new line
          currentLineIsBlank = true;

          if (strstr(linebuf, "Authorization: Basic") > 0 && strstr(linebuf, "c2F0YXJ1bjpwYXNzd29yZA==") > 0)
            authentificated = true;
          memset(linebuf, 0, sizeof(linebuf));
          charcount = 0;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    //stopping client
    client.stop();

    TEMP = readTemp();

    if (readString.indexOf("?button1on") > 0) {
      digitalWrite(led, HIGH);
    }
    if (readString.indexOf("?button1off") > 0) {
      digitalWrite(led, LOW);

      //clearing string for next read
      readString = "";
    }
  }
}

You are sending

HTTP/1.1 200 OKContent-Type: text/html<HTML><HEAD><TITLE>Home Server</TITLE></HEAD><BODY>...

What's missing?

Honestly, I'm not too sure, HTML is far from my strength sadly. Is it perhaps the \r\n at the end of each line

HTML is not that picky about line endings (most of the time), but HTTP is:

    "HTTP/1.1 200 OK\r\n"
    "Content-Type: text/html\r\n"
    "\r\n"
    "<HTML>..."

Note the empty line after the header lines before the HTML payload.

Ah was just reading up on that now.. although it didn't fix it.

My code is now:

void SendOKpage(EthernetClient &client)
{

  client.print(F(

                 "HTTP/1.1 200 OK\r\n"
                 "Content-Type: text/html\r\n"
                 "\r\n"
                 "<HTML>"
                 "<HEAD>..."

The page still loads straight to a blank white page, no authentication prompt, no web page..

Share the full code. Does the basic ethernet Webserver example work for you? if so the issue is in your code.

So this worked when I used client.println(); to display my web page. On initial load, It asks me for my authentication username and password. Correctly entering the password would display the web page. Cancelling the Authentication loaded the 401 unauthorized page.

The only thing I changed was attempting to use client.print(f(); in the
void SendOKpage(EthernetClient &client) and
void SendAuthentificationpage(EthernetClient &client) functions

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

int tempPin = A1;
int TEMP;
int led = 4;

byte mac[] = { 0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };   //physical mac address
byte ip[] = { 10, 0, 0, 100 };                      // ip in lan (that's what you need to use in your browser. ("192.168.1.178")
byte gateway[] = { 10, 0 , 0 , 2 };                  // internet access via router
byte subnet[] = { 255, 255, 255, 0 };                  //subnet mask
EthernetServer server(80);                             //server port
String readString;

void setup() {

  Serial.begin(9600);
  pinMode(TEMP, INPUT);

  // start the Ethernet connection and the server:
  Ethernet.begin(mac, ip, gateway, subnet);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}

void SendOKpage(EthernetClient &client)
{

  client.print(F(

                 "HTTP/1.1 200 OK\r\n"
                 "Content-Type: text/html\r\n"
                 "\r\n"
                 "<HTML>"
                 "<HEAD>"
                 "<TITLE>Home Server</TITLE>"
                 "</HEAD>"
                 "<BODY>"
                 "<H1>Home Server</H1>"
                 "<hr />"
                 "
"
                 "<H2>System Control</H2>"
                 "
"
                 "<a href=\"/?button1on\"\">LED ON</a>"
                 "<a href=\"/?button2on\"\">LED OFF</a>"
                 "
"
               ));

  client.println ("Current temperature is: ");
  client.print (TEMP);
  client.println("
");

  client.print(F(

                 "
"
                 "</BODY>"
                 "</HTML>"
               ));

}


void SendAuthentificationpage(EthernetClient &client)
{


  client.print(F(
                 "HTTP/1.1 401 Authorization Required"
                 "WWW-Authenticate: Basic realm=\"Secure Area\""
                 "Content-Type: text/html"
                 "Connnection: close"
                 "<!DOCTYPE HTML>"
                 "<HTML>  <HEAD>   <TITLE>Error</TITLE>"
                 " </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>"

               ));
}

char linebuf[80];
int charcount = 0;
boolean authentificated = false;

int readTemp() {  // get the temperature and convert it to celsius
  TEMP = analogRead(tempPin);
  return TEMP * 0.48828125;
}


void loop() {

  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    memset(linebuf, 0, sizeof(linebuf));
    charcount = 0;
    authentificated = false;
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;

    while (client.connected()) {
      if (client.available()) {
        char c = client.read();

        if (readString.length() < 100) {
          //store characters to string
          readString += c;
          Serial.print(c);
        }

        linebuf[charcount] = c;
        if (charcount < sizeof(linebuf) - 1) charcount++;
        Serial.write(c);
        // if you've gotten to the end of the line (received a newline
        // character) and the line is blank, the http request has ended,
        // so you can send a reply

        if (c == '\n' && currentLineIsBlank) {
          if (authentificated)
            SendOKpage(client);
          else
            SendAuthentificationpage(client);
          break;
        }

        if (c == '\n') {       // you're starting a new line
          currentLineIsBlank = true;

          if (strstr(linebuf, "Authorization: Basic") > 0 && strstr(linebuf, "c2F0YXJ1bjpwYXNzd29yZA==") > 0)
            authentificated = true;
          memset(linebuf, 0, sizeof(linebuf));
          charcount = 0;
        }
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    delay(1);
    //stopping client
    client.stop();

    TEMP = readTemp();

    if (readString.indexOf("?button1on") > 0) {
      digitalWrite(led, HIGH);
    }
    if (readString.indexOf("?button1off") > 0) {
      digitalWrite(led, LOW);

      //clearing string for next read
      readString = "";
    }
  }
}

So this code using print(f(); does not load anything, just a blank page

Ok now I feel silly. I just fixed it using the tip by @oqibidipo earlier.

All I had to do was add \r\n before the HTML payload in the authentication function

void SendAuthentificationpage(EthernetClient &client)
{


  client.print(F(
                 "HTTP/1.1 401 Authorization Required\r\n"
                 "WWW-Authenticate: Basic realm=\"Secure Area\"\r\n"
                 "Content-Type: text/html\r\n"
                 "Connnection: close\r\n"
                 "\r\n"
                 "<!DOCTYPE HTML>"
                 "<HTML>  <HEAD>   <TITLE>Error</TITLE>"
                 " </HEAD> <BODY><H1>401 Unauthorized.</H1></BODY> </HTML>"

               ));
}

Going back to my second question if someone can assist, how would I display a variable using client.print(f(); . You can see in the above post I tried to display temperature but I'm sure there's a better way.

You can display a variable with F() macro. Variables live in SRAM, the F() macro and PROGMEM stuff is for accessing flash memory. So your approach above is the right one, jus print the variable