[webview_flutter] controller headers loadurl (#1516)
* Modify loadUrl to allow headers
* Add test for headers
* pubspec and changelog
* fix analyze errors
* Add a test for webview headers
* analyze errors
* Add print to debug tests
* fix test
diff --git a/packages/webview_flutter/CHANGELOG.md b/packages/webview_flutter/CHANGELOG.md
index 8985c7b..5048781 100644
--- a/packages/webview_flutter/CHANGELOG.md
+++ b/packages/webview_flutter/CHANGELOG.md
@@ -1,3 +1,7 @@
+## 0.3.6
+
+* Add an optional `headers` field to the controller.
+
## 0.3.5+5
* Fixed error in documentation of `javascriptChannels`.
diff --git a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
index 21720cf..06cbb39 100644
--- a/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
+++ b/packages/webview_flutter/android/src/main/java/io/flutter/plugins/webviewflutter/FlutterWebView.java
@@ -18,6 +18,7 @@
import io.flutter.plugin.common.MethodChannel.MethodCallHandler;
import io.flutter.plugin.common.MethodChannel.Result;
import io.flutter.plugin.platform.PlatformView;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
@@ -100,9 +101,15 @@
}
}
+ @SuppressWarnings("unchecked")
private void loadUrl(MethodCall methodCall, Result result) {
- String url = (String) methodCall.arguments;
- webView.loadUrl(url);
+ Map<String, Object> request = (Map<String, Object>) methodCall.arguments;
+ String url = (String) request.get("url");
+ Map<String, String> headers = (Map<String, String>) request.get("headers");
+ if (headers == null) {
+ headers = Collections.emptyMap();
+ }
+ webView.loadUrl(url, headers);
result.success(null);
}
diff --git a/packages/webview_flutter/example/test_driver/webview.dart b/packages/webview_flutter/example/test_driver/webview.dart
index 03de967..8b56878 100644
--- a/packages/webview_flutter/example/test_driver/webview.dart
+++ b/packages/webview_flutter/example/test_driver/webview.dart
@@ -54,6 +54,39 @@
final String currentUrl = await controller.currentUrl();
expect(currentUrl, 'https://www.google.com/');
});
+
+ test('loadUrl with headers', () async {
+ final Completer<WebViewController> controllerCompleter =
+ Completer<WebViewController>();
+ await pumpWidget(
+ Directionality(
+ textDirection: TextDirection.ltr,
+ child: WebView(
+ key: GlobalKey(),
+ initialUrl: 'https://flutter.dev/',
+ onWebViewCreated: (WebViewController controller) {
+ controllerCompleter.complete(controller);
+ },
+ javascriptMode: JavascriptMode.unrestricted,
+ ),
+ ),
+ );
+ final WebViewController controller = await controllerCompleter.future;
+ final Map<String, String> headers = <String, String>{
+ 'test_header': 'flutter_test_header'
+ };
+ await controller.loadUrl('https://flutter-header-echo.herokuapp.com/',
+ headers: headers);
+ final String currentUrl = await controller.currentUrl();
+ expect(currentUrl, 'https://flutter-header-echo.herokuapp.com/');
+
+ // wait for the web page to load.
+ await Future<dynamic>.delayed(const Duration(seconds: 5));
+
+ final String content = await controller
+ .evaluateJavascript('document.documentElement.innerText');
+ expect(content.contains('flutter_test_header'), isTrue);
+ });
}
Future<void> pumpWidget(Widget widget) {
diff --git a/packages/webview_flutter/ios/Classes/FlutterWebView.m b/packages/webview_flutter/ios/Classes/FlutterWebView.m
index ea3b192..afc2f99 100644
--- a/packages/webview_flutter/ios/Classes/FlutterWebView.m
+++ b/packages/webview_flutter/ios/Classes/FlutterWebView.m
@@ -123,11 +123,11 @@
}
- (void)onLoadUrl:(FlutterMethodCall*)call result:(FlutterResult)result {
- NSString* url = [call arguments];
- if (![self loadUrl:url]) {
- result([FlutterError errorWithCode:@"loadUrl_failed"
- message:@"Failed parsing the URL"
- details:[NSString stringWithFormat:@"URL was: '%@'", url]]);
+ if (![self loadRequest:[call arguments]]) {
+ result([FlutterError
+ errorWithCode:@"loadUrl_failed"
+ message:@"Failed parsing the URL"
+ details:[NSString stringWithFormat:@"Request was: '%@'", [call arguments]]]);
} else {
result(nil);
}
@@ -256,13 +256,36 @@
}
}
+- (bool)loadRequest:(NSDictionary<NSString*, id>*)request {
+ if (!request) {
+ return false;
+ }
+
+ NSString* url = request[@"url"];
+ if ([url isKindOfClass:[NSString class]]) {
+ id headers = request[@"headers"];
+ if ([headers isKindOfClass:[NSDictionary class]]) {
+ return [self loadUrl:url withHeaders:headers];
+ } else {
+ return [self loadUrl:url];
+ }
+ }
+
+ return false;
+}
+
- (bool)loadUrl:(NSString*)url {
+ return [self loadUrl:url withHeaders:[NSMutableDictionary dictionary]];
+}
+
+- (bool)loadUrl:(NSString*)url withHeaders:(NSDictionary<NSString*, NSString*>*)headers {
NSURL* nsUrl = [NSURL URLWithString:url];
if (!nsUrl) {
return false;
}
- NSURLRequest* req = [NSURLRequest requestWithURL:nsUrl];
- [_webView loadRequest:req];
+ NSMutableURLRequest* request = [NSMutableURLRequest requestWithURL:nsUrl];
+ [request setAllHTTPHeaderFields:headers];
+ [_webView loadRequest:request];
return true;
}
diff --git a/packages/webview_flutter/lib/webview_flutter.dart b/packages/webview_flutter/lib/webview_flutter.dart
index 49063a2..2f5bffc 100644
--- a/packages/webview_flutter/lib/webview_flutter.dart
+++ b/packages/webview_flutter/lib/webview_flutter.dart
@@ -414,13 +414,19 @@
/// `url` must not be null.
///
/// Throws an ArgumentError if `url` is not a valid URL string.
- Future<void> loadUrl(String url) async {
+ Future<void> loadUrl(
+ String url, {
+ Map<String, String> headers,
+ }) async {
assert(url != null);
_validateUrlString(url);
// TODO(amirh): remove this on when the invokeMethod update makes it to stable Flutter.
// https://github.com/flutter/flutter/issues/26431
// ignore: strong_mode_implicit_dynamic_method
- return _channel.invokeMethod('loadUrl', url);
+ return _channel.invokeMethod('loadUrl', <String, dynamic>{
+ 'url': url,
+ 'headers': headers,
+ });
}
/// Accessor to the current URL that the WebView is displaying.
diff --git a/packages/webview_flutter/pubspec.yaml b/packages/webview_flutter/pubspec.yaml
index 943f624..183a11d 100644
--- a/packages/webview_flutter/pubspec.yaml
+++ b/packages/webview_flutter/pubspec.yaml
@@ -1,6 +1,6 @@
name: webview_flutter
description: A Flutter plugin that provides a WebView widget on Android and iOS.
-version: 0.3.5+5
+version: 0.3.6
author: Flutter Team <flutter-dev@googlegroups.com>
homepage: https://github.com/flutter/plugins/tree/master/packages/webview_flutter
diff --git a/packages/webview_flutter/test/webview_flutter_test.dart b/packages/webview_flutter/test/webview_flutter_test.dart
index d66f56d..67a5547 100644
--- a/packages/webview_flutter/test/webview_flutter_test.dart
+++ b/packages/webview_flutter/test/webview_flutter_test.dart
@@ -106,6 +106,25 @@
expect(await controller.currentUrl(), isNull);
});
+ testWidgets('Headers in loadUrl', (WidgetTester tester) async {
+ WebViewController controller;
+ await tester.pumpWidget(
+ WebView(
+ onWebViewCreated: (WebViewController webViewController) {
+ controller = webViewController;
+ },
+ ),
+ );
+
+ expect(controller, isNotNull);
+
+ final Map<String, String> headers = <String, String>{
+ 'CACHE-CONTROL': 'ABC'
+ };
+ await controller.loadUrl('https://flutter.io', headers: headers);
+ expect(await controller.currentUrl(), equals('https://flutter.io'));
+ });
+
testWidgets("Can't go back before loading a page",
(WidgetTester tester) async {
WebViewController controller;
@@ -722,8 +741,8 @@
Future<dynamic> onMethodCall(MethodCall call) {
switch (call.method) {
case 'loadUrl':
- final String url = call.arguments;
- _loadUrl(url);
+ final Map<dynamic, dynamic> request = call.arguments;
+ _loadUrl(request['url']);
return Future<void>.sync(() {});
case 'updateSettings':
if (call.arguments['jsMode'] != null) {