30

I wrote a simple server using socket API in C under linux which listens at port 80 on localhost. Now when I send a request from the browser google chrome to the program it receives 2 requests while it receives only one when I send from firefox.

The URL I typed in the browser was: http://localhost/xyz.html

OUTPUT WHEN I TYPE URL IN CHROME

root@anirudh-Aspire-5920:/home/anirudh/workspace/DCMTOL# ./DCMTOL_RUN 

Inside HTTP server Handler

Inside HTTP request Handler 

**Detected request: clientsocket_fd = 6 clientportnumber = 38027**

GET /xyz.html HTTP/1.1

Host: localhost

Connection: keep-alive

Cache-Control: max-age=0

Accept:application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5

User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US) AppleWebKit/534.10 (KHTML, like Gecko) Chrome/8.0.552.224 Safari/534.10

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


Inside HTTP request Handler

**Detected request: clientsocket_fd = 7 clientportnumber = 38029**

^C

root@anirudh-Aspire-5920:/home/anirudh/workspace/DCMTOL# 

the second request does not send any data so my code waits at the read call and so I have to terminate it '^C'.

OUTPUT WHEN I TYPE URL IN FIREFOX

root@anirudh-Aspire-5920:/home/anirudh/workspace/DCMTOL# ./DCMTOL_RUN 
Inside HTTP server Handler
Inside HTTP request Handler

**Detected request: clientsocket_fd = 6 clientportnumber = 45567**

GET /xyz.html HTTP/1.1

Host: localhost

User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.2.13) Gecko/20101206 Ubuntu/10.10 (maverick) Firefox/3.6.13

Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8

Accept-Language: en-us,en;q=0.5

Accept-Encoding: gzip,deflate

Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7

Keep-Alive: 115

Connection: keep-alive


^C

root@anirudh-Aspire-5920:/home/anirudh/workspace/DCMTOL# 

Question: How can chrome browser send 2 requests (one being empty) when I typed the URL only once. As you can see above I detected 2 requests. I tried to do netstat in the case of sending URL from chrome and I found that both of the request were sent by the browser only. and as u can see above when I send the URL from firefox only 1 request is received.

Here is the output of net stat when I send request from chrome

Active Internet connections (w/o servers)

Proto Recv-Q Send-Q Local Address           Foreign Address         State       PID/Program name

tcp        0      0 117.195.110.186:48701   74.125.77.102:80        TIME_WAIT   -

tcp        0      0 117.195.110.186:48700   74.125.77.102:80        ESTABLISHED 5699/google-chrome

tcp        0      0 117.195.110.186:55815   209.85.175.138:80       ESTABLISHED 5699/google-chrome

tcp        0      0 127.0.0.1:80            127.0.0.1:38029         ESTABLISHED -

tcp        0      0 127.0.0.1:38029         127.0.0.1:80            ESTABLISHED 5699/google-chrome

tcp        0      0 127.0.0.1:38027         127.0.0.1:80            ESTABLISHED 5699/google-chrome

tcp        0      0 127.0.0.1:80            127.0.0.1:38027         ESTABLISHED -

tcp        0      0 117.195.110.186:35402   74.125.153.125:5222     ESTABLISHED 4430/pidgin

thanks in advance :)

Durin
  • 2,070
  • 5
  • 23
  • 37
  • 2
    Have you tried running tcpflow or tcpdump to see if anything is actually sent in the request? It could be opening a connection for future requests. (as RomanK mentioned). – Kylar Jan 25 '11 at 17:52
  • 2
    After two years, I've got the same question with Chrome 24. – esengineer Feb 07 '13 at 14:45
  • 2
    Still having this exact same issue in 2019. Chrome version `71.0.3578.98` – WBuck Jan 04 '19 at 02:30

7 Answers7

51

I had a similar issue with my node server. It is due to the following bug in Chrome. In summary, Chrome is sending a request for a favicon on every request. As, is likely, you aren't sending a favicon back, it requests one after every legitimate request.

Firefox, and most other browsers, also send out a request for a favicon when they first connect, but cache the result i.e. if there isn't a favicon returned first time, they don't keep trying - which is why you're only seeing a single request from Firefox. It seems Chrome is unfortunately a little too persistent with its favicon requestiness.

Matt
  • 3,617
  • 2
  • 27
  • 39
  • 3
    For me giving a favicon does not help, I have the problem with the empty request because it blocks the read of the stream for a timeout period (10s). – Alejadro Xalabarder Sep 11 '15 at 21:33
  • 5
    I found that: **the second socket is not for favicon**, nothing will be sent in that socket, as described in davidlt's answer. – WKPlus Nov 20 '15 at 03:33
  • 2
    I'm finding exactly the same. There's no HTTP header. Attempting to read even a single character blocks, meaning the socket has no incoming data. – Jim Carnicelli Aug 17 '16 at 17:26
  • 3
    It might be worth reviewing the accepted answer here. My investigations at the time indicated it was related to the favicon, but I was either wrong, or Chrome's behavior has changed since this was first answered—both completely possible. Either that, or there's more to this than meets the eye. – Matt Aug 17 '16 at 17:30
  • 3
    I'm experiencing the same problem with Chrome (*version* 52.0.2743.116, 32-bit). So if it is favicon request, then the server should get at least the request-line `GET /favicon.ico HTTP/1.1` and optionally the headers. But it does get any. There is **no data sent over this connection**, by the client. – Nawaz Aug 19 '16 at 12:07
21

I am currently writing small async web server on Mono/.NET 4.0 and noticed the same thing. Chrome opens two TCP connection, but only one is used for communication. There is no data send using that socket. Even after you stop loading webpage from browser Chrome still keeps connection alive for quite some time.

I must agree with @RomanK, as it's probably for optimizations or it's a bug, but it's not for favicon as there is not data transfered throw that connection.

davidlt
  • 1,007
  • 2
  • 11
  • 17
  • 6
    I stumbled upon this behaviour as well recently. Apparently, Chrome opens a “speculative socket”, to be able to make the request immediately in case a new request needs to be made. Ironically, it seems to only slow Chrome down when it comes to rendering the page. – Ruud May 11 '13 at 12:28
  • I also have the problem with the empty request. My server is written in java and this request cause an accept then the next step is read the input stream of the socket, unfortunately it blocks for the timeout (10s) the only work around I found is reduce the timeout to 1s. :( – Alejadro Xalabarder Sep 11 '15 at 21:37
  • Fooled by this problem as well. I wrote a http server in python, based on the built-in wsgiref/simple_server which can handle only one request one time, when open the url with chrome, it makes my server blocked. Since there is a "no data socket", my server is blocked when reading it. – WKPlus Nov 20 '15 at 03:22
  • 1
    Agree with that: **it's not for favicon**, nothing will be sent in that socket. – WKPlus Nov 20 '15 at 03:28
  • 2
    I figured out why Chrome does this. That second socket is held open by Chrome in anticipation of a future request, like to download images and other binaries for the page. Once the browser does need something from this server, Chrome sends its request header on that already-open socket. This is sneaky because it gives Chrome priority over other browsers. It's like having your child hold your place in the checkout line while you shop. That said, it probably does speed up page rendering. – Jim Carnicelli Aug 17 '16 at 17:40
  • I agree with *"but it's **not for favicon** as there is **not data transfered** throw that connection."* – Nawaz Aug 19 '16 at 12:11
2

I had empty tcp packet sent by Chrome to my simple server before normal html GET query and /favicon after. Favicon wasn`t a problem but empty tcp was since my server was waiting either for data or for connection to be finished. It had no data and wouldn't release connection for 2 minutes. So thread was hanging for 2 minutes.

In related question I found a useful link saying it may be caused by "Predict network actions to improve page load performance" setting. I tried turning off prediction settings one by one and it worked. In chrome version 73.0.3683.86 (Official Build) (64-bit) this behavior was caused by chrome setting "Use a prediction service to load pages more quickly" turned on.

So just go to setting -> advanced -> privacy and security -> Use a prediction service to load pages more quickly and turn it OFF.

Rustam A.
  • 809
  • 8
  • 15
2

It does not send any data in the seconds socket. We have our Nginx webserver logs filled up with 400 errors because this second connection is closed before sending any data/actual_HTTP_request to the server. Opens the first connection, opens the second immediately then uses the first one and waits till the second one dies.

Here is a non-verbose dump about the second connection

No.     Time        Source                Destination           Protocol Length Info
20227 38.688849   89.ZZZ.TTT.208        80.XX.YYY.186         TCP      66     1758 > 80     [SYN] Seq=0 Win=65535 Len=0 MSS=1440 WS=2 SACK_PERM=1
20228 38.688870   80.XX.YYY.186         89.ZZZ.TTT.208        TCP      66     80 > 1758 [SYN, ACK] Seq=0 Ack=1 Win=5840 Len=0 MSS=1460 SACK_PERM=1 WS=128
20256 38.752121   89.ZZZ.TTT.208        80.XX.YYY.186         TCP      60     1758 > 80 [ACK] Seq=1 Ack=1 Win=65536 Len=0
26351 50.565758   89.ZZZ.TTT.208        80.XX.YYY.186         TCP      60     1758 > 80 [FIN, ACK] Seq=1 Ack=1 Win=65536 Len=0
26352 50.565830   80.XX.YYY.186         89.ZZZ.TTT.208        TCP      54     80 > 1758 [FIN, ACK] Seq=1 Ack=2 Win=5888 Len=0
26396 50.657612   89.ZZZ.TTT.208        80.XX.YYY.186         TCP      60     1758 > 80 [ACK] Seq=2 Ack=2 Win=65536 Len=0
Gabor Vincze
  • 121
  • 2
1

Can you post the source of your server? My guess is that Chrome simply opens a socket against your server to optimize future requests to the same page, but does not send any command on it.

RomanK
  • 1,258
  • 7
  • 18
  • 1
    That's not the case. I actually traced in wireshark and found another request for favorite icon. http://stackoverflow.com/a/12795169/986760 – fkl Oct 09 '12 at 07:59
0

It seems that if chrome can not fetch favicon (received 404 from me) it still opens the second connection for the favicon request but does not actually request it. looks like a bug (still). 'caching' gone wrong maybe aka cache ('i already received nothing the previous time') check is done after the conn is already open?

0

To me it only happen if I write/paste to chrome url field. It is never triggered from anchor tag. If you log url of request you can see it is sent two times.

My was /users. I added consloe.log() in code (node server) and you could see /users appear twice. And since i was not logged in app I would get double notification messages.

This example can reproduce it:

Script 1 name: redirect.php

<?php

session_start();

$_SESSION['x'][] = 'This will show only once';
header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0, max-age=0');
header('Location: /to.php');

Script 2 name: to.php

 <?php    

session_start();

if (isset($_SESSION['x']))
    foreach ($_SESSION['x'] as $x) {
        echo $x . '<br>';
}

unset($_SESSION['x']);

So if you copy paste "SERVERNAME/redirect.php" in url field eventualy you get doubled messages.

Mihael Mamula
  • 330
  • 3
  • 11