Chrome bad Range header: Range: bytes=0-

1,459 views
Skip to first unread message

Loreto Parisi

unread,
Nov 15, 2018, 6:02:20 AM11/15/18
to net-dev
My express node.js server does mp4 streaming with Partial HTTP Content (206). When in Safari this works on, but not in Chrome.

My workflow it this one

Client (Chrome) :/streams/#streamID?start=12&end=34 ----> REQUEST 1 ----> Node.js/Express --(Range)---> MediaServer ---- RESPONSE 1 (Content-Range)---> Client (Chrome)  bytes

When in Chrome, the browser raises REQUEST 2 (with the wrong header "Range= bytes 0-", while Safari will not. In fact Safari works ok, while Chrome is not. So the problem is? Does Safari implement HTTP 206 differently and Chrome is more strict on that? I will not expect this.


You can see the REQUEST/RESPONSE 1 and 2 here:


There should not be the REQUEST 2 from the browser. This request comes from the Google Chrome page when you put in a streaming URL like mp3, etc. It injects into the page a built-in payer (strangely it's a <video> tag, while it should be a <audio> tag), and start that request.

Let's make an example. If you go here (this is not mine, just an example) you will see how Chrome raises a bad request (REQUEST 2) pushing an invalid "Range: bytes=0-" header in in this example:


You can see in the Console the two requests

REQUEST 1
GET /mp3/Beethoven_12_Variation.mp3 HTTP/1.1
Connection: keep-alive
Upgrade-Insecure-Requests: 1
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
Accept-Encoding: gzip, deflate
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,de;q=0.5,ru;q=0.4

RESPONSE 1
HTTP/1.1 200 OK
Date: Thu, 15 Nov 2018 09:52:54 GMT
Server: Apache
Last-Modified: Fri, 26 Mar 2004 15:55:11 GMT
ETag: "1d014e-3d68ac9e215c0"
Accept-Ranges: bytes
Content-Length: 1900878
Keep-Alive: timeout=2, max=200
Connection: Keep-Alive
Content-Type: audio/mpeg


REQUEST 2
GET /mp3/Beethoven_12_Variation.mp3 HTTP/1.1
Connection: keep-alive
Accept-Encoding: identity;q=1, *;q=0
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10_14_1) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/70.0.3538.102 Safari/537.36
Accept: */*
Accept-Language: it-IT,it;q=0.9,en-US;q=0.8,en;q=0.7,es;q=0.6,de;q=0.5,ru;q=0.4
Range: bytes=0-           <----------- HERE!!!! IT's CHROME BUG THEN ?!?


RESPONSE 2
HTTP/1.1 206 Partial Content
Date: Thu, 15 Nov 2018 09:52:55 GMT
Server: Apache
Last-Modified: Fri, 26 Mar 2004 15:55:11 GMT
ETag: "1d014e-3d68ac9e215c0"
Accept-Ranges: bytes
Keep-Alive: timeout=2, max=200
Connection: Keep-Alive
Content-Type: audio/mpeg
Content-Range: bytes 0-1900877/1900878
Content-Length: 1900878

Yutaka Hirano

unread,
Nov 15, 2018, 6:25:53 AM11/15/18
to loreto...@gmail.com, hu...@chromium.org, net...@chromium.org

--
You received this message because you are subscribed to the Google Groups "net-dev" group.
To unsubscribe from this group and stop receiving emails from it, send an email to net-dev+u...@chromium.org.
To post to this group, send email to net...@chromium.org.
To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/net-dev/f90b4c6a-8a5c-441d-b590-006643a63eb3%40chromium.org.

Maksim Orlovich

unread,
Nov 15, 2018, 8:44:27 AM11/15/18
to Yutaka Hirano, loreto...@gmail.com, hubbe, net...@chromium.org
Why do you think Range: 0- is invalid? It's kind of weird to use a
range header like that (representing the whole file), but it seems
compliant, unless I missed some requirement. Or are you referring to
the resource being refetched?
If so, how are the two fetches done?
> To view this discussion on the web visit https://groups.google.com/a/chromium.org/d/msgid/net-dev/CABihn6FypnzxOfvvVhGc-CvVvH2tJT81s00kniOKSV%2BM0JRqrA%40mail.gmail.com.

Loreto Parisi

unread,
Nov 15, 2018, 11:56:26 AM11/15/18
to net-dev, yhi...@chromium.org, loreto...@gmail.com, hu...@chromium.org, morl...@google.com
So, because (1) I get this weird "Range: bytes 0 - " here https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/ZOlTHNAbyNQ
and (2) because Safari does not work in this way and it works.
Basically Chrome raises the REQUEST 2 and it shouldn't. There is not need of that request. The first is the right one. If you take a look at the Gist here https://gist.github.com/loretoparisi/11680342ae7387489c720f2e7d529903

the RESPONSE 1 (from Node.js MediaServer) is the only one needed to start streaming 

*** RESPONSE 1 ***
HTTP/1.1 206 Partial Content
Accept-Ranges: bytes
Access-Control-Allow-Headers: Range
Access-Control-Allow-Methods: POST, GET, OPTIONS
Access-Control-Allow-Origin: *
Cache-Control: no-cache, no-store, must-revalidate
Content-Range: bytes 120429-240237/5751405
Content-Type: audio/mpeg
Date: Wed, 14 Nov 2018 17:46:08 GMT
Expires: 0
Pragma: no-cache
X-Powered-By: Express
Content-Length: 119809
Connection: keep-alive

In fact Safari starts to stream the audio, while Chrome raises REQUEST 2 with the invalid "Range" header. Why?

acol...@chromium.org

unread,
Nov 15, 2018, 12:18:46 PM11/15/18
to net-dev, yhi...@chromium.org, loreto...@gmail.com, hu...@chromium.org, morl...@google.com
Hi Loreto,

I've responded in the private email you sent to me about this, but I'll respond here too just for transparency.

1. I'm not sure where request 1 is triggered, but in my opinion that one is the potentially unnecessary one. Even though it is an "extra" request, it is totally valid and your server should be able to handle it.

2. Using a "Range: bytes 0-" is totally valid and allows Chrome to explicitly verify that the server properly supports Range requests. If the server doesn't respond with a 206 response code and a Content-Range header, then Chrome can assume the server doesn't support Range requests properly. Accept-Ranges in the response is not always enough because we've run into servers in the while that blindly return that header, but don't actually support ranges.

3. As we've discussed in our private email conversation, your server is acting like a proxy, but you are not sending spec compliant responses to Chrome. I'm happy to continue helping you with this, if you'd like.


Aaron


On Thursday, November 15, 2018 at 8:56:26 AM UTC-8, Loreto Parisi wrote:
> So, because (1) I get this weird "Range: bytes 0 - " here https://groups.google.com/a/chromium.org/forum/#!topic/chromium-dev/ZOlTHNAbyNQ
> and (2) because Safari does not work in this way and it works.
> Basically Chrome raises the REQUEST 2 and it shouldn't. There is not need of that request. The first is the right one. If you take a look at the Gist here https://gist.github.com/loretoparisi/11680342ae7387489c720f2e7d529903
>
>
> the RESPONSE 1 (from Node.js MediaServer) is the only one needed to start streaming 
>
>
> *** RESPONSE 1 ***HTTP/1.1 206 Partial ContentAccept-Ranges: bytesAccess-Control-Allow-Headers: RangeAccess-Control-Allow-Methods: POST, GET, OPTIONSAccess-Control-Allow-Origin: *Cache-Control: no-cache, no-store, must-revalidateContent-Range: bytes 120429-240237/5751405Content-Type: audio/mpegDate: Wed, 14 Nov 2018 17:46:08 GMTExpires: 0Pragma: no-cacheX-Powered-By: ExpressContent-Length: 119809Connection: keep-alive
Reply all
Reply to author
Forward
0 new messages