Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / ios / web / web_state / error_translation_util.mm
blob9c6cbd00e3a1d971b994af08cd88351d1b903c8c
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #import "ios/web/web_state/error_translation_util.h"
7 #include <CFNetwork/CFNetwork.h>
9 #import "base/ios/ns_error_util.h"
10 #include "base/mac/scoped_nsobject.h"
11 #include "net/base/net_errors.h"
13 namespace web {
15 namespace {
16 // Translates an iOS error to a net error using |net_error_code| as an
17 // out-parameter.  Returns true if a valid translation was found.
18 bool GetNetErrorFromIOSErrorCode(NSInteger ios_error_code,
19                                  NSInteger* net_error_code) {
20   DCHECK(net_error_code);
21   bool translation_success = true;
22   switch (ios_error_code) {
23     case kCFURLErrorBackgroundSessionInUseByAnotherProcess:
24       *net_error_code = net::ERR_ACCESS_DENIED;
25       break;
26     case kCFURLErrorBackgroundSessionWasDisconnected:
27       *net_error_code = net::ERR_CONNECTION_ABORTED;
28       break;
29     case kCFURLErrorUnknown:
30       *net_error_code = net::ERR_FAILED;
31       break;
32     case kCFURLErrorCancelled:
33       *net_error_code = net::ERR_ABORTED;
34       break;
35     case kCFURLErrorBadURL:
36       *net_error_code = net::ERR_INVALID_URL;
37       break;
38     case kCFURLErrorTimedOut:
39       *net_error_code = net::ERR_CONNECTION_TIMED_OUT;
40       break;
41     case kCFURLErrorUnsupportedURL:
42       *net_error_code = net::ERR_UNKNOWN_URL_SCHEME;
43       break;
44     case kCFURLErrorCannotFindHost:
45       *net_error_code = net::ERR_NAME_NOT_RESOLVED;
46       break;
47     case kCFURLErrorCannotConnectToHost:
48       *net_error_code = net::ERR_CONNECTION_FAILED;
49       break;
50     case kCFURLErrorNetworkConnectionLost:
51       *net_error_code = net::ERR_INTERNET_DISCONNECTED;
52       break;
53     case kCFURLErrorDNSLookupFailed:
54       *net_error_code = net::ERR_NAME_RESOLUTION_FAILED;
55       break;
56     case kCFURLErrorHTTPTooManyRedirects:
57       *net_error_code = net::ERR_TOO_MANY_REDIRECTS;
58       break;
59     case kCFURLErrorResourceUnavailable:
60       *net_error_code = net::ERR_INSUFFICIENT_RESOURCES;
61       break;
62     case kCFURLErrorNotConnectedToInternet:
63       *net_error_code = net::ERR_INTERNET_DISCONNECTED;
64       break;
65     case kCFURLErrorRedirectToNonExistentLocation:
66       *net_error_code = net::ERR_NAME_NOT_RESOLVED;
67       break;
68     case kCFURLErrorBadServerResponse:
69       *net_error_code = net::ERR_INVALID_RESPONSE;
70       break;
71     case kCFURLErrorUserCancelledAuthentication:
72       *net_error_code = net::ERR_ABORTED;
73       break;
74     case kCFURLErrorUserAuthenticationRequired:
75       // TODO(kkhorimoto): ERR_SSL_RENEGOTIATION_REQUESTED is more specific than
76       // the kCFURLErrorUserAuthenticationRequired.  Consider adding a new net
77       // error for this scenario.
78       *net_error_code = net::ERR_SSL_RENEGOTIATION_REQUESTED;
79       break;
80     case kCFURLErrorZeroByteResource:
81       *net_error_code = net::ERR_EMPTY_RESPONSE;
82       break;
83     case kCFURLErrorCannotDecodeRawData:
84       *net_error_code = net::ERR_CONTENT_DECODING_FAILED;
85       break;
86     case kCFURLErrorCannotDecodeContentData:
87       *net_error_code = net::ERR_CONTENT_DECODING_FAILED;
88       break;
89     case kCFURLErrorCannotParseResponse:
90       *net_error_code = net::ERR_INVALID_RESPONSE;
91       break;
92     case kCFURLErrorInternationalRoamingOff:
93       // TODO(kkhorimoto): Create new net error for disabled intl roaming.
94       *net_error_code = net::ERR_INTERNET_DISCONNECTED;
95       break;
96     case kCFURLErrorCallIsActive:
97       *net_error_code = net::ERR_CONNECTION_FAILED;
98       break;
99     case kCFURLErrorDataNotAllowed:
100       // TODO(kkhorimoto): Create new net error for disabled data usage.
101       *net_error_code = net::ERR_INTERNET_DISCONNECTED;
102       break;
103     case kCFURLErrorRequestBodyStreamExhausted:
104       *net_error_code = net::ERR_CONTENT_LENGTH_MISMATCH;
105       break;
106     case kCFURLErrorFileDoesNotExist:
107       *net_error_code = net::ERR_FILE_NOT_FOUND;
108       break;
109     case kCFURLErrorFileIsDirectory:
110       *net_error_code = net::ERR_INVALID_HANDLE;
111       break;
112     case kCFURLErrorNoPermissionsToReadFile:
113       *net_error_code = net::ERR_ACCESS_DENIED;
114       break;
115     case kCFURLErrorDataLengthExceedsMaximum:
116       *net_error_code = net::ERR_FILE_TOO_BIG;
117       break;
118     default:
119       translation_success = false;
120       break;
121   }
122   return translation_success;
124 }  // namespace
126 NSError* NetErrorFromError(NSError* error) {
127   DCHECK(error);
128   NSError* underlying_error =
129       base::ios::GetFinalUnderlyingErrorFromError(error);
130   NSError* translated_error = error;
131   if ([underlying_error.domain isEqualToString:NSURLErrorDomain] ||
132       [underlying_error.domain
133           isEqualToString:static_cast<NSString*>(kCFErrorDomainCFNetwork)]) {
134     // Attempt to translate NSURL and CFNetwork error codes into their
135     // corresponding net error codes.
136     NSInteger net_error_code = net::OK;
137     if (GetNetErrorFromIOSErrorCode(underlying_error.code, &net_error_code)) {
138       NSString* net_error_domain =
139           [NSString stringWithUTF8String:net::kErrorDomain];
140       NSError* net_error = [NSError errorWithDomain:net_error_domain
141                                                code:net_error_code
142                                            userInfo:nil];
143       translated_error =
144           base::ios::ErrorWithAppendedUnderlyingError(error, net_error);
145     }
146   }
147   return translated_error;
149 }  // namespace web