summaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorAndrej Mihajlov <and@mullvad.net>2023-08-24 11:15:03 +0200
committerAndrej Mihajlov <and@mullvad.net>2023-08-24 11:15:03 +0200
commit3ef2b247461a72809cdbca0d753bd308e984ebf7 (patch)
treeef3622b2f55c51afbdb5dece5f031c127ad3039a
parentf8d2e37a08c555c80478fc93ca9c9bf1bb2f84fa (diff)
parentd7edb2acd90b95479a1e179ce027460bedff22bd (diff)
downloadmullvadvpn-3ef2b247461a72809cdbca0d753bd308e984ebf7.tar.xz
mullvadvpn-3ef2b247461a72809cdbca0d753bd308e984ebf7.zip
Merge branch 'fix-http-response-cast-crash-ios-211'
-rw-r--r--ios/MullvadREST/RESTError.swift16
-rw-r--r--ios/MullvadREST/RESTNetworkOperation.swift62
-rw-r--r--ios/MullvadREST/RESTResponseHandler.swift3
3 files changed, 32 insertions, 49 deletions
diff --git a/ios/MullvadREST/RESTError.swift b/ios/MullvadREST/RESTError.swift
index cc8e1e9ecb..1fdb255b81 100644
--- a/ios/MullvadREST/RESTError.swift
+++ b/ios/MullvadREST/RESTError.swift
@@ -122,9 +122,21 @@ extension REST {
}
}
- public struct NoTransportError: LocalizedError {
+ public enum InternalTransportError: LocalizedError {
+ /// Programmer error. Indicates that REST framework is not configured with any transport.
+ case noTransport
+
+ /// Indicates that the transport returned something else but `HTTPURLResponse` upon success.
+ /// Likely a programmer error.
+ case invalidResponse(URLResponse?)
+
public var errorDescription: String? {
- "Transport is not configured."
+ switch self {
+ case .noTransport:
+ return "Transport is not configured."
+ case let .invalidResponse(response):
+ return "Received invalid response. Expected HTTPURLResponse, got \(response.map { "\($0.self)" } ?? "(nil)")."
+ }
}
}
}
diff --git a/ios/MullvadREST/RESTNetworkOperation.swift b/ios/MullvadREST/RESTNetworkOperation.swift
index 8828c54453..27428a2755 100644
--- a/ios/MullvadREST/RESTNetworkOperation.swift
+++ b/ios/MullvadREST/RESTNetworkOperation.swift
@@ -129,10 +129,7 @@ extension REST {
private func didFailToRequestAuthorization(_ error: Swift.Error) {
dispatchPrecondition(condition: .onQueue(dispatchQueue))
- logger.error(
- error: error,
- message: "Failed to request authorization."
- )
+ logger.error(error: error, message: "Failed to request authorization.")
finish(result: .failure(error))
}
@@ -143,7 +140,7 @@ extension REST {
let transport = transportProvider()
guard let transport else {
logger.error("Failed to obtain transport.")
- finish(result: .failure(REST.Error.transport(NoTransportError())))
+ finish(result: .failure(REST.Error.transport(InternalTransportError.noTransport)))
return
}
@@ -158,20 +155,17 @@ extension REST {
guard let self else { return }
dispatchQueue.async {
if let error {
+ let restError: REST.Error = (error as? URLError).map { .network($0) } ?? .transport(error)
+
+ self.didReceiveError(restError, transport: transport, endpoint: endpoint)
+ } else if let httpResponse = response as? HTTPURLResponse {
+ self.didReceiveURLResponse(httpResponse, data: data ?? Data(), endpoint: endpoint)
+ } else {
self.didReceiveError(
- error,
+ .transport(InternalTransportError.invalidResponse(response)),
transport: transport,
endpoint: endpoint
)
- } else {
- let httpResponse = response as! HTTPURLResponse
- let data = data ?? Data()
-
- self.didReceiveURLResponse(
- httpResponse,
- data: data,
- endpoint: endpoint
- )
}
}
}
@@ -180,37 +174,23 @@ extension REST {
private func didFailToCreateURLRequest(_ error: REST.Error) {
dispatchPrecondition(condition: .onQueue(dispatchQueue))
- logger.error(
- error: error,
- message: "Failed to create URLRequest."
- )
+ logger.error(error: error, message: "Failed to create URLRequest.")
finish(result: .failure(error))
}
- private func didReceiveError(
- _ error: Swift.Error,
- transport: RESTTransport,
- endpoint: AnyIPEndpoint
- ) {
+ private func didReceiveError(_ error: REST.Error, transport: RESTTransport, endpoint: AnyIPEndpoint) {
dispatchPrecondition(condition: .onQueue(dispatchQueue))
- if case URLError.cancelled = error {
+ if case .network(URLError.cancelled) = error {
finish(result: .failure(OperationError.cancelled))
} else {
- logger.error(
- error: error,
- message: "Failed to perform request to \(endpoint) using \(transport.name)."
- )
+ logger.error(error: error, message: "Failed to perform request to \(endpoint) using \(transport.name).")
retryRequest(with: error)
}
}
- private func didReceiveURLResponse(
- _ response: HTTPURLResponse,
- data: Data,
- endpoint: AnyIPEndpoint
- ) {
+ private func didReceiveURLResponse(_ response: HTTPURLResponse, data: Data, endpoint: AnyIPEndpoint) {
dispatchPrecondition(condition: .onQueue(dispatchQueue))
logger.debug("Response: \(response.statusCode).")
@@ -246,13 +226,13 @@ extension REST {
}
}
- private func retryRequest(with error: Swift.Error) {
+ private func retryRequest(with error: REST.Error) {
// Check if retry count is not exceeded.
guard retryCount < retryStrategy.maxRetryCount else {
if retryStrategy.maxRetryCount > 0 {
logger.debug("Ran out of retry attempts (\(retryStrategy.maxRetryCount))")
}
- finish(result: .failure(wrapRequestError(error)))
+ finish(result: .failure(error))
return
}
@@ -268,7 +248,7 @@ extension REST {
guard let waitDelay = retryDelayIterator.next() else {
logger.debug("Retry delay iterator failed to produce next value.")
- finish(result: .failure(wrapRequestError(error)))
+ finish(result: .failure(error))
return
}
@@ -290,13 +270,5 @@ extension REST {
retryTimer = timer
}
-
- private func wrapRequestError(_ error: Swift.Error) -> REST.Error {
- if let error = error as? URLError {
- return .network(error)
- } else {
- return .transport(error)
- }
- }
}
}
diff --git a/ios/MullvadREST/RESTResponseHandler.swift b/ios/MullvadREST/RESTResponseHandler.swift
index 5b8ee99ce6..7d16fcdf7f 100644
--- a/ios/MullvadREST/RESTResponseHandler.swift
+++ b/ios/MullvadREST/RESTResponseHandler.swift
@@ -12,8 +12,7 @@ import MullvadTypes
protocol RESTResponseHandler {
associatedtype Success
- func handleURLResponse(_ response: HTTPURLResponse, data: Data) -> REST
- .ResponseHandlerResult<Success>
+ func handleURLResponse(_ response: HTTPURLResponse, data: Data) -> REST.ResponseHandlerResult<Success>
}
extension REST {