Go Down

Topic: Browser unwantedly resend old GET requests (Read 995 times) previous topic - next topic

sidhabo

I'll just start with the short version ..... giving you more info after that

1) I have in my Arduino 2560 baically the Example Webserver (added one input box to send commands back to   webserver and added my own text data sent to  client ).

2) I contact my Webserver over local LAN from my PC with Firefox.

3) The setup is to send commands to Webserver and get back info from sensors on the 2560. All that via my Firefox browser in PC.


The problem I have is that my PC (well basically Firefox) send GET requests to my Arduino when I am NOT actually submitting from my browser input box. Apart from that everything is working good. I can send requests and get proper information back in my browser window.

A typical problem would be.
1)  I send some commands and get proper answers back
2)  I leave the browser window open, not using, for like 4 minutes
3)  I click a + tab in browser and open new tab

This trigger a GET request  sent from my PC to Arduino

Typically e.g.
http://192.168.1.177/?LED=z10+33&submit=Byt

Byt is my label for input box  send knob
z10 33     is my command box text

If I try open new tab before 4 min wait I don't see the problem

Why is browser sending these requests  when I'm not active on the input box ?


More details if you did not stop before this   :)

Trying to google like "GET resend open tab firefox"  or variants just  gave much hits not related.
So I've spent a lot of time trouble shooting using Wireshark on my PC.
For a while I thought I had a solution by commenting out a keep-alive parameter sent from my Webserver (see code)
But problem still exist, just maybe not seen at every attempt to provoke problem

I verified on PC all old ports was properly closed (except the open one to port for my last command from input box)  Before I provoke error by open new tab.

It  might look like a pure browser/Firefox problem. I'm just not educated enough to be sure  if it might be related to my Webserver code.

Frustrated now from not understanding this weird problem. My webserver get resent  my old commands. This at risk of starting not wanted actions on Arduino. Like activating some relay etc.

It's always the exakt same GET request being sent as long as my browser session is not restarted. After restart it might be another GET request. Some of them I sent in the new session. Didn't find any logic in what request get "choosen". It's  not the last true command I sent. It's not the first command sent in session.

Webserver code in attached file.
Here's the  client.println bits of code:

Code: [Select]


        // 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(F("HTTP/1.1 200 OK"));
          client.println(F("Content-Type: text/html"));
          /*client.println(F("Connection: close"));  // the connection will be closed after completion of the response
          client.println(F("Refresh: 5"));  // refresh the page automatically every 5 sec*/
          client.println();
          client.println(F("<!DOCTYPE HTML>"));
          delay(1000);

..........


          ///////////////////////  Web output  ////////////////////////////////

          // output the value temp and humidity
          client.println(F("Humidity: &nbsp&nbsp&nbsp&nbsp"));
          client.println(h);
          client.println(" %\t");
          client.println(F("<br />"));
          client.println(F("Temperature: "));
          client.println(t);
          client.println(F(" *C "));
          client.println(F("<br />"));
          client.println(F("Temp satt: &nbsp&nbsp&nbsp&nbsp"));
          client.println(targettemp);
          client.println(F(" *C "));
          client.println(F("<br />"));
          if (pstat == 1) {
            client.println(F("Temp is on"));
          }


...................................




          client.println(F("<FORM ACTION=\"http://192.168.1.177\" method=get >"));
          client.println(F("Kommando   <INPUT TYPE=TEXT NAME=\"LED\" VALUE=\"\" SIZE=\"25\" MAXLENGTH=\"50\"><BR>"));
          client.println(F("<INPUT TYPE=SUBMIT NAME=\"submit\" VALUE=\"Byt\">"));
          client.println(F("</FORM>"));
          client.println(F("<BR>"));
          client.println(F("</html>"));


.............................

I've been  Using Arduino UNO and Mega2560 so far ....

sidhabo

Is it the keep-alive thingie in GET from PC that triggers when Webserver time out on client connection ?
Since I notice a new client on Webserver is started same like around when I get these "false"   GET request
I've been  Using Arduino UNO and Mega2560 so far ....

PieterP

#2
Dec 06, 2017, 08:20 am Last Edit: Dec 06, 2017, 09:02 am by PieterP
This is exactly what HTTP POST is for. According to the specification, GET should be idempotent and should not have any side-effects. Your code is not compliant to the standard, that's why it doesn't work.
Quote from: RFC2616 §9.1
9.1.1 Safe Methods

Implementors should be aware that the software represents the user in their interactions over the Internet, and should be careful to allow the user to be aware of any actions they might take which may have an unexpected significance to themselves or others.
In particular, the convention has been established that the GET and HEAD methods SHOULD NOT have the significance of taking an action other than retrieval. These methods ought to be considered "safe". This allows user agents to represent other methods, such as POST, PUT and DELETE, in a special way, so that the user is made aware of the fact that a possibly unsafe action is being requested.
Naturally, it is not possible to ensure that the server does not generate side-effects as a result of performing a GET request; in fact, some dynamic resources consider that a feature. The important distinction here is that the user did not request the side-effects, so therefore cannot be held accountable for them.

9.1.2 Idempotent Methods

Methods can also have the property of "idempotence" in that (aside from error or expiration issues) the side-effects of N > 0 identical requests is the same as for a single request. The methods GET, HEAD, PUT and DELETE share this property. Also, the methods OPTIONS and TRACE SHOULD NOT have side effects, and so are inherently idempotent.
However, it is possible that a sequence of several requests is non- idempotent, even if all of the methods executed in that sequence are idempotent. (A sequence is idempotent if a single execution of the entire sequence always yields a result that is not changed by a reexecution of all, or part, of that sequence.) For example, a sequence is non-idempotent if its result depends on a value that is later modified in the same sequence.
A sequence that never has side effects is idempotent, by definition (provided that no concurrent operations are being executed on the same set of resources).
GET requests should only be used for retrieving data.
Quote from: RFC2616 §9.3
The GET method means retrieve whatever information (in the form of an entity) is identified by the Request-URI. If the Request-URI refers to a data-producing process, it is the produced data which shall be returned as the entity in the response and not the source text of the process, unless that text happens to be the output of the process.
Pieter

sidhabo

Thanks Pieter. That was real interesting. So I could fix my problem by changing to POST method.
Let you know when I have found how to do that.
Still real confused why this false GET's occur. Is that following protocol  or some misbehavior of Firefox ?
I've been  Using Arduino UNO and Mega2560 so far ....

noiasca

I only can tell you that I have several arduino/esp webservers running, also missusing GET requests - and Firefox doesn't request multiple sites any more.

Some time ago I had an issue with the .css file which was requested two times from Firefox (only). As far as I remember there was an error in my http Header, but since now - no Problem with the IP traffic. Unfortunatly I don't remember the exact reason - but it should motivate you - that it can be solved.

PieterP

There could be a bug in Firefox, but that's not very likely.
Some browsers will reload a page that has been inactive for a long time, especially when there is low memory available (it deletes the page from memory, and just reloads it when you need it again). There could be a problem with your headers that may cause the browser to think that the page is expired, and therefore reloads it. It is allowed to do so, because it was a GET request, so it should be safe.
Or there could be a problem in your HTML or JS code that causes the browser to reload the page.
Are you sure that it is the web browser reloading, and not just a problem in the Arduino code that sees requests when there aren't any?

Pieter

sidhabo

Yes I know it's a resend from the browser since I monitor packets from / to Arduino with Wireshark.
Still struggle to get POST working   ... have a hard time to catch the POST data with my very crude code. By design now it stops reading from net just before the POST data   he he
I've been  Using Arduino UNO and Mega2560 so far ....

noiasca

that's because you stop after the empty line. Just read the first line after empty line in a buffer and try to find your posted variables ... but imho you can apply the same measures like you did with the URI ...


sidhabo

Thanks all for support  :)
I finally got it working with POST method.
Had a hard time finding the correct place in code to pick up the data from POST

It's at row 345 in code ......  for anyone that won't go crazy from my ugly ugly code   
Big WARNINGS     he he

I'll refrain from marking this as solved ......   feel kinda unfriendly to someone already frustrated by troubleshooting trying to learn from my coding

Anyway I'm happy
Thanks again all

I've been  Using Arduino UNO and Mega2560 so far ....

noiasca

fine if it is working. Nevertheless I would like to give you some feedback from outside:

Your variable post isn't doing so much currently, is it?
Is there a really need that rb is global?
There are two   Serial.begin(9600); in setup
You are using the F Macro not consequently.

instead of 5 packets (caused by each println)
Code: [Select]

          client.println(F("HTTP/1.1 200 OK"));
          client.println(F("Content-Type: text/html"));
          //client.println(F("Connection: close"));  // the connection will be closed after completion of the response
          //client.println(F("Refresh: 5"));  // refresh the page automatically every 5 sec
          client.println();
          client.println(F("<!DOCTYPE HTML>"));


you should send one packet

Code: [Select]

          client.println(F("HTTP/1.1 200 OK\n"
                           "Content-Type: text/html\n"
                           "Connection: close\n"         // the connection will be closed after completion of the response
                           "Refresh: 5\n\n"              // refresh the page automatically every 5 sec
                           "<!DOCTYPE HTML>"));





sidhabo

Thanks for feedback Noiaska. I'm impressed you spend time on my code  :)
The refresh I skipped during troubleshooting this special problem
I'm in no lack of memory so the F() cleanup I need to be very bored some day to address.
Actually I started out with a Uno and had reason to save memory. Now I changed to 2560 to be able to include SD operation.

Thanks
Ha det gött
Bosse
I've been  Using Arduino UNO and Mega2560 so far ....

Go Up