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 |