summaryrefslogtreecommitdiffstats
path: root/ios
diff options
context:
space:
mode:
authorkkhorimoto <kkhorimoto@chromium.org>2015-05-22 14:32:29 -0700
committerCommit bot <commit-bot@chromium.org>2015-05-22 21:34:00 +0000
commit1f3dd239b569036e77a75dd9c36657ab18947f96 (patch)
tree7bc70da852a23b945d2479436ef85830ba3051e9 /ios
parentac94e41f40bfc5252dc23dd72549d985ca221168 (diff)
downloadchromium_src-1f3dd239b569036e77a75dd9c36657ab18947f96.zip
chromium_src-1f3dd239b569036e77a75dd9c36657ab18947f96.tar.gz
chromium_src-1f3dd239b569036e77a75dd9c36657ab18947f96.tar.bz2
Created CRWRedirectClient.
This allows CRWUIWebViewWebController to record server redirects as soon as the redirect response is received by the net layer. BUG=478848 Review URL: https://codereview.chromium.org/1147393004 Cr-Commit-Position: refs/heads/master@{#331178}
Diffstat (limited to 'ios')
-rw-r--r--ios/web/ios_web.gyp4
-rw-r--r--ios/web/navigation/crw_session_controller.mm2
-rw-r--r--ios/web/net/clients/crw_redirect_network_client.h35
-rw-r--r--ios/web/net/clients/crw_redirect_network_client.mm52
-rw-r--r--ios/web/net/clients/crw_redirect_network_client_factory.h21
-rw-r--r--ios/web/net/clients/crw_redirect_network_client_factory.mm54
-rw-r--r--ios/web/web_state/ui/crw_ui_web_view_web_controller.mm47
-rw-r--r--ios/web/web_state/web_state_impl.mm1
8 files changed, 213 insertions, 3 deletions
diff --git a/ios/web/ios_web.gyp b/ios/web/ios_web.gyp
index c8ec30c..0776a10 100644
--- a/ios/web/ios_web.gyp
+++ b/ios/web/ios_web.gyp
@@ -78,6 +78,10 @@
'net/clients/crw_passkit_network_client.mm',
'net/clients/crw_passkit_network_client_factory.h',
'net/clients/crw_passkit_network_client_factory.mm',
+ 'net/clients/crw_redirect_network_client.h',
+ 'net/clients/crw_redirect_network_client.mm',
+ 'net/clients/crw_redirect_network_client_factory.h',
+ 'net/clients/crw_redirect_network_client_factory.mm',
'net/cookie_notification_bridge.h',
'net/cookie_notification_bridge.mm',
'net/crw_request_tracker_delegate.h',
diff --git a/ios/web/navigation/crw_session_controller.mm b/ios/web/navigation/crw_session_controller.mm
index b86f243..eb8a92a1 100644
--- a/ios/web/navigation/crw_session_controller.mm
+++ b/ios/web/navigation/crw_session_controller.mm
@@ -434,8 +434,6 @@ NSString* const kXCallbackParametersKey = @"xCallbackParameters";
if (url != item->GetURL()) {
item->SetURL(url);
item->SetVirtualURL(url);
- // Since updates are caused by page redirects, they are renderer-initiated.
- item->set_is_renderer_initiated(true);
// Redirects (3xx response code), or client side navigation must change
// POST requests to GETs.
item->SetPostData(nil);
diff --git a/ios/web/net/clients/crw_redirect_network_client.h b/ios/web/net/clients/crw_redirect_network_client.h
new file mode 100644
index 0000000..41a4c7b
--- /dev/null
+++ b/ios/web/net/clients/crw_redirect_network_client.h
@@ -0,0 +1,35 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_NET_CLIENTS_CRW_REDIRECT_NETWORK_CLIENT_H_
+#define IOS_WEB_NET_CLIENTS_CRW_REDIRECT_NETWORK_CLIENT_H_
+
+#import <Foundation/Foundation.h>
+
+#include "base/ios/weak_nsobject.h"
+#import "ios/net/clients/crn_forwarding_network_client.h"
+
+@protocol CRWRedirectClientDelegate;
+
+// The CRWRedirectNetworkClient observes redirects and notifies its delegate
+// when they occur.
+@interface CRWRedirectNetworkClient : CRNForwardingNetworkClient
+
+// Designated initializer.
+- (instancetype)initWithDelegate:
+ (base::WeakNSProtocol<id<CRWRedirectClientDelegate>>)delegate;
+
+@end
+
+// Delegate for CRWRedirectNetworkClients.
+@protocol CRWRedirectClientDelegate<NSObject>
+
+// Notifies the delegate that the current http request recieved |response| and
+// was redirected to |request|.
+- (void)wasRedirectedToRequest:(NSURLRequest*)request
+ redirectResponse:(NSURLResponse*)response;
+
+@end
+
+#endif // IOS_WEB_NET_CLIENTS_CRW_REDIRECT_NETWORK_CLIENT_H_
diff --git a/ios/web/net/clients/crw_redirect_network_client.mm b/ios/web/net/clients/crw_redirect_network_client.mm
new file mode 100644
index 0000000..2442834
--- /dev/null
+++ b/ios/web/net/clients/crw_redirect_network_client.mm
@@ -0,0 +1,52 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/web/net/clients/crw_redirect_network_client.h"
+
+#include "base/location.h"
+#include "base/mac/bind_objc_block.h"
+#include "ios/web/public/web_thread.h"
+
+@interface CRWRedirectNetworkClient () {
+ // The delegate.
+ base::WeakNSProtocol<id<CRWRedirectClientDelegate>> delegate_;
+}
+
+@end
+
+@implementation CRWRedirectNetworkClient
+
+- (instancetype)init {
+ NOTREACHED();
+ return nil;
+}
+
+- (instancetype)initWithDelegate:
+ (base::WeakNSProtocol<id<CRWRedirectClientDelegate>>)delegate {
+ self = [super init];
+ if (self) {
+ // CRWRedirectNetworkClients are created on the IO thread, but due to the
+ // threading restrictions of WeakNSObjects, |delegate_| may only be
+ // dereferenced on the UI thread.
+ DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::IO);
+ delegate_ = delegate;
+ }
+ return self;
+}
+
+- (void)wasRedirectedToRequest:(NSURLRequest*)request
+ nativeRequest:(net::URLRequest*)nativeRequest
+ redirectResponse:(NSURLResponse*)redirectResponse {
+ DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::IO);
+ web::WebThread::PostTask(web::WebThread::UI, FROM_HERE, base::BindBlock(^{
+ // |delegate_| can only be dereferenced from the UI thread.
+ [delegate_ wasRedirectedToRequest:request
+ redirectResponse:redirectResponse];
+ }));
+ [super wasRedirectedToRequest:request
+ nativeRequest:nativeRequest
+ redirectResponse:redirectResponse];
+}
+
+@end
diff --git a/ios/web/net/clients/crw_redirect_network_client_factory.h b/ios/web/net/clients/crw_redirect_network_client_factory.h
new file mode 100644
index 0000000..68e3c49
--- /dev/null
+++ b/ios/web/net/clients/crw_redirect_network_client_factory.h
@@ -0,0 +1,21 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef IOS_WEB_NET_CLIENTS_CRW_REDIRECT_NETWORK_CLIENT_FACTORY_H_
+#define IOS_WEB_NET_CLIENTS_CRW_REDIRECT_NETWORK_CLIENT_FACTORY_H_
+
+#import <Foundation/Foundation.h>
+
+#import "ios/web/net/clients/crw_redirect_network_client.h"
+#import "ios/net/clients/crn_forwarding_network_client_factory.h"
+
+// Factory that creates CRWRedirectNetworkClient instances.
+@interface CRWRedirectNetworkClientFactory : CRNForwardingNetworkClientFactory
+
+// Designated initializer. |delegate| is expected to be non-nil.
+- (instancetype)initWithDelegate:(id<CRWRedirectClientDelegate>)delegate;
+
+@end
+
+#endif // IOS_WEB_NET_CLIENTS_CRW_REDIRECT_NETWORK_CLIENT_FACTORY_H_
diff --git a/ios/web/net/clients/crw_redirect_network_client_factory.mm b/ios/web/net/clients/crw_redirect_network_client_factory.mm
new file mode 100644
index 0000000..d3ac5da
--- /dev/null
+++ b/ios/web/net/clients/crw_redirect_network_client_factory.mm
@@ -0,0 +1,54 @@
+// Copyright 2015 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "ios/web/net/clients/crw_redirect_network_client_factory.h"
+
+#include "base/location.h"
+#import "base/ios/weak_nsobject.h"
+#include "base/mac/bind_objc_block.h"
+#include "ios/web/public/web_thread.h"
+#include "net/http/http_response_headers.h"
+#include "net/url_request/url_request.h"
+#include "url/gurl.h"
+
+@interface CRWRedirectNetworkClientFactory () {
+ // Delegate passed to each vended CRWRedirectClient.
+ base::WeakNSProtocol<id<CRWRedirectClientDelegate>> client_delegate_;
+}
+
+@end
+
+@implementation CRWRedirectNetworkClientFactory
+
+- (instancetype)init {
+ NOTREACHED();
+ return nil;
+}
+
+- (instancetype)initWithDelegate:(id<CRWRedirectClientDelegate>)delegate {
+ self = [super init];
+ if (self) {
+ DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::UI);
+ DCHECK(delegate);
+ client_delegate_.reset(delegate);
+ }
+ return self;
+}
+
+#pragma mark - CRNForwardingNetworkClientFactory
+
+- (Class)clientClass {
+ return [CRWRedirectNetworkClient class];
+}
+
+- (CRNForwardingNetworkClient*)clientHandlingRedirect:
+ (const net::URLRequest&)request
+ url:(const GURL&)url
+ response:(NSURLResponse*)response {
+ DCHECK_CURRENTLY_ON_WEB_THREAD(web::WebThread::IO);
+ return [[[CRWRedirectNetworkClient alloc]
+ initWithDelegate:client_delegate_] autorelease];
+}
+
+@end
diff --git a/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm b/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm
index bd24193..8a97881 100644
--- a/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm
+++ b/ios/web/web_state/ui/crw_ui_web_view_web_controller.mm
@@ -19,6 +19,7 @@
#import "ios/net/nsurlrequest_util.h"
#import "ios/web/navigation/crw_session_controller.h"
#import "ios/web/navigation/crw_session_entry.h"
+#include "ios/web/net/clients/crw_redirect_network_client_factory.h"
#import "ios/web/net/crw_url_verifying_protocol_handler.h"
#include "ios/web/net/request_group_util.h"
#include "ios/web/public/url_scheme_util.h"
@@ -54,7 +55,8 @@ const int64 kContinuousCheckIntervalMSLow = 3000;
} // namespace web
-@interface CRWUIWebViewWebController ()<UIWebViewDelegate> {
+@interface CRWUIWebViewWebController () <CRWRedirectClientDelegate,
+ UIWebViewDelegate> {
// The UIWebView managed by this instance.
base::scoped_nsobject<UIWebView> _uiWebView;
@@ -123,6 +125,10 @@ const int64 kContinuousCheckIntervalMSLow = 3000;
// Backs the property of the same name.
id<CRWRecurringTaskDelegate>_recurringTaskDelegate;
+
+ // Redirect client factory.
+ base::scoped_nsobject<CRWRedirectNetworkClientFactory>
+ redirect_client_factory_;
}
// Whether or not URL caching is enabled. Between enabling and disabling
@@ -326,6 +332,30 @@ const size_t kMaxMessageQueueSize = 262144;
@"UIMoviePlayerControllerDidExitFullscreenNotification"
object:nil];
_recurringTaskDelegate = self;
+
+ // UIWebViews require a redirect network client in order to accurately
+ // detect server redirects.
+ redirect_client_factory_.reset(
+ [[CRWRedirectNetworkClientFactory alloc] initWithDelegate:self]);
+ // WeakNSObjects cannot be dereferenced outside of the main thread, and
+ // CRWWebController must be deallocated from the main thread. Keep a
+ // reference to self on the main thread and release it after successfully
+ // adding the redirect client factory to the RequestTracker on the IO
+ // thread.
+ __block base::scoped_nsobject<CRWUIWebViewWebController> scopedSelf(
+ [self retain]);
+ web::WebThread::PostTaskAndReply(
+ web::WebThread::IO, FROM_HERE, base::BindBlock(^{
+ // Only add the factory if there is a valid request tracker.
+ web::WebStateImpl* webState = [scopedSelf webStateImpl];
+ if (webState && webState->GetRequestTracker()) {
+ webState->GetRequestTracker()->AddNetworkClientFactory(
+ redirect_client_factory_);
+ }
+ }),
+ base::BindBlock(^{
+ scopedSelf.reset();
+ }));
}
return self;
}
@@ -1318,6 +1348,21 @@ const size_t kMaxMessageQueueSize = 262144;
}
#pragma mark -
+#pragma mark CRWRedirectClientDelegate
+
+- (void)wasRedirectedToRequest:(NSURLRequest*)request
+ redirectResponse:(NSURLResponse*)response {
+ // Register the redirected load request if it originated from the main page
+ // load.
+ GURL redirectedURL = net::GURLWithNSURL(response.URL);
+ if ([self currentNavigationURL] == redirectedURL) {
+ [self registerLoadRequest:net::GURLWithNSURL(request.URL)
+ referrer:[self currentReferrer]
+ transition:ui::PAGE_TRANSITION_SERVER_REDIRECT];
+ }
+}
+
+#pragma mark -
#pragma mark UIWebViewDelegate Methods
// Called when a load begins, and for subsequent subpages.
diff --git a/ios/web/web_state/web_state_impl.mm b/ios/web/web_state/web_state_impl.mm
index f35c593..7450809 100644
--- a/ios/web/web_state/web_state_impl.mm
+++ b/ios/web/web_state/web_state_impl.mm
@@ -341,6 +341,7 @@ void WebStateImpl::ClearWebInterstitialForNavigation() {
// interstitial, have the session controller go back one page.
[sessionController goBack];
}
+ [sessionController discardNonCommittedEntries];
interstitial->DontProceed();
}
}