Skip to content

Commit 962fc35

Browse files
Removed Android Hybrid Composition constraint to use the pull-to-refresh feature, Removed Android com.squareup.okhttp3:okhttp dependency
1 parent b82baaa commit 962fc35

File tree

9 files changed

+164
-99
lines changed

9 files changed

+164
-99
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
## 6.0.0-beta.16
2+
3+
- Removed Android Hybrid Composition constraint to use the pull-to-refresh feature
4+
- Removed Android `com.squareup.okhttp3:okhttp` dependency
5+
16
## 6.0.0-beta.15
27

38
- Automatically infer `useShouldOverrideUrlLoading`, `useOnLoadResource`, `useOnDownloadStart`, `useShouldInterceptAjaxRequest`, `useShouldInterceptFetchRequest`, `useShouldInterceptRequest`, `useOnRenderProcessGone`, `useOnNavigationResponse` settings if their value is `null` and the corresponding event is implemented by the WebView (`InAppWebView` and `HeadlessInAppWebView`, not `InAppBrowser`) before it's native initialization
@@ -145,6 +150,10 @@
145150
- Removed `URLProtectionSpace.iosIsProxy` property
146151
- `historyUrl` and `baseUrl` of `InAppWebViewInitialData` can be `null`
147152

153+
## 5.7.2
154+
155+
- Removed Android Hybrid Composition constraint to use the pull-to-refresh feature
156+
148157
## 5.7.1+2
149158

150159
- Fixed Android `NullPointerException` on `InAppBrowserActivity.dispose`

android/build.gradle

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,6 @@ android {
4848
implementation 'androidx.webkit:webkit:1.5.0'
4949
implementation 'androidx.browser:browser:1.4.0'
5050
implementation 'androidx.appcompat:appcompat:1.5.1'
51-
implementation 'com.squareup.okhttp3:okhttp:3.14.9'
5251
implementation 'androidx.swiperefreshlayout:swiperefreshlayout:1.1.0'
5352
}
5453
}

android/src/main/java/com/pichillilorenzo/flutter_inappwebview/Util.java

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,10 @@
3333
import java.io.InputStream;
3434
import java.lang.reflect.InvocationTargetException;
3535
import java.lang.reflect.Method;
36+
import java.net.HttpURLConnection;
3637
import java.net.Inet6Address;
3738
import java.net.InetAddress;
39+
import java.net.URL;
3840
import java.net.UnknownHostException;
3941
import java.security.Key;
4042
import java.security.KeyStore;
@@ -47,18 +49,11 @@
4749
import java.util.List;
4850
import java.util.Map;
4951
import java.util.Objects;
50-
import java.util.concurrent.TimeUnit;
5152
import java.util.regex.Pattern;
5253

53-
import javax.net.ssl.HostnameVerifier;
54-
import javax.net.ssl.SSLContext;
55-
import javax.net.ssl.SSLSession;
56-
import javax.net.ssl.SSLSocketFactory;
57-
import javax.net.ssl.TrustManager;
58-
import javax.net.ssl.X509TrustManager;
54+
import javax.net.ssl.SSLHandshakeException;
5955

6056
import io.flutter.plugin.common.MethodChannel;
61-
import okhttp3.OkHttpClient;
6257

6358
public class Util {
6459

@@ -171,12 +166,38 @@ public PrivateKeyAndCertificates(PrivateKey privateKey, X509Certificate[] certif
171166
}
172167
}
173168

174-
public static OkHttpClient getBasicOkHttpClient() {
175-
return new OkHttpClient.Builder()
176-
.connectTimeout(15, TimeUnit.SECONDS)
177-
.writeTimeout(15, TimeUnit.SECONDS)
178-
.readTimeout(15, TimeUnit.SECONDS)
179-
.build();
169+
@Nullable
170+
public static HttpURLConnection makeHttpRequest(String urlString, String method, @Nullable Map<String, String> headers) {
171+
HttpURLConnection urlConnection = null;
172+
try {
173+
URL url = new URL(urlString);
174+
urlConnection = (HttpURLConnection) url.openConnection();
175+
urlConnection.setRequestMethod(method);
176+
if (headers != null) {
177+
for (Map.Entry<String, String> header : headers.entrySet()) {
178+
urlConnection.setRequestProperty(header.getKey(), header.getValue());
179+
}
180+
}
181+
urlConnection.setConnectTimeout(15000); // 15 seconds
182+
urlConnection.setReadTimeout(15000); // 15 seconds
183+
urlConnection.setDoInput(true);
184+
urlConnection.setInstanceFollowRedirects(true);
185+
if ("GET".equalsIgnoreCase(method)) {
186+
urlConnection.setDoOutput(false);
187+
}
188+
urlConnection.connect();
189+
return urlConnection;
190+
}
191+
catch (Exception e) {
192+
if (!(e instanceof SSLHandshakeException)) {
193+
e.printStackTrace();
194+
Log.e(LOG_TAG, e.getMessage());
195+
}
196+
if (urlConnection != null) {
197+
urlConnection.disconnect();
198+
}
199+
}
200+
return null;
180201
}
181202

182203
/**

android/src/main/java/com/pichillilorenzo/flutter_inappwebview/content_blocker/ContentBlockerHandler.java

Lines changed: 108 additions & 65 deletions
Original file line numberDiff line numberDiff line change
@@ -2,32 +2,34 @@
22

33
import android.os.Build;
44
import android.os.Handler;
5+
import android.text.TextUtils;
56
import android.util.Log;
67
import android.webkit.WebResourceResponse;
78

89
import androidx.annotation.Nullable;
910

10-
import com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview.InAppWebView;
11-
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
1211
import com.pichillilorenzo.flutter_inappwebview.Util;
12+
import com.pichillilorenzo.flutter_inappwebview.plugin_scripts_js.JavaScriptBridgeJS;
13+
import com.pichillilorenzo.flutter_inappwebview.types.WebResourceRequestExt;
14+
import com.pichillilorenzo.flutter_inappwebview.webview.in_app_webview.InAppWebView;
1315

1416
import java.io.ByteArrayInputStream;
1517
import java.io.InputStream;
18+
import java.net.HttpURLConnection;
1619
import java.net.MalformedURLException;
1720
import java.net.URI;
1821
import java.net.URISyntaxException;
1922
import java.net.URL;
2023
import java.util.ArrayList;
24+
import java.util.HashMap;
2125
import java.util.List;
26+
import java.util.Map;
2227
import java.util.concurrent.CopyOnWriteArrayList;
2328
import java.util.concurrent.CountDownLatch;
2429
import java.util.regex.Matcher;
2530

2631
import javax.net.ssl.SSLHandshakeException;
2732

28-
import okhttp3.Request;
29-
import okhttp3.Response;
30-
3133
public class ContentBlockerHandler {
3234
protected static final String LOG_TAG = "ContentBlockerHandler";
3335

@@ -48,10 +50,14 @@ public void setRuleList(List<ContentBlocker> newRuleList) {
4850
}
4951

5052
@Nullable
51-
public WebResourceResponse checkUrl(final InAppWebView webView, String url, ContentBlockerTriggerResourceType responseResourceType) throws URISyntaxException, InterruptedException, MalformedURLException {
53+
public WebResourceResponse checkUrl(final InAppWebView webView, WebResourceRequestExt request,
54+
ContentBlockerTriggerResourceType responseResourceType)
55+
throws URISyntaxException, InterruptedException, MalformedURLException {
5256
if (webView.customSettings.contentBlockers == null)
5357
return null;
5458

59+
String url = request.getUrl();
60+
5561
URI u;
5662
try {
5763
u = new URI(url);
@@ -182,36 +188,85 @@ public void run() {
182188
if (scheme.equals("http") && (port == -1 || port == 80)) {
183189
String urlHttps = url.replace("http://", "https://");
184190

185-
Request mRequest = new Request.Builder().url(urlHttps).build();
186-
Response response = null;
187-
188-
try {
189-
response = Util.getBasicOkHttpClient().newCall(mRequest).execute();
190-
byte[] dataBytes = response.body().bytes();
191-
InputStream dataStream = new ByteArrayInputStream(dataBytes);
192-
193-
String[] contentTypeSplitted = response.header("content-type", "text/plain").split(";");
194-
195-
String contentType = contentTypeSplitted[0].trim();
196-
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
197-
? contentTypeSplitted[1].replace("charset=", "").trim()
198-
: "utf-8";
199-
200-
response.body().close();
201-
response.close();
202-
203-
return new WebResourceResponse(contentType, encoding, dataStream);
204-
205-
} catch (Exception e) {
206-
if (response != null) {
207-
response.body().close();
208-
response.close();
209-
}
210-
if (!(e instanceof SSLHandshakeException)) {
211-
e.printStackTrace();
212-
Log.e(LOG_TAG, e.getMessage());
191+
HttpURLConnection urlConnection = Util.makeHttpRequest(urlHttps, request.getMethod(), request.getHeaders());
192+
if (urlConnection != null) {
193+
try {
194+
byte[] dataBytes = Util.readAllBytes(urlConnection.getInputStream());
195+
if (dataBytes == null) {
196+
return null;
197+
}
198+
InputStream dataStream = new ByteArrayInputStream(dataBytes);
199+
200+
String encoding = urlConnection.getContentEncoding();
201+
String contentType = urlConnection.getContentType();
202+
if (contentType == null) {
203+
contentType = "text/plain";
204+
} else {
205+
String[] contentTypeSplitted = contentType.split(";");
206+
contentType = contentTypeSplitted[0].trim();
207+
if (encoding == null) {
208+
encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
209+
? contentTypeSplitted[1].replace("charset=", "").trim()
210+
: "utf-8";
211+
}
212+
}
213+
214+
String reasonPhrase = urlConnection.getResponseMessage();
215+
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.LOLLIPOP && reasonPhrase != null) {
216+
Map<String, String> responseHeaders = new HashMap<>();
217+
for (Map.Entry<String, List<String>> responseHeader : urlConnection.getHeaderFields().entrySet()) {
218+
responseHeaders.put(responseHeader.getKey(), TextUtils.join(",", responseHeader.getValue()));
219+
}
220+
return new WebResourceResponse(contentType,
221+
encoding,
222+
urlConnection.getResponseCode(),
223+
reasonPhrase,
224+
responseHeaders,
225+
dataStream);
226+
} else {
227+
return new WebResourceResponse(contentType,
228+
encoding,
229+
dataStream);
230+
}
231+
} catch (Exception e) {
232+
if (!(e instanceof SSLHandshakeException)) {
233+
e.printStackTrace();
234+
}
235+
} finally {
236+
urlConnection.disconnect();
213237
}
214238
}
239+
240+
// Request mRequest = new Request.Builder().url(urlHttps).build();
241+
// Response response = null;
242+
//
243+
// try {
244+
// response = Util.getBasicOkHttpClient().newCall(mRequest).execute();
245+
// byte[] dataBytes = response.body().bytes();
246+
// InputStream dataStream = new ByteArrayInputStream(dataBytes);
247+
//
248+
// String[] contentTypeSplitted = response.header("content-type", "text/plain").split(";");
249+
//
250+
// String contentType = contentTypeSplitted[0].trim();
251+
// String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
252+
// ? contentTypeSplitted[1].replace("charset=", "").trim()
253+
// : "utf-8";
254+
//
255+
// response.body().close();
256+
// response.close();
257+
//
258+
// return new WebResourceResponse(contentType, encoding, dataStream);
259+
//
260+
// } catch (Exception e) {
261+
// if (response != null) {
262+
// response.body().close();
263+
// response.close();
264+
// }
265+
// if (!(e instanceof SSLHandshakeException)) {
266+
// e.printStackTrace();
267+
// Log.e(LOG_TAG, e.getMessage());
268+
// }
269+
// }
215270
}
216271
break;
217272
}
@@ -221,48 +276,36 @@ public void run() {
221276
}
222277

223278
@Nullable
224-
public WebResourceResponse checkUrl(final InAppWebView webView, String url) throws URISyntaxException, InterruptedException, MalformedURLException {
225-
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromUrl(url);
226-
return checkUrl(webView, url, responseResourceType);
279+
public WebResourceResponse checkUrl(final InAppWebView webView, WebResourceRequestExt request) throws URISyntaxException, InterruptedException, MalformedURLException {
280+
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromUrl(request);
281+
return checkUrl(webView, request, responseResourceType);
227282
}
228283

229284
@Nullable
230-
public WebResourceResponse checkUrl(final InAppWebView webView, String url, String contentType) throws URISyntaxException, InterruptedException, MalformedURLException {
285+
public WebResourceResponse checkUrl(final InAppWebView webView, WebResourceRequestExt request, String contentType) throws URISyntaxException, InterruptedException, MalformedURLException {
231286
ContentBlockerTriggerResourceType responseResourceType = getResourceTypeFromContentType(contentType);
232-
return checkUrl(webView, url, responseResourceType);
287+
return checkUrl(webView, request, responseResourceType);
233288
}
234289

235-
public ContentBlockerTriggerResourceType getResourceTypeFromUrl(String url) {
290+
public ContentBlockerTriggerResourceType getResourceTypeFromUrl(WebResourceRequestExt request) {
236291
ContentBlockerTriggerResourceType responseResourceType = ContentBlockerTriggerResourceType.RAW;
292+
String url = request.getUrl();
237293

238294
if (url.startsWith("http://") || url.startsWith("https://")) {
239295
// make an HTTP "HEAD" request to the server for that URL. This will not return the full content of the URL.
240-
Request mRequest = new Request.Builder().url(url).head().build();
241-
Response response = null;
242-
try {
243-
response = Util.getBasicOkHttpClient().newCall(mRequest).execute();
244-
245-
if (response.header("content-type") != null) {
246-
String[] contentTypeSplitted = response.header("content-type").split(";");
247-
248-
String contentType = contentTypeSplitted[0].trim();
249-
String encoding = (contentTypeSplitted.length > 1 && contentTypeSplitted[1].contains("charset="))
250-
? contentTypeSplitted[1].replace("charset=", "").trim()
251-
: "utf-8";
252-
253-
response.body().close();
254-
response.close();
255-
responseResourceType = getResourceTypeFromContentType(contentType);
256-
}
257-
258-
} catch (Exception e) {
259-
if (response != null) {
260-
response.body().close();
261-
response.close();
262-
}
263-
if (!(e instanceof SSLHandshakeException)) {
296+
HttpURLConnection urlConnection = Util.makeHttpRequest(url, "HEAD", request.getHeaders());
297+
if (urlConnection != null) {
298+
try {
299+
String contentType = urlConnection.getContentType();
300+
if (contentType != null) {
301+
String[] contentTypeSplitted = contentType.split(";");
302+
contentType = contentTypeSplitted[0].trim();
303+
responseResourceType = getResourceTypeFromContentType(contentType);
304+
}
305+
} catch (Exception e) {
264306
e.printStackTrace();
265-
Log.e(LOG_TAG, e.getMessage());
307+
} finally {
308+
urlConnection.disconnect();
266309
}
267310
}
268311
}

android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/FlutterWebView.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -68,15 +68,13 @@ public FlutterWebView(final InAppWebViewFlutterPlugin plugin, final Context cont
6868
customSettings.useHybridComposition ? null : plugin.flutterView, userScripts);
6969
displayListenerProxy.onPostWebViewInitialization(displayManager);
7070

71-
if (customSettings.useHybridComposition) {
72-
// set MATCH_PARENT layout params to the WebView, otherwise it won't take all the available space!
73-
webView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
74-
PullToRefreshSettings pullToRefreshSettings = new PullToRefreshSettings();
75-
pullToRefreshSettings.parse(pullToRefreshInitialSettings);
76-
pullToRefreshLayout = new PullToRefreshLayout(context, plugin, id, pullToRefreshSettings);
77-
pullToRefreshLayout.addView(webView);
78-
pullToRefreshLayout.prepare();
79-
}
71+
// set MATCH_PARENT layout params to the WebView, otherwise it won't take all the available space!
72+
webView.setLayoutParams(new FrameLayout.LayoutParams(ViewGroup.LayoutParams.MATCH_PARENT, ViewGroup.LayoutParams.MATCH_PARENT));
73+
PullToRefreshSettings pullToRefreshSettings = new PullToRefreshSettings();
74+
pullToRefreshSettings.parse(pullToRefreshInitialSettings);
75+
pullToRefreshLayout = new PullToRefreshLayout(context, plugin, id, pullToRefreshSettings);
76+
pullToRefreshLayout.addView(webView);
77+
pullToRefreshLayout.prepare();
8078

8179
FindInteractionController findInteractionController = new FindInteractionController(webView, plugin, id, null);
8280
webView.findInteractionController = findInteractionController;

android/src/main/java/com/pichillilorenzo/flutter_inappwebview/webview/in_app_webview/InAppWebViewClient.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -690,7 +690,7 @@ public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceReque
690690
if (customSchemeResponse != null) {
691691
WebResourceResponse response = null;
692692
try {
693-
response = webView.contentBlockerHandler.checkUrl(webView, url, customSchemeResponse.getContentType());
693+
response = webView.contentBlockerHandler.checkUrl(webView, request, customSchemeResponse.getContentType());
694694
} catch (Exception e) {
695695
e.printStackTrace();
696696
}
@@ -705,7 +705,7 @@ public WebResourceResponse shouldInterceptRequest(WebView view, WebResourceReque
705705
WebResourceResponse response = null;
706706
if (webView.contentBlockerHandler.getRuleList().size() > 0) {
707707
try {
708-
response = webView.contentBlockerHandler.checkUrl(webView, url);
708+
response = webView.contentBlockerHandler.checkUrl(webView, request);
709709
} catch (Exception e) {
710710
e.printStackTrace();
711711
}

example/ios/Flutter/flutter_export_environment.sh

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,11 @@
33
export "FLUTTER_ROOT=/Users/lorenzopichilli/fvm/versions/3.3.6"
44
export "FLUTTER_APPLICATION_PATH=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example"
55
export "COCOAPODS_PARALLEL_CODE_SIGN=true"
6-
export "FLUTTER_TARGET=integration_test/webview_flutter_test.dart"
6+
export "FLUTTER_TARGET=/Users/lorenzopichilli/Desktop/flutter_inappwebview/example/lib/main.dart"
77
export "FLUTTER_BUILD_DIR=build"
88
export "FLUTTER_BUILD_NAME=1.0.0"
99
export "FLUTTER_BUILD_NUMBER=1"
10-
export "DART_DEFINES=RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
10+
export "DART_DEFINES=Zmx1dHRlci5pbnNwZWN0b3Iuc3RydWN0dXJlZEVycm9ycz10cnVl,RkxVVFRFUl9XRUJfQVVUT19ERVRFQ1Q9dHJ1ZQ=="
1111
export "DART_OBFUSCATION=false"
1212
export "TRACK_WIDGET_CREATION=true"
1313
export "TREE_SHAKE_ICONS=false"

0 commit comments

Comments
 (0)