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