From a336f6be891c514ecc6b38dc23473bdbd4f90514 Mon Sep 17 00:00:00 2001 From: Grishka Date: Tue, 15 Nov 2022 15:16:58 +0400 Subject: [PATCH] Support domain redirects via `/.well-known/host-meta` Closes #312 --- .../onboarding/InstanceCatalogFragment.java | 148 +++++++++++++++--- 1 file changed, 123 insertions(+), 25 deletions(-) diff --git a/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/InstanceCatalogFragment.java b/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/InstanceCatalogFragment.java index 863ecf03..19f9bb20 100644 --- a/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/InstanceCatalogFragment.java +++ b/mastodon/src/main/java/org/joinmastodon/android/fragments/onboarding/InstanceCatalogFragment.java @@ -1,5 +1,6 @@ package org.joinmastodon.android.fragments.onboarding; +import android.app.Activity; import android.app.ProgressDialog; import android.content.Context; import android.net.Uri; @@ -9,6 +10,7 @@ import android.os.LocaleList; import android.text.Editable; import android.text.TextUtils; import android.text.TextWatcher; +import android.util.Log; import android.view.KeyEvent; import android.view.View; import android.view.ViewGroup; @@ -21,6 +23,7 @@ import android.widget.RadioButton; import android.widget.TextView; import org.joinmastodon.android.R; +import org.joinmastodon.android.api.MastodonAPIController; import org.joinmastodon.android.api.MastodonAPIRequest; import org.joinmastodon.android.api.MastodonErrorResponse; import org.joinmastodon.android.api.requests.instance.GetInstance; @@ -36,7 +39,13 @@ import org.joinmastodon.android.ui.M3AlertDialogBuilder; import org.joinmastodon.android.ui.tabs.TabLayout; import org.joinmastodon.android.ui.utils.UiUtils; import org.parceler.Parcels; +import org.w3c.dom.Document; +import org.w3c.dom.Element; +import org.w3c.dom.Node; +import org.w3c.dom.NodeList; +import org.xml.sax.InputSource; +import java.io.IOException; import java.net.IDN; import java.util.ArrayList; import java.util.Collections; @@ -46,6 +55,8 @@ import java.util.List; import java.util.Map; import java.util.stream.Collectors; +import javax.xml.parsers.DocumentBuilderFactory; + import androidx.annotation.NonNull; import androidx.recyclerview.widget.DiffUtil; import androidx.recyclerview.widget.RecyclerView; @@ -58,6 +69,9 @@ import me.grishka.appkit.utils.MergeRecyclerAdapter; import me.grishka.appkit.utils.SingleViewRecyclerAdapter; import me.grishka.appkit.utils.V; import me.grishka.appkit.views.UsableRecyclerView; +import okhttp3.Call; +import okhttp3.Request; +import okhttp3.Response; public class InstanceCatalogFragment extends BaseRecyclerFragment{ private InstancesAdapter adapter; @@ -75,9 +89,11 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment categories=new ArrayList<>(); private String loadingInstanceDomain; private GetInstance loadingInstanceRequest; + private Call loadingInstanceRedirectRequest; private HashMap instancesCache=new HashMap<>(); private ProgressDialog instanceProgressDialog; private View buttonBar; + private HashMap redirects=new HashMap<>(), redirectsInverse=new HashMap<>(); private boolean isSignup; @@ -271,7 +287,7 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment{ - if(loadingInstanceRequest!=null){ - loadingInstanceRequest.cancel(); - loadingInstanceRequest=null; - loadingInstanceDomain=null; - } - }); + instanceProgressDialog.setOnCancelListener(dialog->cancelLoadingInstanceInfo()); instanceProgressDialog.show(); } @@ -429,10 +439,12 @@ public class InstanceCatalogFragment extends BaseRecyclerFragmentshowInstanceInfoLoadError(domain, e)); + } + + @Override + public void onResponse(@NonNull Call call, @NonNull Response response) throws IOException{ + loadingInstanceRedirectRequest=null; + loadingInstanceDomain=null; + Activity a=getActivity(); + if(a==null) + return; + try(response){ + if(!response.isSuccessful()){ + a.runOnUiThread(()->showInstanceInfoLoadError(domain, response.code()+" "+response.message())); + return; + } + InputSource source=new InputSource(response.body().charStream()); + Document doc=DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(source); + NodeList list=doc.getElementsByTagName("Link"); + for(int i=0;iloadInstanceInfo(redirectDomain, true)); + return; + } + } + } + a.runOnUiThread(()->showInstanceInfoLoadError(domain, origError)); + }catch(Exception x){ + a.runOnUiThread(()->showInstanceInfoLoadError(domain, x)); + } + } + }); + } + @Override public void onApplyWindowInsets(WindowInsets insets){ if(Build.VERSION.SDK_INT>=27){ @@ -580,7 +678,7 @@ public class InstanceCatalogFragment extends BaseRecyclerFragment