Some Eclipse Foundation services are deprecated, or will be soon. Please ensure you've read this important communication.

Bug 487878

Summary: Etags for cache control for the eclipsecon API
Product: Community Reporter: Christopher Guindon <chris.guindon>
Component: EclipseConAssignee: Eric Poirier <eric.poirier>
Status: RESOLVED FIXED QA Contact:
Severity: enhancement    
Priority: P2 CC: chris.guindon, cpetrov
Version: unspecified   
Target Milestone: ---   
Hardware: PC   
OS: Mac OS X   
Whiteboard:

Description Christopher Guindon CLA 2016-02-16 09:34:26 EST
From my inbox:

https://www.eclipsecon.org/na2016/api/1.0/eclipsecon_scheduled_sessions service sends an Etag in the response. Upon consecutive requests with this ETag sent as "If-None-Match" header value, the server should respond with "304 Not Modified" if the Etag matches the current one. However the server always sends 200 OK.

"Last-Modified" is always a current date and using "If-Modified-Since" yields the same result (all requests get a 200 OK response regardless of the If-Modified-Since header value).

Do you think entity tag caching could be enabled for the service?

We to implement the proper logic for E-tags.
Comment 1 Christopher Guindon CLA 2016-02-16 09:38:50 EST
I am upping the priority for this since the app is due to be released really soon...
Comment 2 Christopher Guindon CLA 2016-02-16 11:57:38 EST
After some investigation, I can't reproduce the error since i am getting a 304 not modified:

If I go to https://www.eclipsecon.org/na2016/api/1.0/eclipsecon_scheduled_sessions with my browser, the response is a 304 not modified:

GET /na2016/api/1.0/eclipsecon_scheduled_sessions HTTP/1.1
Host: www.eclipsecon.org
User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:43.0) Gecko/20100101 Firefox/43.0
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-US,en;q=0.5
Accept-Encoding: gzip, deflate
Cookie: I REMOVED IT
Connection: keep-alive
If-Modified-Since: Tue, 16 Feb 2016 16:50:43 GMT
If-None-Match: "1455641443-0"
Cache-Control: max-age=0

HTTP/1.1 304 Not Modified
Date: Tue, 16 Feb 2016 16:51:34 GMT
Server: Apache
Connection: Keep-Alive
Keep-Alive: timeout=3, max=100
Etag: "1455641443-0"
Cache-Control: public, max-age=900
Vary: Accept,Accept-Encoding
Comment 3 Christian Petrov CLA 2016-02-16 12:58:25 EST
(In reply to Christopher Guindon from comment #2)
> After some investigation, I can't reproduce the error since i am getting a
> 304 not modified:
> 
> If I go to
> https://www.eclipsecon.org/na2016/api/1.0/eclipsecon_scheduled_sessions with
> my browser, the response is a 304 not modified:
> 
> GET /na2016/api/1.0/eclipsecon_scheduled_sessions HTTP/1.1
> Host: www.eclipsecon.org
> User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:43.0)
> Gecko/20100101 Firefox/43.0
> Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
> Accept-Language: en-US,en;q=0.5
> Accept-Encoding: gzip, deflate
> Cookie: I REMOVED IT
> Connection: keep-alive
> If-Modified-Since: Tue, 16 Feb 2016 16:50:43 GMT
> If-None-Match: "1455641443-0"
> Cache-Control: max-age=0
> 
> HTTP/1.1 304 Not Modified
> Date: Tue, 16 Feb 2016 16:51:34 GMT
> Server: Apache
> Connection: Keep-Alive
> Keep-Alive: timeout=3, max=100
> Etag: "1455641443-0"
> Cache-Control: public, max-age=900
> Vary: Accept,Accept-Encoding

This only seems to work if both 'If-Modified-Since' and 'If-None-Match' headers are sent and only if both headers have the exact same values you have sent with your request.

1) When sending 'If-None-Match' set to '"1455641443-0"' alone, 200 OK is received.

This contradicts with RFC 7232 (https://tools.ietf.org/html/rfc7232):

'A recipient MUST ignore If-Modified-Since if the request contains an
If-None-Match header field; the condition in If-None-Match is
considered to be a more accurate replacement for the condition in
If-Modified-Since, and the two are only combined for the sake of
interoperating with older intermediaries that might not implement
If-None-Match.'

2) Moreover, the server only sends '304 Not Modified' if the 'If-Modified-Since' header exactly matches the value you have sent: 'Tue, 16 Feb 2016 16:50:43 GMT'. When sending e.g. 'Tue, 16 Feb 2016 16:50:44 GMT', one second later instead together with 'If-None-Match: "1455641443-0"', the response's status will be '200 OK', although '304 Not Modified' would be expected.
Comment 4 Christopher Guindon CLA 2016-02-16 13:19:41 EST
(In reply to Christian Petrov from comment #3)
> (In reply to Christopher Guindon from comment #2)
> > After some investigation, I can't reproduce the error since i am getting a
> > 304 not modified:
> > 
> > If I go to
> > https://www.eclipsecon.org/na2016/api/1.0/eclipsecon_scheduled_sessions with
> > my browser, the response is a 304 not modified:
> > 
> > GET /na2016/api/1.0/eclipsecon_scheduled_sessions HTTP/1.1
> > Host: www.eclipsecon.org
> > User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:43.0)
> > Gecko/20100101 Firefox/43.0
> > Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
> > Accept-Language: en-US,en;q=0.5
> > Accept-Encoding: gzip, deflate
> > Cookie: I REMOVED IT
> > Connection: keep-alive
> > If-Modified-Since: Tue, 16 Feb 2016 16:50:43 GMT
> > If-None-Match: "1455641443-0"
> > Cache-Control: max-age=0
> > 
> > HTTP/1.1 304 Not Modified
> > Date: Tue, 16 Feb 2016 16:51:34 GMT
> > Server: Apache
> > Connection: Keep-Alive
> > Keep-Alive: timeout=3, max=100
> > Etag: "1455641443-0"
> > Cache-Control: public, max-age=900
> > Vary: Accept,Accept-Encoding
> 
> This only seems to work if both 'If-Modified-Since' and 'If-None-Match'
> headers are sent and only if both headers have the exact same values you
> have sent with your request.
> 
> 1) When sending 'If-None-Match' set to '"1455641443-0"' alone, 200 OK is
> received.
> 
> This contradicts with RFC 7232 (https://tools.ietf.org/html/rfc7232):
> 
> 'A recipient MUST ignore If-Modified-Since if the request contains an
> If-None-Match header field; the condition in If-None-Match is
> considered to be a more accurate replacement for the condition in
> If-Modified-Since, and the two are only combined for the sake of
> interoperating with older intermediaries that might not implement
> If-None-Match.'
> 
> 2) Moreover, the server only sends '304 Not Modified' if the
> 'If-Modified-Since' header exactly matches the value you have sent: 'Tue, 16
> Feb 2016 16:50:43 GMT'. When sending e.g. 'Tue, 16 Feb 2016 16:50:44 GMT',
> one second later instead together with 'If-None-Match: "1455641443-0"', the
> response's status will be '200 OK', although '304 Not Modified' would be
> expected.

It seems that drupal requires both:

https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/drupal_serve_page_from_cache/7


  // See if the client has provided the required HTTP headers.
  $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ? strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
  $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ? stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;

  if ($if_modified_since && $if_none_match
     && $if_none_match == $etag // etag must match
     && $if_modified_since == $cache->created) { // if-modified-since must match
    header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
    drupal_send_headers($default_headers);
    return;
  }
Comment 5 Christopher Guindon CLA 2016-02-16 13:33:49 EST
(In reply to Christopher Guindon from comment #4)
> (In reply to Christian Petrov from comment #3)
> > (In reply to Christopher Guindon from comment #2)
> > > After some investigation, I can't reproduce the error since i am getting a
> > > 304 not modified:
> > > 
> > > If I go to
> > > https://www.eclipsecon.org/na2016/api/1.0/eclipsecon_scheduled_sessions with
> > > my browser, the response is a 304 not modified:
> > > 
> > > GET /na2016/api/1.0/eclipsecon_scheduled_sessions HTTP/1.1
> > > Host: www.eclipsecon.org
> > > User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:43.0)
> > > Gecko/20100101 Firefox/43.0
> > > Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
> > > Accept-Language: en-US,en;q=0.5
> > > Accept-Encoding: gzip, deflate
> > > Cookie: I REMOVED IT
> > > Connection: keep-alive
> > > If-Modified-Since: Tue, 16 Feb 2016 16:50:43 GMT
> > > If-None-Match: "1455641443-0"
> > > Cache-Control: max-age=0
> > > 
> > > HTTP/1.1 304 Not Modified
> > > Date: Tue, 16 Feb 2016 16:51:34 GMT
> > > Server: Apache
> > > Connection: Keep-Alive
> > > Keep-Alive: timeout=3, max=100
> > > Etag: "1455641443-0"
> > > Cache-Control: public, max-age=900
> > > Vary: Accept,Accept-Encoding
> > 
> > This only seems to work if both 'If-Modified-Since' and 'If-None-Match'
> > headers are sent and only if both headers have the exact same values you
> > have sent with your request.
> > 
> > 1) When sending 'If-None-Match' set to '"1455641443-0"' alone, 200 OK is
> > received.
> > 
> > This contradicts with RFC 7232 (https://tools.ietf.org/html/rfc7232):
> > 
> > 'A recipient MUST ignore If-Modified-Since if the request contains an
> > If-None-Match header field; the condition in If-None-Match is
> > considered to be a more accurate replacement for the condition in
> > If-Modified-Since, and the two are only combined for the sake of
> > interoperating with older intermediaries that might not implement
> > If-None-Match.'
> > 
> > 2) Moreover, the server only sends '304 Not Modified' if the
> > 'If-Modified-Since' header exactly matches the value you have sent: 'Tue, 16
> > Feb 2016 16:50:43 GMT'. When sending e.g. 'Tue, 16 Feb 2016 16:50:44 GMT',
> > one second later instead together with 'If-None-Match: "1455641443-0"', the
> > response's status will be '200 OK', although '304 Not Modified' would be
> > expected.
> 
> It seems that drupal requires both:
> 
> https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/
> drupal_serve_page_from_cache/7
> 
> 
>   // See if the client has provided the required HTTP headers.
>   $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
> strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
>   $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
> stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
> 
>   if ($if_modified_since && $if_none_match
>      && $if_none_match == $etag // etag must match
>      && $if_modified_since == $cache->created) { // if-modified-since must
> match
>     header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
>     drupal_send_headers($default_headers);
>     return;
>   }

I believe that you are right, they are not following the specs. 

I would need to override this function for the eclipsecon api but I don't think I have time to work on this right now.

Can you work around it and supply the same value from the initial response for the If-Modified-Since and If-match header?
Comment 6 Christian Petrov CLA 2016-02-17 14:42:53 EST
(In reply to Christopher Guindon from comment #5)
> (In reply to Christopher Guindon from comment #4)
> > (In reply to Christian Petrov from comment #3)
> > > (In reply to Christopher Guindon from comment #2)
> > > > After some investigation, I can't reproduce the error since i am getting a
> > > > 304 not modified:
> > > > 
> > > > If I go to
> > > > https://www.eclipsecon.org/na2016/api/1.0/eclipsecon_scheduled_sessions with
> > > > my browser, the response is a 304 not modified:
> > > > 
> > > > GET /na2016/api/1.0/eclipsecon_scheduled_sessions HTTP/1.1
> > > > Host: www.eclipsecon.org
> > > > User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.10; rv:43.0)
> > > > Gecko/20100101 Firefox/43.0
> > > > Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
> > > > Accept-Language: en-US,en;q=0.5
> > > > Accept-Encoding: gzip, deflate
> > > > Cookie: I REMOVED IT
> > > > Connection: keep-alive
> > > > If-Modified-Since: Tue, 16 Feb 2016 16:50:43 GMT
> > > > If-None-Match: "1455641443-0"
> > > > Cache-Control: max-age=0
> > > > 
> > > > HTTP/1.1 304 Not Modified
> > > > Date: Tue, 16 Feb 2016 16:51:34 GMT
> > > > Server: Apache
> > > > Connection: Keep-Alive
> > > > Keep-Alive: timeout=3, max=100
> > > > Etag: "1455641443-0"
> > > > Cache-Control: public, max-age=900
> > > > Vary: Accept,Accept-Encoding
> > > 
> > > This only seems to work if both 'If-Modified-Since' and 'If-None-Match'
> > > headers are sent and only if both headers have the exact same values you
> > > have sent with your request.
> > > 
> > > 1) When sending 'If-None-Match' set to '"1455641443-0"' alone, 200 OK is
> > > received.
> > > 
> > > This contradicts with RFC 7232 (https://tools.ietf.org/html/rfc7232):
> > > 
> > > 'A recipient MUST ignore If-Modified-Since if the request contains an
> > > If-None-Match header field; the condition in If-None-Match is
> > > considered to be a more accurate replacement for the condition in
> > > If-Modified-Since, and the two are only combined for the sake of
> > > interoperating with older intermediaries that might not implement
> > > If-None-Match.'
> > > 
> > > 2) Moreover, the server only sends '304 Not Modified' if the
> > > 'If-Modified-Since' header exactly matches the value you have sent: 'Tue, 16
> > > Feb 2016 16:50:43 GMT'. When sending e.g. 'Tue, 16 Feb 2016 16:50:44 GMT',
> > > one second later instead together with 'If-None-Match: "1455641443-0"', the
> > > response's status will be '200 OK', although '304 Not Modified' would be
> > > expected.
> > 
> > It seems that drupal requires both:
> > 
> > https://api.drupal.org/api/drupal/includes!bootstrap.inc/function/
> > drupal_serve_page_from_cache/7
> > 
> > 
> >   // See if the client has provided the required HTTP headers.
> >   $if_modified_since = isset($_SERVER['HTTP_IF_MODIFIED_SINCE']) ?
> > strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']) : FALSE;
> >   $if_none_match = isset($_SERVER['HTTP_IF_NONE_MATCH']) ?
> > stripslashes($_SERVER['HTTP_IF_NONE_MATCH']) : FALSE;
> > 
> >   if ($if_modified_since && $if_none_match
> >      && $if_none_match == $etag // etag must match
> >      && $if_modified_since == $cache->created) { // if-modified-since must
> > match
> >     header($_SERVER['SERVER_PROTOCOL'] . ' 304 Not Modified');
> >     drupal_send_headers($default_headers);
> >     return;
> >   }
> 
> I believe that you are right, they are not following the specs. 
> 
> I would need to override this function for the eclipsecon api but I don't
> think I have time to work on this right now.
> 
> Can you work around it and supply the same value from the initial response
> for the If-Modified-Since and If-match header?

Thank you for the information, we would have to adhere to the non-standard implementation for caching of COD data.
Comment 7 Christopher Guindon CLA 2016-03-03 10:25:47 EST
I am re-opening this bug because of the following comment in my inbox from Christian:

when the user is logged in, i.e. session cookies are sent along, the eclipsecon_scheduled_sessions service responds with "Cache-Control → no-cache [...]" and respectively without "ETag" and "Last-Modified" headers.

Would it be possible to enable caching on the service for requests containing cookies?
Comment 8 Christopher Guindon CLA 2019-02-19 16:14:36 EST
(In reply to Christopher Guindon from comment #7)
> I am re-opening this bug because of the following comment in my inbox from
> Christian:
> 
> when the user is logged in, i.e. session cookies are sent along, the
> eclipsecon_scheduled_sessions service responds with "Cache-Control →
> no-cache [...]" and respectively without "ETag" and "Last-Modified" headers.
> 
> Would it be possible to enable caching on the service for requests
> containing cookies?

Our new API has better support for this:
https://www.eclipsecon.org/api/sessions

There is no reason to include a session cookie to fetch this data.