Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Langtag download issue 987 #1232

Open
wants to merge 5 commits into
base: master
Choose a base branch
from

Conversation

elisunger
Copy link
Collaborator

@elisunger elisunger commented Oct 14, 2022

This change is Reviewable

@ermshiperete ermshiperete linked an issue Oct 14, 2022 that may be closed by this pull request
SIL.WritingSystems/Sldr.cs Show resolved Hide resolved
{
etag = File.ReadAllText(etagPath);
currentEtag = webResponse.Headers.Get("Etag");
if (etag == "")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No need to check for empty etag after we got the Etag header. You can unconditionally write the new value (but maybe do it in the webResponse.StatusCode != HttpStatusCode.NotModified block).

Comment on lines 427 to 491
else
sinceTime = fileTime;
}
sinceTime += TimeSpan.FromSeconds(1);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Since we don't send sinceTime to the server, we no longer need that variable here - we only need it above in line 419 so that we can compare it to fileTime.

{
LoadLanguageTagsIfNecessary();
if (downloadLangTags) LoadLanguageTags();
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should download the tags before we call LoadLanguageTagsIfNecessary

webRequest.Timeout = 10000;
webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using var webResponse = (HttpWebResponse) webRequest.GetResponse();
public static void LoadLanguageTags()
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We now have two methods with almost identical names (LoadLanguageTags and LoadLanguageTagsIfNecessary) which do different things which is confusing. Maybe rename this method to DownloadLanguageTags?

Copy link
Member

@ermshiperete ermshiperete left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're getting closer. There are a few things that still need to be changed.

I also added some unit tests that you can use to debug and verify the correct behavior. You'll have to run git pull [email protected]:elisunger/libpalaso.git --rebase langtagDownload-issue-987 to get them.

if (File.Exists(etagPath))
{
etag = File.ReadAllText(etagPath);
webRequest.Headers.Set(etag, "If-None-Match");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is backwards. etag is the value, "If-None-Match" the key.

Suggested change
webRequest.Headers.Set(etag, "If-None-Match");
webRequest.Headers.Set("If-None-Match", etag);

webRequest.Timeout = 10000;
webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using var webResponse = (HttpWebResponse)webRequest.GetResponse();
if (File.Exists(etagPath))
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You'll also have to check for the existence of langtags.json file - it's possible that langtags.json.etag exists but langtags.json doesn't (e.g. it gets renamed if it contains corrupt content).

{
//File.WriteAllText(etagPath, currentEtag);
//webRequest.Headers.Set(etag, "If-None-Match");
if (webResponse.StatusCode != HttpStatusCode.NotModified)
Copy link
Member

@ermshiperete ermshiperete Nov 14, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The status code should be checked directly after calling webRequest.GetResponse(). If we get a status code other than OK we can return right away: either it's NotModified in which case we don't have to do anything, or we get an error in which case the data we got is not valid, so we can't do anything with it either.

In all cases I saw in my testing we got a WebException instead of a non-OK status code, but since the code comment says we might get a NotModified status code it safer to check it.

File.WriteAllText(etagPath, currentEtag);
using Stream output = File.OpenWrite(cachedAllTagsPath);
using var input = webResponse.GetResponseStream();
input.CopyTo(output);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's possible that webResponse.GetResponseStream() returns null, so you should check for null here. This can be easiest done as:

Suggested change
input.CopyTo(output);
input?.CopyTo(output);

Comment on lines 507 to 508
if (_offlineMode)
throw new WebException("Test mode: SLDR offline so accessing cache", WebExceptionStatus.ConnectFailure);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These two lines can go directly below CreateSldrCacheDirectory().

SIL.WritingSystems/Sldr.cs Show resolved Hide resolved
webRequest.Timeout = 10000;
webRequest.AutomaticDecompression = DecompressionMethods.GZip | DecompressionMethods.Deflate;
using var webResponse = (HttpWebResponse)webRequest.GetResponse();
if (webResponse.StatusCode != "OK")
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

StatusCode returns an enum, so you can't compare to string:

Suggested change
if (webResponse.StatusCode != "OK")
if (webResponse.StatusCode != HttpStatusCode.OK)

var langtagsUrl =
$"{SldrRepository}index.html?query=langtags&ext=json{StagingParameter}";
var webRequest = (HttpWebRequest)WebRequest.Create(Uri.EscapeUriString(langtagsUrl));
webRequest.Headers.Set("If-None-Match", etag);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The compiler doesn't like this line and fails with Error CS0165 : Use of unassigned local variable 'etag'. You should read etagPath before this line (you can copy lines 525 and 527).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Improve how SLDR downloads langtag.json file
2 participants