Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(888)

Unified Diff: ios/web/web_state/ui/crw_wk_web_view_web_controller.mm

Issue 1516303002: Adds support for POST request with bodies on WKWebView. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@2564
Patch Set: Created 5 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « ios/web/web_state/ui/crw_wk_script_message_router.mm ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
diff --git a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
index fb9433e76143ca0f7ba4772b73bb72f439098697..8da1e3777fb7e520b4d07386acb6cb89c5bf22c6 100644
--- a/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
+++ b/ios/web/web_state/ui/crw_wk_web_view_web_controller.mm
@@ -10,7 +10,7 @@
#include "base/ios/ios_util.h"
#include "base/ios/weak_nsobject.h"
#include "base/json/json_reader.h"
-#include "base/mac/objc_property_releaser.h"
+#import "base/mac/objc_property_releaser.h"
#import "base/mac/scoped_nsobject.h"
#include "base/macros.h"
#include "base/metrics/histogram_macros.h"
@@ -39,6 +39,7 @@
#import "ios/web/web_state/crw_pass_kit_downloader.h"
#import "ios/web/web_state/error_translation_util.h"
#include "ios/web/web_state/frame_info.h"
+#import "ios/web/web_state/js/crw_js_post_request_loader.h"
#import "ios/web/web_state/js/crw_js_window_id_manager.h"
#import "ios/web/web_state/ui/crw_web_controller+protected.h"
#import "ios/web/web_state/ui/crw_wk_script_message_router.h"
@@ -187,6 +188,9 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
// Handles downloading PassKit data for WKWebView. Lazy initialized.
base::scoped_nsobject<CRWPassKitDownloader> _passKitDownloader;
+ // Object for loading POST requests with body.
+ base::scoped_nsobject<CRWJSPOSTRequestLoader> _POSTRequestLoader;
+
// Whether the web page is currently performing window.history.pushState or
// window.history.replaceState
// Set to YES on window.history.willChangeState message. To NO on
@@ -239,6 +243,15 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
// Downloader for PassKit files. Lazy initialized.
@property(nonatomic, readonly) CRWPassKitDownloader* passKitDownloader;
+// Loads POST request with body in |_wkWebView| by constructing an HTML page
+// that executes the request through JavaScript and replaces document with the
+// result.
+// Note that this approach includes multiple body encodings and decodings, plus
+// the data is passed to |_wkWebView| on main thread.
+// This is necessary because WKWebView ignores POST request body.
+// Workaround for https://bugs.webkit.org/show_bug.cgi?id=145410
+- (void)loadPOSTRequest:(NSMutableURLRequest*)request;
+
// Returns the WKWebViewConfigurationProvider associated with the web
// controller's BrowserState.
- (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider;
@@ -573,20 +586,42 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
- (void)loadRequestForCurrentNavigationItem {
DCHECK(self.webView && !self.nativeController);
+ DCHECK([self currentSessionEntry]);
+
+ web::WKBackForwardListItemHolder* holder =
+ [self currentBackForwardListItemHolder];
+ BOOL isFormResubmission =
+ (holder->navigation_type() == WKNavigationTypeFormResubmitted ||
+ holder->navigation_type() == WKNavigationTypeFormSubmitted);
+ web::NavigationItemImpl* currentItem =
+ [self currentSessionEntry].navigationItemImpl;
+ NSData* POSTData = currentItem->GetPostData();
+ NSMutableURLRequest* request = [self requestForCurrentNavigationItem];
+
+ // If the request has POST data and is not a form resubmission, configure and
+ // run the POST request.
+ if (POSTData.length && !isFormResubmission) {
+ [request setHTTPMethod:@"POST"];
+ [request setHTTPBody:POSTData];
+ [request setAllHTTPHeaderFields:[self currentHTTPHeaders]];
+ [self registerLoadRequest:[self currentNavigationURL]
+ referrer:[self currentSessionEntryReferrer]
+ transition:[self currentTransition]];
+ [self loadPOSTRequest:request];
+ return;
+ }
ProceduralBlock defaultNavigationBlock = ^{
[self registerLoadRequest:[self currentNavigationURL]
referrer:[self currentSessionEntryReferrer]
transition:[self currentTransition]];
- [self loadRequest:[self requestForCurrentNavigationItem]];
+ [self loadRequest:request];
};
// If there is no corresponding WKBackForwardListItem, or the item is not in
// the current WKWebView's back-forward list, navigating using WKWebView API
// is not possible. In this case, fall back to the default navigation
// mechanism.
- web::WKBackForwardListItemHolder* holder =
- [self currentBackForwardListItemHolder];
if (!holder->back_forward_list_item() ||
![self isBackForwardListItemValid:holder->back_forward_list_item()]) {
defaultNavigationBlock();
@@ -610,10 +645,8 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
// If the request is not a form submission or resubmission, or the user
// doesn't need to confirm the load, then continue right away.
- web::NavigationItemImpl* currentItem =
- [self currentSessionEntry].navigationItemImpl;
- if ((holder->navigation_type() != WKNavigationTypeFormResubmitted &&
- holder->navigation_type() != WKNavigationTypeFormSubmitted) ||
+
+ if (!isFormResubmission ||
currentItem->ShouldSkipResubmitDataConfirmation()) {
webViewNavigationBlock();
return;
@@ -621,6 +654,7 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
// If the request is form submission or resubmission, then prompt the
// user before proceeding.
+ DCHECK(isFormResubmission);
[self.delegate webController:self
onFormResubmissionForRequest:nil
continueBlock:webViewNavigationBlock
@@ -744,6 +778,25 @@ WKWebViewErrorSource WKWebViewErrorSourceFromError(NSError* error) {
}
#endif
+- (void)loadPOSTRequest:(NSMutableURLRequest*)request {
+ if (!_POSTRequestLoader) {
+ _POSTRequestLoader.reset([[CRWJSPOSTRequestLoader alloc] init]);
+ }
+
+ CRWWKScriptMessageRouter* messageRouter =
+ [self webViewConfigurationProvider].GetScriptMessageRouter();
+
+ [_POSTRequestLoader loadPOSTRequest:request
+ inWebView:_wkWebView
+ messageRouter:messageRouter
+ completionHandler:^(NSError* loadError) {
+ if (loadError)
+ [self handleLoadError:loadError inMainFrame:YES];
+ else
+ self.webStateImpl->SetContentsMimeType("text/html");
+ }];
+}
+
- (web::WKWebViewConfigurationProvider&)webViewConfigurationProvider {
DCHECK(self.webStateImpl);
web::BrowserState* browserState = self.webStateImpl->GetBrowserState();
« no previous file with comments | « ios/web/web_state/ui/crw_wk_script_message_router.mm ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698