0

In my C# code with the Graph SDK, I am testing "download large file" with a method generously provided here: Download large files from OneDrive using Microsoft Graph SDK

However, even though I explicitly request the DriveItem from the service just prior to calling this method (which then uses the downloadUrl from the AdditionalData in the DriveItem), I am getting a response indicating JWT Token Expired.

I assume this token is embedded in the pre-authenticated downloadUrl. Further, I theorize that this token is either single-use or it expires relatively quickly...both reasons for me to explicitly request the DriveItem just before attempting to utilize that URL.

How do I ensure that the service is sending me back a "fresh" downloadUrl? Are there some no-cache headers or something I should explicitly include in my DriveItem request?

As mentioned, even though I have the DriveItem object local, I am explicitly re-fetching it from the service to ensure I have the latest properties, and a new downloadUrl. (But this is not working.) Using the Request object without any extra Headers (or other odata parameters) is apparently not enough to trigger the generation of a new URL.

This does not happen every test. I believe it happens when re-running a test with the same DriveItem in a short time-window. Again, I'm not sure if the JWT token is single-use or time-expired, but if it's expired in any case, I think the service should automatically generate a new one. If that's not practical, just understanding how to explicitly ask for a new one is certainly effective too!

AWeber
  • 381
  • 1
  • 3
  • 14
  • 1
    Are you including the `Authorization` header when attempting to download the file? – Marc LaFleur Feb 07 '19 at 21:31
  • 1
    No, sir. According to this page, https://learn.microsoft.com/en-us/graph/api/driveitem-get-content?view=graph-rest-1.0 I should not do so. – AWeber Feb 07 '19 at 22:12

1 Answers1

2

Continuing to debug and try different things, I believe I have found the answer to my question...

Sending a known-false ETag in the request for the DriveItem seems to force the service to send me a new copy. Example code as follows:

//we need a "recent" copy of this object, because the downloadURL is only good for a limited time...
IList<HeaderOption> opts = new List<HeaderOption>();
opts.Add(new HeaderOption("Cache-Control", "no-cache, no-store"));
opts.Add(new HeaderOption("if-none-match", "xyz")); //never match

DriveItem item = await client.Me.Drive.Items[Id].Request(opts).GetAsync();
if (item == null)
{
    log.Warn("Could not fetch existing driveItem? " + Id);
    return null;
}

object downloadUrl = null;
item.AdditionalData?.TryGetValue(@"@microsoft.graph.downloadUrl", out downloadUrl);

I am still testing this, but initial tests show it to work. I will update this answer when my testing is reasonably conclusive.

Still "bonus points" for anyone who can identify the specific expiration of these URLs (time, number of uses, etc.). Then we can actually check locally whether our object is "stale" and only re-fetch when necessary.

AWeber
  • 381
  • 1
  • 3
  • 14