Server: Enhance caching capabilities for capabilities-endpoint

Created on 27 Apr 2020  路  8Comments  路  Source: nextcloud/server

How to use GitHub

  • Please use the 馃憤 reaction to show that you are interested into the same feature.
  • Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
  • Subscribe to receive notifications on status change and new comments.

Is your feature request related to a problem? Please describe.

Feature Request

The capabilities-endpoint () is a quiet important endpoint for nearly every app that integrates with a Nextcloud instance. It is used for applying theming, detecting active apps and supported API versions, hence it is important for clients to keep it up to date.

Though it looks like this endpoint does not support ETags. This means for 3rd party clients (e. g. Android apps) that each request transfers the complete JSON-response. This means that every client has to transfer (at the sample of my small cloud with only a few apps) 3.1 kB each and every time a request is made.

Describe the solution you'd like

This is a request to implement ETags and If-None-Match headers which allow the 3rd party applications to safely cache the response and only download the payload if it is actually needed. Especially mobile applications with a limited data quota will profilt enormously.

Describe alternatives you've considered
Well, proceeding like now, sucking each users mobile data quota :laughing:

Additional context
Sample response headers from the capabilities-endpoint (Missing ETag-Header):

HTTP/1.1 200 OK
Date: Mon, 27 Apr 2020 17:03:36 GMT
Server: Apache
X-Powered-By: PHP/7.3.17
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Pragma: no-cache
Cache-Control: no-cache, no-store, must-revalidate
Content-Security-Policy: default-src 'none';base-uri 'none';manifest-src 'self'
Feature-Policy: autoplay 'none';camera 'none';fullscreen 'none';geolocation 'none';microphone 'none';payment 'none'
Set-Cookie: oc_sessionPassphrase=xxxxxx; path=/; secure; HttpOnly
Set-Cookie: __Host-nc_sameSiteCookielax=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=lax
Set-Cookie: __Host-nc_sameSiteCookiestrict=true; path=/; httponly;secure; expires=Fri, 31-Dec-2100 23:59:59 GMT; SameSite=strict
Set-Cookie: ocqot8q2lp2m=g89qbvr49l7ei9grsfc752isdq; path=/; secure; HttpOnly
Set-Cookie: cookie_test=test; expires=Mon, 27-Apr-2020 18:03:36 GMT; Max-Age=3600
Referrer-Policy: no-referrer
X-Content-Type-Options: nosniff
X-Download-Options: noopen
X-Frame-Options: SAMEORIGIN
X-Permitted-Cross-Domain-Policies: none
X-Robots-Tag: none
X-XSS-Protection: 1; mode=block
Content-Length: 3126
Content-Type: application/json; charset=utf-8
0. Needs triage enhancement

Most helpful comment

Fair point. I can look into that.

All 8 comments

Fair point. I can look into that.

Technically the server would need to gather the response (like it already does) and hash it.

given an If-None-Match header is present in the request:

  • If the calculated hash matches the value of the If-None-Match header send status code 304 without any payload
  • If the calculated hash does not match the value of the If-None-Match header send response like today and add the calculated hash as value for an ETag header

given no If-None-Match header is present in the request:

send response like today and add the calculated hash as value for an ETag header

Technically the server would need to gather the response (like it already does) and hash it.

Not per se. The etag can also be calculated in other ways. For example if you return a file don't start hashing the content. Just use the etag we already have etc. But yes for text responses a quick hash would be a good idea I guess.

A simple middle ware to handle this would already work I guess.
@kesselb feel free to look into it :)

@rullzer how will the capabilities-endpoint get notified when another server app (like Notes or Deck) change their entry? For example provide other API versions or change something else?

I think @tobiasKaminsky mentioned that this is not possible yet, therefore is suggested to gather and hash the response.

Sorry I didn't mean to confuse things. Yes in this case hashing it makes sense. I just meant lets not do that for all responses as it might create a lot of overhead.

So did i understand you correctly: you mean you want to cache the capabilities endpoint based on time? That might cause issues, e.g. when maintenance mode is turned on but according to the capabilities endpoint it is still switched off.

Aah, @rullzer with "all responses" you didn't mean "each response for this endpoint" but "responses from other endpoints", right? :question: :laughing: confused

So, we have a working solution. It's up to you to decide whether or not it's worth to calculate the hash.

Pro: Less mobile data (Files, Notes, Deck, Passwords, Bookmarks, Talk - they all could profit from this change)

Contra: More work for the server (I can't estimate how bad it is for the server to hash the response of the capabilities-endpoint on each request)

Was this page helpful?
0 / 5 - 0 ratings