diff options
| author | Andrej Mihajlov <and@mullvad.net> | 2021-12-20 14:16:31 +0100 |
|---|---|---|
| committer | Andrej Mihajlov <and@mullvad.net> | 2021-12-21 15:21:32 +0100 |
| commit | 71e24d6a009fe8757fe9f974bed6e837e1ed46ba (patch) | |
| tree | c077a13fab8d2f67512f7f5f7677e57a6836c457 | |
| parent | 220948c522328928c16faafca5a553c6bce2e95e (diff) | |
| download | mullvadvpn-71e24d6a009fe8757fe9f974bed6e837e1ed46ba.tar.xz mullvadvpn-71e24d6a009fe8757fe9f974bed6e837e1ed46ba.zip | |
REST: handle success response codes defensively
| -rw-r--r-- | ios/MullvadVPN/REST/HTTP.swift | 29 | ||||
| -rw-r--r-- | ios/MullvadVPN/REST/RESTClient.swift | 46 |
2 files changed, 23 insertions, 52 deletions
diff --git a/ios/MullvadVPN/REST/HTTP.swift b/ios/MullvadVPN/REST/HTTP.swift index e5d7940e03..595809ee0e 100644 --- a/ios/MullvadVPN/REST/HTTP.swift +++ b/ios/MullvadVPN/REST/HTTP.swift @@ -20,32 +20,11 @@ struct HTTPMethod: RawRepresentable { } } -// HTTP status codes -struct HTTPStatus: RawRepresentable, Equatable { - static let ok = HTTPStatus(rawValue: 200) - static let created = HTTPStatus(rawValue: 201) - static let noContent = HTTPStatus(rawValue: 204) - static let notModified = HTTPStatus(rawValue: 304) +enum HTTPStatus { + static let notModified = 304 - let rawValue: Int - init(rawValue value: Int) { - rawValue = value - } - - static func == (lhs: Self, rhs: Self) -> Bool { - return lhs.rawValue == rhs.rawValue - } - - static func == (lhs: Self, rhs: Int) -> Bool { - return lhs.rawValue == rhs - } - - static func == (lhs: Int, rhs: Self) -> Bool { - return lhs == rhs.rawValue - } - - static func ~= (lhs: Self, rhs: Int) -> Bool { - return lhs.rawValue == rhs + static func isSuccess(_ code: Int) -> Bool { + return (200..<300).contains(code) } } diff --git a/ios/MullvadVPN/REST/RESTClient.swift b/ios/MullvadVPN/REST/RESTClient.swift index 478fe5b4e6..bc9f49301f 100644 --- a/ios/MullvadVPN/REST/RESTClient.swift +++ b/ios/MullvadVPN/REST/RESTClient.swift @@ -65,7 +65,7 @@ extension REST { let restResult = responseResult .mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<AccountResponse, REST.Error> in - if httpResponse.statusCode == HTTPStatus.created { + if HTTPStatus.isSuccess(httpResponse.statusCode) { return Self.decodeSuccessResponse(AccountResponse.self, from: data) } else { return Self.decodeErrorResponseAndMapToServerError(from: data) @@ -86,7 +86,7 @@ extension REST { let dataTask = self.dataTask(request: request) { responseResult in let restResult = responseResult.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<[AnyIPEndpoint], REST.Error> in - if httpResponse.statusCode == HTTPStatus.ok { + if HTTPStatus.isSuccess(httpResponse.statusCode) { return Self.decodeSuccessResponse([AnyIPEndpoint].self, from: data) } else { return Self.decodeErrorResponseAndMapToServerError(from: data) @@ -110,18 +110,15 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<ServerRelaysCacheResponse, REST.Error> in - switch httpResponse.statusCode { - case .ok: + if HTTPStatus.isSuccess(httpResponse.statusCode) { return Self.decodeSuccessResponse(ServerRelaysResponse.self, from: data) .map { serverRelays in let newEtag = httpResponse.value(forCaseInsensitiveHTTPHeaderField: HTTPHeader.etag) return .newContent(newEtag, serverRelays) } - - case .notModified where etag != nil: + } else if httpResponse.statusCode == HTTPStatus.notModified && etag != nil { return .success(.notModified) - - default: + } else { return Self.decodeErrorResponseAndMapToServerError(from: data) } } @@ -142,7 +139,7 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<AccountResponse, REST.Error> in - if httpResponse.statusCode == HTTPStatus.ok { + if HTTPStatus.isSuccess(httpResponse.statusCode) { return Self.decodeSuccessResponse(AccountResponse.self, from: data) } else { return Self.decodeErrorResponseAndMapToServerError(from: data) @@ -169,7 +166,7 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<WireguardAddressesResponse, REST.Error> in - if httpResponse.statusCode == HTTPStatus.ok { + if HTTPStatus.isSuccess(httpResponse.statusCode) { return Self.decodeSuccessResponse(WireguardAddressesResponse.self, from: data) } else { return Self.decodeErrorResponseAndMapToServerError(from: data) @@ -198,10 +195,9 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<WireguardAddressesResponse, REST.Error> in - switch httpResponse.statusCode { - case .created, .ok: + if HTTPStatus.isSuccess(httpResponse.statusCode) { return Self.decodeSuccessResponse(WireguardAddressesResponse.self, from: data) - default: + } else { return Self.decodeErrorResponseAndMapToServerError(from: data) } } @@ -230,7 +226,7 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<WireguardAddressesResponse, REST.Error> in - if httpResponse.statusCode == HTTPStatus.created { + if HTTPStatus.isSuccess(httpResponse.statusCode) { return Self.decodeSuccessResponse(WireguardAddressesResponse.self, from: data) } else { return Self.decodeErrorResponseAndMapToServerError(from: data) @@ -257,7 +253,7 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<(), REST.Error> in - if httpResponse.statusCode == HTTPStatus.noContent { + if HTTPStatus.isSuccess(httpResponse.statusCode) { return .success(()) } else { return Self.decodeErrorResponseAndMapToServerError(from: data) @@ -287,20 +283,16 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<CreateApplePaymentResponse, REST.Error> in - switch httpResponse.statusCode { - case HTTPStatus.ok: - return REST.Client.decodeSuccessResponse(CreateApplePaymentRawResponse.self, from: data) - .map { (response) in - return .noTimeAdded(response.newExpiry) - } - - case HTTPStatus.created: + if HTTPStatus.isSuccess(httpResponse.statusCode) { return REST.Client.decodeSuccessResponse(CreateApplePaymentRawResponse.self, from: data) .map { (response) in - return .timeAdded(response.timeAdded, response.newExpiry) + if response.timeAdded > 0 { + return .timeAdded(response.timeAdded, response.newExpiry) + } else { + return .noTimeAdded(response.newExpiry) + } } - - default: + } else { return Self.decodeErrorResponseAndMapToServerError(from: data) } } @@ -324,7 +316,7 @@ extension REST { let dataTask = self.dataTask(request: request) { restResponse in let restResult = restResponse.mapError(self.mapNetworkError) .flatMap { httpResponse, data -> Result<(), REST.Error> in - if httpResponse.statusCode == HTTPStatus.noContent { + if HTTPStatus.isSuccess(httpResponse.statusCode) { return .success(()) } else { return Self.decodeErrorResponseAndMapToServerError(from: data) |
