Slavic
Slavic

Reputation: 1962

Reasons why Chrome would make a request twice

I have the following in my nginx server logs (IPs and some paths changed for the sake of the example):

101.101.101.101 - - [15/Apr/2020:14:46:03 +0000] "GET /item/download-file/ready/5e971e290107e HTTP/2.0" 200 142940 "https://example.com/referer" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"

101.101.101.101 - - [15/Apr/2020:14:46:04 +0000] "GET /item/download-file/ready/5e971e290107e HTTP/1.1" 200 5 "https://example.com/referer" "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/80.0.3987.163 Safari/537.36"

The trouble is the accessed link is for a non-idempotent resource (it can only be accessed once), thus the client experiences an error.

The links are for a file download, which is accessed by a JavaScript piece involving window.location.href = "...". The response server headers include Content-Disposition: attachment.

Under what circumstances would Chrome send two requests involving HTTP/2.0 first, then HTTP/1.1 a few moments after? Perhaps there is an extension that could cause this?

Note that I can not reproduce it in any browser I own.

Update 2:

I have determined it does not just happen in Chrome. Edge 44 came up in logs too. Also, the second request for other instances of this issue did not switch to HTTP/1.1. Instead they are HTTP/2.0.

Update:

I was asked to provide the response headers for a typical request:

cache-control: no-store, no-cache, must-revalidate
content-disposition: attachment; filename=sources.zip
content-length: 8597357
content-transfer-encoding: Binary
content-type: application/octet-stream
date: Wed, 15 Apr 2020 17:23:44 GMT
expires: Thu, 19 Nov 1981 08:52:00 GMT
pragma: no-cache
server: nginx/1.16.1
status: 200

Upvotes: 7

Views: 2221

Answers (1)

Caltor
Caltor

Reputation: 2756

I don't know why you are getting multiple requests (perhaps it is just HTTP 2/1.1 negotiation) but the real answer is that you should make the GET request safe and idempotent and ask the client to send a separate DELETE request. I know this probably isn't the answer you want though.

If you have an unsafe/non-idempotent GET request then you are open to problems if the client makes multiple requests (which it should be free to do) or something like an indexing "spider" or pre-fetch cache ever hits your site and decides to visit every GET endpoint it can find. See https://www.rfc-editor.org/rfc/rfc7231#section-8.1.3 for details of which HTTP methods should and shouldn't be safe and idempotent.

Upvotes: 0

Related Questions