dropbox-sdk-dotnet icon indicating copy to clipboard operation
dropbox-sdk-dotnet copied to clipboard

How to use eTags

Open Bananas-Are-Yellow opened this issue 1 year ago • 1 comments

According to the Dropbox for HTTP Developers documentation:

These endpoints also support HTTP GET along with ETag-based caching (If-None-Match) ...

ETags are returned for certain calls, and DownloadAsync is one of them.

Dropbox API v2 does not give me access to the request headers or the response headers, but according to this forum post, the eTag value can be found in the rev property. Well almost, you have to prefix it with the weak eTag validator prefix:

  • rev: "5f99c43bf6a930044b034"
  • ETag: W/"5f99c43bf6a930044b034"

That value is the rev (and hence the eTag) for /path/to/file.txt in my Dropbox folder.

Using curl, I can verify that If-None-Match: W/"5f99c43bf6a930044b034" does indeed work:

curl -i -X POST https://content.dropboxapi.com/2/files/download \
    --header 'Authorization: Bearer ...' \
    --header 'Dropbox-API-Arg: {"path":"/path/to/file.txt}' \
    --header 'If-None-Match: W/"5f99c43bf6a930044b034"'

HTTP/1.1 304 Not Modified
Content-Security-Policy: sandbox allow-forms allow-scripts
Etag: W/"5f99c43bf6a930044b034"
Content-Type: application/json
Accept-Encoding: identity,gzip
Date: Tue, 25 Jul 2023 16:05:29 GMT
Server: envoy
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
X-Robots-Tag: noindex, nofollow, noimageindex
Vary: Accept-Encoding
X-Dropbox-Response-Origin: far_remote
X-Dropbox-Request-Id: 39f2e29e01f94a9c96bc17e8f05d98f0

This correctly returns 304 Not Modified and avoids downloading the content which has not changed.

How can I do this using Dropbox API v2? The only way I can think of is to make two calls:

  • Call GetMetadataAsync to get the rev property.
  • Compare this to my stored eTag to see if the rev has changed.
  • If changed, call DownloadAsync to get the new contents.

But the whole point of If-None-Match is to avoid making two calls!

I could use the HttpClient directly and set If-None-Match in the request header myself, but this means I will not get the automatic refreshing of the access token which takes place in DropboxRequestHandler.

Thanks.

Bananas-Are-Yellow avatar Jul 25 '23 16:07 Bananas-Are-Yellow

Thanks for writing this up! You have this correct, the Dropbox .NET SDK doesn't currently support setting If-None-Match unfortunately, so you'd need to make the multiple calls, which would be less efficient. I'll pass this along as a feature request, but I can't promise if or when that might be implemented.

By the way, if you haven't already, check out the Detecting Changes Guide, which covers some other strategies for following changes relatively efficiently which might be helpful, depending on your use case.

greg-db avatar Jul 25 '23 17:07 greg-db