Simple Web Server and Chrome

I modified the "Simple Web Server" example to display a page counter.
See below.

Question: Why does the counter advance by 2 when I reload the page with Chrome,
but only by one with Internet Explorer 8.
Firefox advance by two on first load, one thereafter. I think.

Do you see a workaround to make a functional page counter that will work with all browsers ??

/*  Simple Web Server */

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

// Enter a MAC address and IP address for your controller below.
// The IP address will be dependent on your local network:
byte mac[] = { 
  0xDE, 0xAD, 0xBE, 0xEF, 0xFE, 0xED };
IPAddress ip(192,168,1,78);
EthernetServer server(8248);

int iPageCounter = 1;


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 and the server:
  Ethernet.begin(mac, ip);
  server.begin();
  Serial.print("server is at ");
  Serial.println(Ethernet.localIP());
}


void loop() {
  // listen for incoming clients
  EthernetClient client = server.available();
  if (client) {
    Serial.println("new client");
    // an http request ends with a blank line
    boolean currentLineIsBlank = true;
    while (client.connected()) {
      if (client.available()) {
        char c = client.read();
        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) {
          // send a standard http response header
          client.println("HTTP/1.1 200 OK");
          client.println("Content-Type: text/html");
          client.println("Connnection: close");
          client.println();
          client.println("<!DOCTYPE HTML>");
          client.println("<html>");
          client.print("<h1>Page Count: ");
          client.println(iPageCounter++);   // THIS IS THE PAGE COUNTER LINE
          client.print("</h2>");    
          client.println("</html>");
          break;
        }
        if (c == '\n') {
          // you're starting a new line
          currentLineIsBlank = true;
        } 
        else if (c != '\r') {
          // you've gotten a character on the current line
          currentLineIsBlank = false;
        }
      }
    }
    // give the web browser time to receive the data
    delay(1);
    // close the connection:
    client.stop();
    Serial.println("client disconnected");
  }
}

It is the web browser request for favicon.ico that adds to the count. Chrome requests it every reload. Firefox and IE don't.

Check for the request for "GET /favicon.ico HTTP/1.1" and ignore that count.

I was gonna point that out :wink:

GET /favicon.ico HTTP/1.1

Host: 192.168.1.5
Connection: keep-alive
Accept: */*
User-Agent: Mozilla/5.0 (Windows NT 6.0; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31
Accept-Encoding: gzip,deflate,sdch
Accept-Language: en-US,en;q=0.8
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.3

If you only increment when the requested resource is / then you won't count the favicon request.

A quick way to divert the problem will be to point the browser to elsewhere for the favicon.com like putting this in the header:

<link rel="shortcut icon" type="image/x-icon" href="http://arduino.cc/en/favicon.png" />

From careful observation of IE, firefox, and chrome, I conclude that chrome tends to hog the client connection for longer period of time than necessary. When using IE or firefox, client disconnects immediate upon receiving the entire file from Arduino, on the other hand with chrome, it holds on to the connection for at least a few extra seconds, what a hog!

BTW, I send everything with Content-length: so there is really no need to hog a connection. I might want to kick chrome ass with my code revision. If agent is chrome, close connection immediately after transferring the last byte.

If agent is chrome, close connection immediately after transferring the last byte.

Let me reword that for you:
If agent is anything, close connection immediately after transferring the last byte.

SurferTim:

If agent is chrome, close connection immediately after transferring the last byte.

Let me reword that for you:
If agent is anything, close connection immediately after transferring the last byte.

Yes yes, next time I won't use the sample code Arduino provides, which doesn't voluntarily terminate connection.

I should have seen that.
It was the "GET /favicon.ico HTTP/1.1" that I was missing.
Thanks.
I'll be good to go now !

BobW

SurferTim:
It is the web browser request for favicon.ico that adds to the count. Chrome requests it every reload. Firefox and IE don't.

Check for the request for "GET /favicon.ico HTTP/1.1" and ignore that count.

You guys have been very helpful to me with your replies.

What I did to handle the GET /favicon.ico was just to check for the character 'f' after the first '/', and when I found it, just DEcrement my page counter by one, so when it got incremented later, it ended up unchanged. Just a few extra lines of code.

Page counter works well now with all five major browsers (IE, FF, Chrome, Safari, Opera).

Thanks again !

BobW

BobW:
I should have seen that.
It was the "GET /favicon.ico HTTP/1.1" that I was missing.
Thanks.
I'll be good to go now !

BobW

SurferTim:
It is the web browser request for favicon.ico that adds to the count. Chrome requests it every reload. Firefox and IE don't.

Check for the request for "GET /favicon.ico HTTP/1.1" and ignore that count.

Alright! What I am doing is making an HTTP file server so it will look in the SD card and only serve files to client that exists on the SD card. I know this doesn't suit you (if you embed numbers read with Arduino on the web page) but you could try an approach that looks at the requested URI and only counts if the requested is available.