<?xml version="1.0" encoding="UTF-8"?>
<rss xmlns:content="http://purl.org/rss/1.0/modules/content/" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#" xmlns:taxo="http://purl.org/rss/1.0/modules/taxonomy/" version="2.0">
  <channel>
    <title>topic Playlist tracks API returns 304 Not Modified with Content-Length 0 in Spotify for Developers</title>
    <link>https://community.spotify.com/t5/Spotify-for-Developers/Playlist-tracks-API-returns-304-Not-Modified-with-Content-Length/m-p/5193142#M2430</link>
    <description>&lt;P&gt;&lt;STRONG&gt;Device: custom Android tablet; Squid&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;My Question or Issue&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The playlist tracks API (&lt;FONT face="terminal, monaco"&gt;/v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&amp;amp;limit=40&amp;amp;market=US&lt;/FONT&gt;) 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 (&lt;FONT face="terminal, monaco"&gt;cache-control: public, max-age=0&lt;/FONT&gt;).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The Spotify API then returns a 304 Not Modified, but included in that response is a &lt;FONT face="terminal, monaco"&gt;Content-Length: 0&lt;/FONT&gt; 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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;HTTP traffic — initial GET, non-revalidated:&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;GET /v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&amp;amp;limit=40&amp;amp;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&amp;amp;limit=40&amp;amp;market=US",
⋮&lt;/PRE&gt;&lt;P&gt;&lt;STRONG&gt;HTTP GET to revalidate: &lt;/STRONG&gt;(this is the buggy one)&lt;/P&gt;&lt;PRE&gt;GET /v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&amp;amp;limit=40&amp;amp;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&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
    <pubDate>Fri, 23 Apr 2021 14:29:29 GMT</pubDate>
    <dc:creator>derobert_gtl</dc:creator>
    <dc:date>2021-04-23T14:29:29Z</dc:date>
    <item>
      <title>Playlist tracks API returns 304 Not Modified with Content-Length 0</title>
      <link>https://community.spotify.com/t5/Spotify-for-Developers/Playlist-tracks-API-returns-304-Not-Modified-with-Content-Length/m-p/5193142#M2430</link>
      <description>&lt;P&gt;&lt;STRONG&gt;Device: custom Android tablet; Squid&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;My Question or Issue&lt;/STRONG&gt;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The playlist tracks API (&lt;FONT face="terminal, monaco"&gt;/v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&amp;amp;limit=40&amp;amp;market=US&lt;/FONT&gt;) 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 (&lt;FONT face="terminal, monaco"&gt;cache-control: public, max-age=0&lt;/FONT&gt;).&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;The Spotify API then returns a 304 Not Modified, but included in that response is a &lt;FONT face="terminal, monaco"&gt;Content-Length: 0&lt;/FONT&gt; 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.&lt;/P&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;&lt;P&gt;&lt;STRONG&gt;HTTP traffic — initial GET, non-revalidated:&lt;/STRONG&gt;&lt;/P&gt;&lt;PRE&gt;GET /v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&amp;amp;limit=40&amp;amp;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&amp;amp;limit=40&amp;amp;market=US",
⋮&lt;/PRE&gt;&lt;P&gt;&lt;STRONG&gt;HTTP GET to revalidate: &lt;/STRONG&gt;(this is the buggy one)&lt;/P&gt;&lt;PRE&gt;GET /v1/playlists/37i9dQZEVXbLRQDuF5jeBp/tracks?offset=0&amp;amp;limit=40&amp;amp;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&lt;/PRE&gt;&lt;P&gt;&amp;nbsp;&lt;/P&gt;</description>
      <pubDate>Fri, 23 Apr 2021 14:29:29 GMT</pubDate>
      <guid>https://community.spotify.com/t5/Spotify-for-Developers/Playlist-tracks-API-returns-304-Not-Modified-with-Content-Length/m-p/5193142#M2430</guid>
      <dc:creator>derobert_gtl</dc:creator>
      <dc:date>2021-04-23T14:29:29Z</dc:date>
    </item>
    <item>
      <title>Re: Playlist tracks API returns 304 Not Modified with Content-Length 0</title>
      <link>https://community.spotify.com/t5/Spotify-for-Developers/Playlist-tracks-API-returns-304-Not-Modified-with-Content-Length/m-p/5203373#M2513</link>
      <description>&lt;P&gt;Just curious if anyone has taken a look at this?&lt;/P&gt;</description>
      <pubDate>Tue, 11 May 2021 15:53:58 GMT</pubDate>
      <guid>https://community.spotify.com/t5/Spotify-for-Developers/Playlist-tracks-API-returns-304-Not-Modified-with-Content-Length/m-p/5203373#M2513</guid>
      <dc:creator>derobert_gtl</dc:creator>
      <dc:date>2021-05-11T15:53:58Z</dc:date>
    </item>
  </channel>
</rss>

