| OLD | NEW |
| 1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #import "ios/web/web_state/ui/crw_web_controller.h" | 5 #import "ios/web/web_state/ui/crw_web_controller.h" |
| 6 | 6 |
| 7 #import <objc/runtime.h> | 7 #import <objc/runtime.h> |
| 8 #include <cmath> | 8 #include <cmath> |
| 9 | 9 |
| 10 #include "base/ios/block_types.h" | 10 #include "base/ios/block_types.h" |
| 11 #import "base/ios/ns_error_util.h" |
| 11 #include "base/ios/weak_nsobject.h" | 12 #include "base/ios/weak_nsobject.h" |
| 12 #include "base/json/json_reader.h" | 13 #include "base/json/json_reader.h" |
| 13 #include "base/json/json_writer.h" | 14 #include "base/json/json_writer.h" |
| 14 #include "base/json/string_escape.h" | 15 #include "base/json/string_escape.h" |
| 15 #include "base/logging.h" | 16 #include "base/logging.h" |
| 16 #include "base/mac/bundle_locations.h" | 17 #include "base/mac/bundle_locations.h" |
| 17 #include "base/mac/foundation_util.h" | 18 #include "base/mac/foundation_util.h" |
| 18 #include "base/mac/objc_property_releaser.h" | 19 #include "base/mac/objc_property_releaser.h" |
| 19 #include "base/mac/scoped_cftyperef.h" | 20 #include "base/mac/scoped_cftyperef.h" |
| 20 #include "base/mac/scoped_nsobject.h" | 21 #include "base/mac/scoped_nsobject.h" |
| (...skipping 1403 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1424 } | 1425 } |
| 1425 } | 1426 } |
| 1426 } | 1427 } |
| 1427 | 1428 |
| 1428 - (void)loadErrorInNativeView:(NSError*)error { | 1429 - (void)loadErrorInNativeView:(NSError*)error { |
| 1429 [self removeWebViewAllowingCachedReconstruction:NO]; | 1430 [self removeWebViewAllowingCachedReconstruction:NO]; |
| 1430 | 1431 |
| 1431 const GURL currentUrl = [self currentNavigationURL]; | 1432 const GURL currentUrl = [self currentNavigationURL]; |
| 1432 BOOL isPost = [self currentPOSTData] != nil; | 1433 BOOL isPost = [self currentPOSTData] != nil; |
| 1433 | 1434 |
| 1435 error = web::NetErrorFromError(error); |
| 1434 [self setNativeController:[_nativeProvider controllerForURL:currentUrl | 1436 [self setNativeController:[_nativeProvider controllerForURL:currentUrl |
| 1435 withError:error | 1437 withError:error |
| 1436 isPost:isPost]]; | 1438 isPost:isPost]]; |
| 1437 [self loadNativeViewWithSuccess:NO]; | 1439 [self loadNativeViewWithSuccess:NO]; |
| 1438 } | 1440 } |
| 1439 | 1441 |
| 1440 // Load the current URL in a native controller, retrieved from the native | 1442 // Load the current URL in a native controller, retrieved from the native |
| 1441 // provider. Call |loadNativeViewWithSuccess:YES| to load the native controller. | 1443 // provider. Call |loadNativeViewWithSuccess:YES| to load the native controller. |
| 1442 - (void)loadCurrentURLInNativeView { | 1444 - (void)loadCurrentURLInNativeView { |
| 1443 // Free the web view. | 1445 // Free the web view. |
| (...skipping 1386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2830 // Reset |_lastRegisteredRequestURL| so that it reflects the URL from before | 2832 // Reset |_lastRegisteredRequestURL| so that it reflects the URL from before |
| 2831 // the load was rejected. This value may be out of sync because | 2833 // the load was rejected. This value may be out of sync because |
| 2832 // |_lastRegisteredRequestURL| may have already been updated before the load | 2834 // |_lastRegisteredRequestURL| may have already been updated before the load |
| 2833 // was rejected. | 2835 // was rejected. |
| 2834 _lastRegisteredRequestURL = [self currentURL]; | 2836 _lastRegisteredRequestURL = [self currentURL]; |
| 2835 _loadPhase = web::PAGE_LOADING; | 2837 _loadPhase = web::PAGE_LOADING; |
| 2836 [self didFinishNavigation]; | 2838 [self didFinishNavigation]; |
| 2837 } | 2839 } |
| 2838 | 2840 |
| 2839 - (void)handleLoadError:(NSError*)error inMainFrame:(BOOL)inMainFrame { | 2841 - (void)handleLoadError:(NSError*)error inMainFrame:(BOOL)inMainFrame { |
| 2840 // Attempt to translate iOS errors into their corresponding net errors. | |
| 2841 error = web::NetErrorFromError(error); | |
| 2842 | |
| 2843 if ([error code] == NSURLErrorUnsupportedURL) | 2842 if ([error code] == NSURLErrorUnsupportedURL) |
| 2844 return; | 2843 return; |
| 2845 // In cases where a Plug-in handles the load do not take any further action. | 2844 // In cases where a Plug-in handles the load do not take any further action. |
| 2846 if ([[error domain] isEqual:WebKitErrorDomain] && | 2845 if ([[error domain] isEqual:WebKitErrorDomain] && |
| 2847 ([error code] == WebKitErrorPlugInLoadFailed || | 2846 ([error code] == WebKitErrorPlugInLoadFailed || |
| 2848 [error code] == WebKitErrorCannotShowURL)) | 2847 [error code] == WebKitErrorCannotShowURL)) |
| 2849 return; | 2848 return; |
| 2850 | 2849 |
| 2851 // Continue processing only if the error is on the main request or is the | 2850 // Continue processing only if the error is on the main request or is the |
| 2852 // result of a user interaction. | 2851 // result of a user interaction. |
| (...skipping 41 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2894 [_delegate controllerForUnhandledContentAtURL:errorGURL]; | 2893 [_delegate controllerForUnhandledContentAtURL:errorGURL]; |
| 2895 if (controller) { | 2894 if (controller) { |
| 2896 [self loadCompleteWithSuccess:NO]; | 2895 [self loadCompleteWithSuccess:NO]; |
| 2897 [self removeWebViewAllowingCachedReconstruction:NO]; | 2896 [self removeWebViewAllowingCachedReconstruction:NO]; |
| 2898 [self setNativeController:controller]; | 2897 [self setNativeController:controller]; |
| 2899 [self loadNativeViewWithSuccess:YES]; | 2898 [self loadNativeViewWithSuccess:YES]; |
| 2900 return; | 2899 return; |
| 2901 } | 2900 } |
| 2902 } | 2901 } |
| 2903 | 2902 |
| 2904 // Otherwise, handle the error normally. | 2903 // Ignore errors that originate from URLs that are opened in external apps. |
| 2905 if ([_openedApplicationURL containsObject:errorURL]) | 2904 if ([_openedApplicationURL containsObject:errorURL]) |
| 2906 return; | 2905 return; |
| 2907 // Certain frame errors don't have URL information for some reason; for | 2906 // Certain frame errors don't have URL information for some reason; for |
| 2908 // those cases (so far the only known case is plugin content loaded directly | 2907 // those cases (so far the only known case is plugin content loaded directly |
| 2909 // in a frame) just ignore the error. See crbug.com/414295 | 2908 // in a frame) just ignore the error. See crbug.com/414295 |
| 2910 if (!errorURL) { | 2909 if (!errorURL) { |
| 2911 DCHECK(!inMainFrame); | 2910 DCHECK(!inMainFrame); |
| 2912 return; | 2911 return; |
| 2913 } | 2912 } |
| 2914 // The wrapper error uses the URL of the error and not the requested URL | 2913 // The wrapper error uses the URL of the error and not the requested URL |
| 2915 // (which can be different in case of a redirect) to match desktop Chrome | 2914 // (which can be different in case of a redirect) to match desktop Chrome |
| 2916 // behavior. | 2915 // behavior. |
| 2917 NSError* wrapperError = [NSError | 2916 NSError* wrapperError = [NSError |
| 2918 errorWithDomain:[error domain] | 2917 errorWithDomain:[error domain] |
| 2919 code:[error code] | 2918 code:[error code] |
| 2920 userInfo:@{ | 2919 userInfo:@{ |
| 2921 NSURLErrorFailingURLStringErrorKey : [errorURL absoluteString], | 2920 NSURLErrorFailingURLStringErrorKey : [errorURL absoluteString], |
| 2922 NSUnderlyingErrorKey : error | 2921 NSUnderlyingErrorKey : error |
| 2923 }]; | 2922 }]; |
| 2924 [self loadCompleteWithSuccess:NO]; | 2923 [self loadCompleteWithSuccess:NO]; |
| 2925 [self loadErrorInNativeView:wrapperError]; | 2924 [self loadErrorInNativeView:wrapperError]; |
| 2926 return; | 2925 return; |
| 2927 } | 2926 } |
| 2928 | 2927 |
| 2929 // TODO(ios): Audit comments and behavior below regarding error origin. The | |
| 2930 // error has been translated and may appear to have originated in the Chrome | |
| 2931 // network stack when that is not true (crbug.com/496972) | |
| 2932 // Ignore cancelled errors. | |
| 2933 if ([error code] == NSURLErrorCancelled) { | 2928 if ([error code] == NSURLErrorCancelled) { |
| 2934 NSError* underlyingError = [userInfo objectForKey:NSUnderlyingErrorKey]; | 2929 if ([self shouldAbortLoadForCancelledError:error]) { |
| 2935 if (underlyingError && [self shouldAbortLoadForCancelledURL:errorGURL]) { | 2930 NSError* underlyingError = |
| 2936 DCHECK([underlyingError isKindOfClass:[NSError class]]); | 2931 base::ios::GetFinalUnderlyingErrorFromError(error); |
| 2932 DCHECK([underlyingError.domain |
| 2933 isEqualToString:base::SysUTF8ToNSString(net::kErrorDomain)]); |
| 2937 | 2934 |
| 2938 // The Error contains an NSUnderlyingErrorKey so it's being generated | 2935 // NSURLCancelled errors with underlying errors are generated from the |
| 2939 // in the Chrome network stack. Aborting the load in this case. | 2936 // Chrome network stack. Abort the load in this case. |
| 2940 [self abortLoad]; | 2937 [self abortLoad]; |
| 2941 | 2938 |
| 2942 switch ([underlyingError code]) { | 2939 switch ([underlyingError code]) { |
| 2943 case net::ERR_ABORTED: | 2940 case net::ERR_ABORTED: |
| 2944 // |NSURLErrorCancelled| errors with underlying net error code | 2941 // |NSURLErrorCancelled| errors with underlying net error code |
| 2945 // |net::ERR_ABORTED| are used by the Chrome network stack to | 2942 // |net::ERR_ABORTED| are used by the Chrome network stack to |
| 2946 // indicate that the current load should be aborted and the pending | 2943 // indicate that the current load should be aborted and the pending |
| 2947 // entry should be discarded. | 2944 // entry should be discarded. |
| 2948 [[self sessionController] discardNonCommittedEntries]; | 2945 [[self sessionController] discardNonCommittedEntries]; |
| 2949 break; | 2946 break; |
| 2950 case net::ERR_BLOCKED_BY_CLIENT: | 2947 case net::ERR_BLOCKED_BY_CLIENT: |
| 2951 // |NSURLErrorCancelled| errors with underlying net error code | 2948 // |NSURLErrorCancelled| errors with underlying net error code |
| 2952 // |net::ERR_BLOCKED_BY_CLIENT| are used by the Chrome network stack | 2949 // |net::ERR_BLOCKED_BY_CLIENT| are used by the Chrome network stack |
| 2953 // to indicate that the current load should be aborted and the pending | 2950 // to indicate that the current load should be aborted and the pending |
| 2954 // entry should be kept. | 2951 // entry should be kept. |
| 2955 break; | 2952 break; |
| 2956 default: | 2953 default: |
| 2957 NOTREACHED(); | 2954 NOTREACHED(); |
| 2958 } | 2955 } |
| 2959 } | 2956 } |
| 2957 // NSURLErrorCancelled errors that aren't handled by aborting the load will |
| 2958 // automatically be retried by the web view, so early return in this case. |
| 2960 return; | 2959 return; |
| 2961 } | 2960 } |
| 2962 | 2961 |
| 2963 [self loadCompleteWithSuccess:NO]; | 2962 [self loadCompleteWithSuccess:NO]; |
| 2964 [self loadErrorInNativeView:error]; | 2963 [self loadErrorInNativeView:error]; |
| 2965 } | 2964 } |
| 2966 | 2965 |
| 2967 - (BOOL)shouldAbortLoadForCancelledURL:(const GURL &)cancelledURL { | 2966 - (BOOL)shouldAbortLoadForCancelledError:(NSError*)cancelledError { |
| 2968 // Subclasses must implement this method. | 2967 // Subclasses must implement this method. |
| 2969 NOTREACHED(); | 2968 NOTREACHED(); |
| 2970 return YES; | 2969 return YES; |
| 2971 } | 2970 } |
| 2972 | 2971 |
| 2973 #pragma mark - | 2972 #pragma mark - |
| 2974 #pragma mark WebUI | 2973 #pragma mark WebUI |
| 2975 | 2974 |
| 2976 - (void)createWebUIForURL:(const GURL&)URL { | 2975 - (void)createWebUIForURL:(const GURL&)URL { |
| 2977 _webStateImpl->CreateWebUI(URL); | 2976 _webStateImpl->CreateWebUI(URL); |
| (...skipping 896 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3874 if (!_externalRequest || !_externalRequest->window_name) | 3873 if (!_externalRequest || !_externalRequest->window_name) |
| 3875 return @""; | 3874 return @""; |
| 3876 return _externalRequest->window_name; | 3875 return _externalRequest->window_name; |
| 3877 } | 3876 } |
| 3878 | 3877 |
| 3879 - (void)resetExternalRequest { | 3878 - (void)resetExternalRequest { |
| 3880 _externalRequest.reset(); | 3879 _externalRequest.reset(); |
| 3881 } | 3880 } |
| 3882 | 3881 |
| 3883 @end | 3882 @end |
| OLD | NEW |