Move redirect handling to DownloadService

- Only redirects when feed was parsed successfully (captive portals)
- Decouple http client from database
This commit is contained in:
ByteHamster 2022-04-01 22:56:21 +02:00
parent 3b47deb705
commit bd6798d2af
4 changed files with 26 additions and 37 deletions

View File

@ -6,20 +6,14 @@ import androidx.annotation.NonNull;
import de.danoeh.antennapod.core.preferences.UserPreferences; import de.danoeh.antennapod.core.preferences.UserPreferences;
import de.danoeh.antennapod.core.service.BasicAuthorizationInterceptor; import de.danoeh.antennapod.core.service.BasicAuthorizationInterceptor;
import de.danoeh.antennapod.core.service.UserAgentInterceptor; import de.danoeh.antennapod.core.service.UserAgentInterceptor;
import de.danoeh.antennapod.core.storage.DBWriter;
import de.danoeh.antennapod.net.ssl.SslClientSetup; import de.danoeh.antennapod.net.ssl.SslClientSetup;
import okhttp3.Cache; import okhttp3.Cache;
import okhttp3.Credentials; import okhttp3.Credentials;
import okhttp3.HttpUrl;
import okhttp3.JavaNetCookieJar; import okhttp3.JavaNetCookieJar;
import okhttp3.OkHttpClient; import okhttp3.OkHttpClient;
import okhttp3.Request;
import okhttp3.Response;
import okhttp3.internal.http.StatusLine;
import java.io.File; import java.io.File;
import java.net.CookieManager; import java.net.CookieManager;
import java.net.CookiePolicy; import java.net.CookiePolicy;
import java.net.HttpURLConnection;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
import java.net.Proxy; import java.net.Proxy;
import java.net.SocketAddress; import java.net.SocketAddress;
@ -69,36 +63,6 @@ public class AntennapodHttpClient {
System.setProperty("http.maxConnections", String.valueOf(MAX_CONNECTIONS)); System.setProperty("http.maxConnections", String.valueOf(MAX_CONNECTIONS));
OkHttpClient.Builder builder = new OkHttpClient.Builder(); OkHttpClient.Builder builder = new OkHttpClient.Builder();
// detect 301 Moved permanently and 308 Permanent Redirect
builder.networkInterceptors().add(chain -> {
Request request = chain.request();
Response response = chain.proceed(request);
if (response.code() == HttpURLConnection.HTTP_MOVED_PERM
|| response.code() == StatusLine.HTTP_PERM_REDIRECT) {
String location = response.header("Location");
if (location == null) {
return response;
}
if (location.startsWith("/")) { // URL is not absolute, but relative
HttpUrl url = request.url();
location = url.scheme() + "://" + url.host() + location;
} else if (!location.toLowerCase().startsWith("http://")
&& !location.toLowerCase().startsWith("https://")) {
// Reference is relative to current path
HttpUrl url = request.url();
String path = url.encodedPath();
String newPath = path.substring(0, path.lastIndexOf("/") + 1) + location;
location = url.scheme() + "://" + url.host() + newPath;
}
try {
DBWriter.updateFeedDownloadURL(request.url().toString(), location).get();
} catch (Exception e) {
Log.e(TAG, Log.getStackTraceString(e));
}
}
return response;
});
builder.interceptors().add(new BasicAuthorizationInterceptor()); builder.interceptors().add(new BasicAuthorizationInterceptor());
builder.networkInterceptors().add(new UserAgentInterceptor()); builder.networkInterceptors().add(new UserAgentInterceptor());

View File

@ -335,6 +335,9 @@ public class DownloadService extends Service {
// Was stored in the database before and not initiated manually // Was stored in the database before and not initiated manually
newEpisodesNotification.showIfNeeded(DownloadService.this, task.getSavedFeed()); newEpisodesNotification.showIfNeeded(DownloadService.this, task.getSavedFeed());
} }
if (downloader.permanentRedirectUrl != null) {
DBWriter.updateFeedDownloadURL(request.getSource(), downloader.permanentRedirectUrl);
}
} else { } else {
DBWriter.setFeedLastUpdateFailed(request.getFeedfileId(), true); DBWriter.setFeedLastUpdateFailed(request.getFeedfileId(), true);
saveDownloadStatus(task.getDownloadStatus()); saveDownloadStatus(task.getDownloadStatus());

View File

@ -18,8 +18,8 @@ public abstract class Downloader implements Callable<Downloader> {
private static final String TAG = "Downloader"; private static final String TAG = "Downloader";
private volatile boolean finished; private volatile boolean finished;
public volatile boolean cancelled; public volatile boolean cancelled;
public String permanentRedirectUrl = null;
@NonNull @NonNull
final DownloadRequest request; final DownloadRequest request;

View File

@ -7,6 +7,7 @@ import android.util.Log;
import de.danoeh.antennapod.core.util.NetworkUtils; import de.danoeh.antennapod.core.util.NetworkUtils;
import de.danoeh.antennapod.model.download.DownloadStatus; import de.danoeh.antennapod.model.download.DownloadStatus;
import okhttp3.CacheControl; import okhttp3.CacheControl;
import okhttp3.internal.http.StatusLine;
import org.apache.commons.io.IOUtils; import org.apache.commons.io.IOUtils;
import java.io.BufferedInputStream; import java.io.BufferedInputStream;
@ -19,6 +20,7 @@ import java.net.HttpURLConnection;
import java.net.SocketTimeoutException; import java.net.SocketTimeoutException;
import java.net.URI; import java.net.URI;
import java.net.UnknownHostException; import java.net.UnknownHostException;
import java.util.ArrayList;
import java.util.Collections; import java.util.Collections;
import java.util.Date; import java.util.Date;
@ -173,6 +175,7 @@ public class HttpDownloader extends Downloader {
return; return;
} }
} }
checkIfRedirect(response);
connection = new BufferedInputStream(responseBody.byteStream()); connection = new BufferedInputStream(responseBody.byteStream());
@ -279,6 +282,25 @@ public class HttpDownloader extends Downloader {
} }
} }
private void checkIfRedirect(Response response) {
// detect 301 Moved permanently and 308 Permanent Redirect
ArrayList<Response> responses = new ArrayList<>();
while (response != null) {
responses.add(response);
response = response.priorResponse();
}
if (responses.isEmpty()) {
return;
}
Collections.reverse(responses);
int firstCode = responses.get(0).code();
if (firstCode == HttpURLConnection.HTTP_MOVED_PERM || firstCode == StatusLine.HTTP_PERM_REDIRECT) {
String secondUrl = responses.get(1).request().url().toString();
Log.d(TAG, "Detected permanent redirect from " + request.getSource() + " to " + secondUrl);
permanentRedirectUrl = secondUrl;
}
}
private void onSuccess() { private void onSuccess() {
Log.d(TAG, "Download was successful"); Log.d(TAG, "Download was successful");
result.setSuccessful(); result.setSuccessful();