Chrome making multiple Get calls - google-chrome

i am facing issue where in Chrome is making multiple Rest Get calls ( not immediately but after some delay), even when i requested only once. this is not happening in other browsers, seems to be specific to Chrome.
The Rest Get call i am working will returns audio or video file and it plays in browser. when audio and video is playing, chrome is making other call and the server is throwing broken pipe exception. below is info as i see from Chrome developer Tools
General Data
Request URL:http://localhost:6390/x/y/MP3
Request Method:GET
Status Code:200
Remote Address:[::1]:6390
Referrer Policy:no-referrer-when-downgrade
Request Headers
Accept:*/*
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:en-US,en;q=0.8,te;q=0.6
Connection:keep-alive
Host:localhost:6390
Range:bytes=0-
Response Headers
Cache-Control:max-age=31536000, public
Content-Length:27133142
Content-Type:audio/mpeg
Date:Mon, 22 May 2017 01:00:31 GMT
Expires:Mon, 21 May 2018 21:00:31 GMT
if we look at the content-length of the response on first call, it is almost 25 mb file, but only downloading around 5.3mb file, and when audio/video is playing for downloaded file, Chrome is making additional call even when the response code is 200 first call.
Here is info from 2nd Call even when i have not requested. it is called by Chrome automatically
General Info
Request URL:http://localhost:6390/x/y/MP3
Request Method:GET
Status Code:200
Remote Address:[::1]:6390
Referrer Policy:no-referrer-when-downgrade
Request Headers
Accept:*/*
Accept-Encoding:identity;q=1, *;q=0
Accept-Language:en-US,en;q=0.8,te;q=0.6
Connection:keep-alive
Host:localhost:6390
Range:bytes=5421245-
Response Headers
Cache-Control:max-age=31536000, public
Content-Length:27133142
Content-Type:audio/mpeg
Date:Mon, 22 May 2017 01:20:07 GMT
Expires:Mon, 21 May 2018 21:20:07 GMT
2nd request have bytes header with range. why is chrome making second call with range header even when first request i am sending complete content and response code of 200. i am under impression that unless i use Bytes Header with 206, browser should not make additional call.
i have checked many threads on why chrome is making additional calls, but they dont seem to fall into issue i am facing.
please help me on why i am facing this issue on chrome, any pointers would be helpful.
my Stack is Spring Boot, Spring Rest and Tomcat server

Related

Chrome does not invalidate cache when PUT request contains If-Match header

I'm creating a HTTP Web API where some of my resources will be cacheable. A cacheable resource will have two operations, GET & PUT. The GET will return response headers of Cache-Control: public,max-age=3600 & Etag: "2kuSN7rMzfGcB2DKt67EqDWQELA". The PUT will require the If-Match header which will contain the Etag value from a GET of the same resource. My goal is to have the browser cache invalidate a resource when I PUT to that resource. This works fine until I add the If-Match header to the PUT request. When the PUT request contains the If-Match header, subsequent GET requests will fetch from the cache which would be stale data. This is the behavior I've been experiencing with Chrome. Firefox doesn't behave like this, and works as I assume it should. Is this a bug in Chrome or am I misunderstanding some part of the HTTP spec?
Here are some example requests to show behavior:
//correctly fetchs from origin server (returns 200)
GET http://localhost/api/my-number/1
Response Headers
cache-control: public,max-age=3600
etag: "2kuSN7rMzfGcB2DKt67EqDWQELA"
Response Body
7
//correctly fetchs from disk cache (returns 200)
GET http://localhost/api/my-number/1
Response Headers
cache-control: public,max-age=3600
etag: "2kuSN7rMzfGcB2DKt67EqDWQELA"
Response Body
7
//correctly updates origin server (returns 200)
PUT http://localhost/api/my-number/1
Request Headers
if-match: "2kuSN7rMzfGcB2DKt67EqDWQELA"
Request Body
8
//incorrectly still fetches from disk cache (returns 200)
GET http://localhost/api/my-number/1
Response Headers
cache-control: public,max-age=3600
etag: "2kuSN7rMzfGcB2DKt67EqDWQELA"
Response Body
7
This is indeed incorrect behavior. RFC 7234 says:
A cache MUST invalidate the effective Request URI... as well as the URI(s) in the Location and Content-Location
response header fields (if present) when a non-error status code is
received in response to an unsafe request method.
Given that, the bug report you filed looks appropriate to me.

HTTP 204 leads to download in Chrome

when I try to Respond with on HTTP 204 Status, my Chrome browser is starting an Download that fails.
Request:
Request URL: https://dummy.page/dummyRequest
Request Method: GET
Status Code: 204
Remote Address: [dummy]:443
Referrer Policy: no-referrer-when-downgrade
Response:
date: Fri, 08 Mar 2019 08:24:05 GMT
server:
status: 204
When I use Dev-Tool to inspect the response, chrome says "faild to load response data" and in firefox I can see one empty line.
My server returns a Response via Java:
return Response.noContent().build();
I also tried to return NULL at this point but that did not change anything.
The whole thing is working fine in Firefox but when I try in Chrome it starts an Download of "dummyRequest" (from the URL) which fails.
So what I want to know: why is Chrome starting a download and what could I do against?
Thanks for helping ;)
I came across the same issue with 204 responses. What worked for me was checking the Content-Type response header on the server-side before sending the response.
My 204 responses were sending a default Content-Type of application/octet-stream (from the link: "An unknown file type should use this type. Browsers pay a particular care when manipulating these files"). When switching the Content-Type to something different (I chose text/html), the trigger for downloads stopped.

Cannot play wav file on safari

I'm trying to play a wav file on safari. Pretty much the same question as this: playing a WAV file on iOS Safari
But the accepted answers aren't working. I'm using a rails server with apache and phusion passenger. The audio file plays fine on chrome but not on any safari (desktop, mobile, and through uiwebview).
I'm sending the file in rails with
send_file filename, :type => "audio/x-wav", :disposition => "inline"
From the other stack overflow q&a, I tried adding Content-Range and Content-Length headers to the response
size = File.size(filename)
response.header["Content-Range"] = "bytes 0-#{size-1}/#{size}"
response.header["Content-Length"] = "#{size}"
The error i'm receiving is pretty nondescript "Failed to load resource: Plug-in handled load"
Here are the headers of the response
x-runtime 0.589797
Date Wed, 17 Aug 2016 16:38:49 GMT
X-Content-Type-Options nosniff
Server Apache/2.2.15 (CentOS)
X-Powered-By Phusion Passenger 5.0.7
Status 200 OK
Content-Type audio/x-wav
content-range bytes 0-3243/3244
Cache-Control private
Content-Transfer-Encoding binary
Content-Disposition inline; filename="eng-182-msg0026.wav"
Connection close
Content-Length 3244
X-XSS-Protection 1; mode=block
x-runtime 0.589797
When requesting a direct link to a media file this would work. But I was requesting this through a controller. Safari was making multiple http requests each for a certain range. The server was responding with the entire file every time which is why it fails.
The annoying thing is that the Safari web inspector decides not to show the "Range" header in the network request. It'll show other http headers but not the most important one in this case...
Anyways, short answer, respond back with the the correct byte range that each request wants.
I had the same problem, playing audio files on the Safari didn't work, but on the Chrome and every other browser everything worked as expected.
Set proper Content-Range in response header solve my problem. I used forked gem send_file_with_range, which contain fix for the Rails 5.1.
I recommend this gem because code in this gem is pretty simple and short, and this solution seems like the simplest and quickest.
Note: this solution is specific for the Ruby on Rails developers, but general solution is to set proper Content-Range in the response header, for every request.
I hope that this will be helpful for somebody.

Override the "cache-control" values in a HTTP response

I have a web page that returns the following header when I access material:
HTTP/1.1 200 OK
Date: Sat, 29 Jun 2013 15:57:25 GMT
Server: Apache
Content-Length: 2247515
Cache-Control: no-cache, no-store, must-revalidate, max-age=-1
Pragma: no-cache, no-store
Expires: -1
Connection: close
Using a chrome extension, I want to modify this response header so that the material is actually cached instead of wasting bandwidth.
I have the following sample code:
chrome.webRequest.onHeadersReceived.addListener(function(details)
{
// Delete the required elements
removeHeader(details.responseHeaders, 'pragma');
removeHeader(details.responseHeaders, 'expires');
// Modify cache-control
updateHeader(details.responseHeaders, 'cache-control', 'max-age=3600;')
console.log(details.url);
console.log(details.responseHeaders);
return{responseHeaders: details.responseHeaders};
},
{urls: ["<all_urls>"]}, ['blocking', 'responseHeaders']
);
Which correctly modifies the header to something like this (based on the console.log() output):
HTTP/1.1 200 OK
Date: Sat, 29 Jun 2013 15:57:25 GMT
Server: Apache
Content-Length: 2247515
Cache-Control: max-age=3600
Connection: close
But based on everything I have tried to check this, I cannot see any evidence whatsoever that this has actually happened:
The cache does not contain an entry for this file
The Network tab in the Developer Console shows no change at all to the HTTP response (I have tried changing it to even trivial modifications just for the sake of ensuring that its not a error, but still no change).
The only real hints I can find are this question which suggests that my approach still works and this paragraph on the webRequest API documentation which suggests that this won't work (but doesn't explain why I can't get any changes whatsoever):
Note that the web request API presents an abstraction of the network
stack to the extension. Internally, one URL request can be split into
several HTTP requests (for example to fetch individual byte ranges
from a large file) or can be handled by the network stack without
communicating with the network. For this reason, the API does not
provide the final HTTP headers that are sent to the network. For
example, all headers that are related to caching are invisible to the
extension.
Nothing is working whatsoever (I can't modify the HTTP response header at all) so I think that's my first concern.
Any suggestions at where I could be going wrong or how to go about finding what is going wrong here?
If its not possible, are there any other ways to achieve what I am trying to achieve?
I have recently spent some hours on trying to get a file cached, and discovered that the chrome.webRequest and chrome.declarativeWebRequest APIs cannot force resources to be cached. In no way.
The Cache-Control (and other) response headers can be changed, but it will only be visible in the getResponseHeader method. Not in the caching behaviour.

Why is Firefox ignoring cache control on Range-based queries?

Web servers have the ability to stream media (audio in this example) to browsers. Browsers use HTML5 controls to play the media. What I'm discovering, however, is that Firefox is caching the media, even though I (believe I) explicitly tell it not to. I have a hunch that it has something to do with the 206 Partial Content response as a regular "non-range" GET with a full 200 OK response does not get cached. Chrome (27) handles this OK, but Firefox (21) does not:
HTTP/1.1 206 Partial Content
Date: Tue, 21 May 2013 17:24:29 GMT
Expires: 0
Pragma: no-cache
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Content-Disposition: attachment; filename="audio.wav"
Content-Type: audio/x-wav
Connection: close
Accept-Ranges: bytes
Content-Range: bytes 0-218923/218924
Anyone got any ideas as to how to make Firefox not cache this? When I click to play other audio files that are named the same, Firefox simply plays the first one that was clicked (cached) in a session as opposed to re-fetching the new one from the server.
Note that this question seems to directly ask/answer this, but it does not work... I use the headers mentioned.
Thanks for any help.
EDIT: I also tried adding an ETag: header, but still Firefox caches the original response.
EDIT: Including a Content-Length: header to match (218924 in this example) does not seem to impact the issue.
EDIT: I have filed a bug at bugzilla.mozilla.org but no activity on it at this point.
Your Firefox is implementing Section 13.8 of rfc2616. So this behavior is alright.
13.8 Errors or Incomplete Response Cache Behavior
A cache that receives an incomplete response (for example, with fewer
bytes of data than specified in a Content-Length header) MAY store the
response. However, the cache MUST treat this as a partial response.
Partial responses MAY be combined as described in section 13.5.4; the
result might be a full response or might still be partial. A cache
MUST NOT return a partial response to a client without explicitly
marking it as such, using the 206 (Partial Content) status code. A
cache MUST NOT return a partial response using a status code of 200
(OK).
Partial responses may(or maynot) be stored. So Chrome and Firefox both follow the rules.