-
-
Notifications
You must be signed in to change notification settings - Fork 3.1k
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
Respect expires header when checking for new versions #5474
Conversation
Looks good to me.
|
Right, right there was something about that in the issue... Completly forgot about that 😅
As in static? |
@TheAssassin Anything against using the With that one the app can calculate the expiry datetime itself. During this calculation it can take into account the lower/upper limits. So i only have to save a single preference and as a whole i think the code is cleaner because of less if conditions to check |
Citing @TheAssassin from #5467
|
@XiangRongLin I don't really care. I remembered Just let me know which one you want to use, we can set up either of them. But if you go with Usually, both are set anyway by webservers. Browsers, which implement a proper parser, usually prefer Edit: yes, I'd go for a 6 hours lower boundary. That's more than good enough. |
|
return null; | ||
} | ||
|
||
final String expire = prefs.getString(app.getString(R.string.update_expire_date_key), null); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You should add more comments to your code. NewPipe is pretty bad at this. Please check out https://standards.mousepawmedia.com/csi.html.
Here, you could like above state that you check whether a timeout has been met already.
It does seem a bit wasteful to always re-parse the string. But I presume it's just easier to do that, so you can conveniently use isAfter
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It does seem a bit wasteful to always re-parse the string. But I presume it's just easier to do that, so you can conveniently use isAfter
When i added a log statement to the new version check it is only run at startup of the app and not on rotation, meaning very rarely. Is the tradeof of using a little bit more ram constantly compared to a little bit of cpu once good?
@B0pol How did you come to think thats it's run on device rotation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As said, I don't mind this. In fact, I probably reconstructed your thinking.
It was an example of what kind of comment is missing there. I can see what you are doing, but only guess why you are doing it like that. It showcases perfectly why CSI matters.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@XiangRongLin I was wrong about device rotation, it is the case for MainFragment, MainActivity and many other classes .onCreate() methods, but not App.onCreate()
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to write the code in a way that does not require comments. In that case maybe add a seperate method with a name, which makes the comment not needed.
I did not do it here at first, since the issue was labelled as ASAP
. But i forgot that i have time until at least saturday when the release needs to be done
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I prefer to write the code in a way that does not require comments. In that case maybe add a seperate method with a name, which makes the comment not needed.
This is just not possible. And very much not a matter of preference.
Do I really have to quote CSI? You don't seem to have had a look:
“Self-Commenting Code” is a practice wherein a code’s functionality is self-evident. Through naming, structure, and various other techniques, the immediate purpose becomes obvious to the reader. This is beneficial in any language.
However, “Self-Commenting Code” is seldom capable of expressing the entire intent, or “why”, of the code.
It is nearly impossible to express the intended behavior of the code;
-- https://standards.mousepawmedia.com/csi.html#csi-vs-self-commenting-code
Again, your code tells nothing about why you're doing it like that. It cost me valuable time guess the why, and that's then still just a guess.
In practice, intent-commenting saves me considerably more time than it takes! It's a true investment in the future: an extra 10-20 minutes now saves me literal hours later.
-- https://dev.to/codemouse92/to-comment-or-not-to-comment-3f7h
The entire implementation looks very, very basic. I'd recommend to at least check the HTTP status. Anything other than 200 can be considered an error. You don't have to attempt to parse JSON from plain text. It makes no sense. Also, I miss a lot of error handling in there. You make a lot of assumptions about how the JSON has to look. Does that JSON parser exception also show up when a certain key is missing in there? I'm not so sure. The code also lacks a lot of comments that explain what you're trying to accomplish there, and especially why. I recommend most people to read https://standards.mousepawmedia.com/csi.html. CSI is usually perceived as a bit overkill with regards to the amount of comments. But in general, I very much agree with the author's arguments. I try to implement form of "CSI light" in all my projects. That makes them a lot more beginner friendly. |
It was called to many times and acted similar to a DOS attack.
db255b7
to
2926cb7
Compare
app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
Outdated
Show resolved
Hide resolved
When it's expired it means, that the app should get the data. Meaning it should not abort prematurely by returning null. Co-authored-by: Tobias Groza <TobiGr@users.noreply.github.com>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree with @TheAssassin that there should be a basic status code check.
E.g. when there is an internal server error, we should not check back the next time the method is called, but also implement a short cooldown of e.g. 10 min.
Depending on how much time you have to implement this, we could also ship this improvement with the next update.
I've also suggested two comments to clarify why we check and store expiry.
@TobiGr |
Co-authored-by: Tobias Groza <TobiGr@users.noreply.github.com>
I don't have permission to push to this branch, will open a new PR which adds an one hour cooldown when there are server side or connectivity problems: diff --git a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
index 63baef5479..11be734ae9 100644
--- a/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
+++ b/app/src/main/java/org/schabi/newpipe/CheckForNewAppVersion.java
@@ -10,19 +10,22 @@ import android.content.pm.Signature;
import android.net.ConnectivityManager;
import android.net.Uri;
import android.util.Log;
+
import androidx.annotation.NonNull;
import androidx.annotation.Nullable;
import androidx.core.app.NotificationCompat;
import androidx.core.app.NotificationManagerCompat;
import androidx.core.content.ContextCompat;
import androidx.preference.PreferenceManager;
+
import com.grack.nanojson.JsonObject;
import com.grack.nanojson.JsonParser;
import com.grack.nanojson.JsonParserException;
-import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
-import io.reactivex.rxjava3.core.Maybe;
-import io.reactivex.rxjava3.disposables.Disposable;
-import io.reactivex.rxjava3.schedulers.Schedulers;
+
+import org.schabi.newpipe.report.ErrorActivity;
+import org.schabi.newpipe.report.ErrorInfo;
+import org.schabi.newpipe.report.UserAction;
+
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.security.MessageDigest;
@@ -31,9 +34,13 @@ import java.security.cert.CertificateEncodingException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
-import org.schabi.newpipe.report.ErrorActivity;
-import org.schabi.newpipe.report.ErrorInfo;
-import org.schabi.newpipe.report.UserAction;
+import java.time.Instant;
+import java.time.temporal.ChronoUnit;
+
+import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
+import io.reactivex.rxjava3.core.Maybe;
+import io.reactivex.rxjava3.disposables.Disposable;
+import io.reactivex.rxjava3.schedulers.Schedulers;
public final class CheckForNewAppVersion {
private CheckForNewAppVersion() { }
@@ -236,10 +243,17 @@ public final class CheckForNewAppVersion {
}
},
e -> {
- // connectivity problems, do not alarm user and fail silently
+ // connectivity or server side problems
+ // do not alarm user and fail silently
if (DEBUG) {
Log.w(TAG, "Could not get NewPipe API: network problem", e);
}
+ // wait at least an hour before making the next attempt to get API data
+ final long newExpiry = Instant.now()
+ .plus(1, ChronoUnit.HOURS).getEpochSecond();
+ prefs.edit()
+ .putLong(app.getString(R.string.update_expiry_key), newExpiry)
+ .apply();
});
}
} |
…_header Respect expires header when checking for new versions
What is it?
Description of the changes in your PR
Fixes the following issue(s)
Due diligence
I'd to do some refactoring and add some test if time permitts.
APK
https://github.com/XiangRongLin/NewPipe/actions/runs/501846770
XiangRongLin#10
this apk ignores usual checks for when to run the request