Announcements

Help Wizard

Step 1

NEXT STEP

Playlist tracks API returns 304 Not Modified with Content-Length 0

Playlist tracks API returns 304 Not Modified with Content-Length 0

Device: custom Android tablet; Squid

 

My Question or Issue

Background: In our environment, we're required to filter web traffic, so the clients (the tablets) are configured to allow a proxy to intercept HTTPS traffic; we use Squid for this.

 

The playlist tracks API (/v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&limit=40&market=US) returns a Cache-Control header which tells Squid the result is cacheable, and that the cached result can be shared between clients, but that it needs to be revalidated each time (cache-control: public, max-age=0).

 

The next time a tablet requests it, Squid does that revalidation— it sends a GET request with If-Modified-Since and If-None-Match with the modification date and the etag returned on the first request.

 

The Spotify API then returns a 304 Not Modified, but included in that response is a Content-Length: 0 header. That's not correct; the right size is 132524, and that violates the HTTP spec RFC7230 §3.3.2: "A server MAY send a Content-Length header field in a 304 (Not Modified) response to a conditional GET request (Section 4.1 of [RFC7232]); a server MUST NOT send Content-Length in such a response unless its field-value equals the decimal number of octets that would have been sent in the payload body of a 200 (OK) response to the same request." This unfortunately leaves Squid rather confused.

 

HTTP traffic — initial GET, non-revalidated:

GET /v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&limit=40&market=US HTTP/1.1
Accept: application/json
Content-Type: application/json
Authorization: Bearer REDACTED
Accept-Encoding: gzip
User-Agent: okhttp/4.9.0
Host: api.spotify.com
X-Forwarded-For: unknown
Cache-Control: max-age=2419200
Connection: keep-alive

HTTP/1.1 200 OK
content-type: application/json; charset=utf-8
cache-control: public, max-age=0
etag: "MC-IjEwMGE1NzJmOGM0Y2VkNjgwOTNkZmUzNGM3YzljMDkwIg=="
x-robots-tag: noindex, nofollow
access-control-allow-origin: *
access-control-allow-headers: Accept, App-Platform, Authorization, Content-Type, Origin, Retry-After, Spotify-App-Version, X-Cloud-Trace-Context, client-token, content-access-token
access-control-allow-methods: GET, POST, OPTIONS, PUT, DELETE, PATCH
access-control-allow-credentials: true
access-control-max-age: 604800
Content-Length: 132524
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
vary: Accept-Encoding
date: Wed, 21 Apr 2021 18:00:16 GMT
server: envoy
Via: HTTP/2 edgeproxy, 1.1 google
Alt-Svc: clear
Connection: close

{
  "href" : "https://api.spotify.com/v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&limit=40&market=US",
⋮

HTTP GET to revalidate: (this is the buggy one)

GET /v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&limit=40&market=US HTTP/1.1
If-Modified-Since: Wed, 21 Apr 2021 18:00:16 GMT
If-None-Match: "MC-IjEwMGE1NzJmOGM0Y2VkNjgwOTNkZmUzNGM3YzljMDkwIg=="
Accept: application/json
Content-Type: application/json
Authorization: Bearer REDACTED
Accept-Encoding: gzip
User-Agent: okhttp/4.9.0
Host: api.spotify.com
X-Forwarded-For: unknown
Cache-Control: max-age=2419200
Connection: keep-alive

HTTP/1.1 304 Not Modified
cache-control: public, max-age=0
etag: "MC-IjEwMGE1NzJmOGM0Y2VkNjgwOTNkZmUzNGM3YzljMDkwIg=="
x-robots-tag: noindex, nofollow
access-control-allow-origin: *
access-control-allow-headers: Accept, App-Platform, Authorization, Content-Type, Origin, Retry-After, Spotify-App-Version, X-Cloud-Trace-Context, client-token, content-access-token
access-control-allow-methods: GET, POST, OPTIONS, PUT, DELETE, PATCH
access-control-allow-credentials: true
access-control-max-age: 604800
Content-Length: 0
strict-transport-security: max-age=31536000
x-content-type-options: nosniff
date: Wed, 21 Apr 2021 18:01:20 GMT
server: envoy
Via: HTTP/2 edgeproxy, 1.1 google
Alt-Svc: clear
Connection: close

 

Reply
1 Reply

Just curious if anyone has taken a look at this?

Suggested posts