-
Notifications
You must be signed in to change notification settings - Fork 369
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Enable testing API access with a given configuration
- Loading branch information
1 parent
f4ec9f8
commit a34caac
Showing
15 changed files
with
259 additions
and
31 deletions.
There are no files selected for viewing
55 changes: 55 additions & 0 deletions
55
ios/MullvadREST/ApiHandlers/APIAvailabilityTestRequest.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,55 @@ | ||
// | ||
// APIAvailabilityTestRequest.swift | ||
// MullvadREST | ||
// | ||
// Created by Marco Nikic on 2024-01-08. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import MullvadTypes | ||
|
||
extension REST { | ||
public struct APIAvailabilityTestRequest { | ||
let transport: RESTTransport | ||
|
||
public init(transport: RESTTransport) { | ||
self.transport = transport | ||
} | ||
|
||
/// Executes an HTTP `HEAD` request to the "api-addrs" endpoint. | ||
/// | ||
/// - Parameter completion: Completes with `nil` if the request was successful, and `Error` otherwise. | ||
/// - Returns: A cancellable token to cancel the request inflight. | ||
public func makeRequest(completion: @escaping (Swift.Error?) -> Void) -> Cancellable { | ||
do { | ||
let factory = RequestFactory( | ||
hostname: defaultAPIHostname, | ||
pathPrefix: "/app/v1", | ||
networkTimeout: defaultAPINetworkTimeout, | ||
bodyEncoder: JSONEncoder() | ||
) | ||
var request = try factory.createRequest( | ||
endpoint: defaultAPIEndpoint, | ||
method: .head, | ||
pathTemplate: "api-addrs" | ||
) | ||
request.urlRequest.cachePolicy = .reloadIgnoringLocalCacheData | ||
|
||
return transport.sendRequest(request.urlRequest) { _, response, error in | ||
// Any response in the form of `HTTPURLResponse` means that the API was reached successfully | ||
// and implying an HTTP server is running, therefore the test is considered successful. | ||
guard response is HTTPURLResponse else { | ||
completion(error) | ||
return | ||
} | ||
completion(nil) | ||
} | ||
|
||
} catch { | ||
completion(error) | ||
} | ||
return AnyCancellable() | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
58 changes: 58 additions & 0 deletions
58
ios/MullvadREST/Transport/ProxyConfigurationTransportProvider.swift
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
// | ||
// ProxyConfigurationTransportProvider.swift | ||
// MullvadREST | ||
// | ||
// Created by Marco Nikic on 2024-01-19. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
import Foundation | ||
import MullvadSettings | ||
import MullvadTypes | ||
|
||
/// Allows the creation of `RESTTransport` objects that bypass the network routing logic provided by `TransportProvider`. | ||
public class ProxyConfigurationTransportProvider { | ||
private let shadowsocksLoader: ShadowsocksLoaderProtocol | ||
private let addressCache: REST.AddressCache | ||
|
||
public init(shadowsocksLoader: ShadowsocksLoaderProtocol, addressCache: REST.AddressCache) { | ||
self.shadowsocksLoader = shadowsocksLoader | ||
self.addressCache = addressCache | ||
} | ||
|
||
public func makeTransport(with configuration: PersistentProxyConfiguration) throws -> RESTTransport { | ||
let urlSession = REST.makeURLSession() | ||
switch configuration { | ||
case .direct: | ||
return URLSessionTransport(urlSession: urlSession) | ||
case .bridges: | ||
let shadowsocksConfiguration = try shadowsocksLoader.load() | ||
return ShadowsocksTransport( | ||
urlSession: urlSession, | ||
configuration: shadowsocksConfiguration, | ||
addressCache: addressCache | ||
) | ||
case let .shadowsocks(shadowSocksConfiguration): | ||
return ShadowsocksTransport( | ||
urlSession: urlSession, | ||
configuration: ShadowsocksConfiguration( | ||
address: shadowSocksConfiguration.server, | ||
port: shadowSocksConfiguration.port, | ||
password: shadowSocksConfiguration.password, | ||
cipher: shadowSocksConfiguration.cipher.rawValue.description | ||
), | ||
addressCache: addressCache | ||
) | ||
case let .socks5(socksConfiguration): | ||
return URLSessionSocks5Transport( | ||
urlSession: urlSession, | ||
configuration: Socks5Configuration( | ||
proxyEndpoint: socksConfiguration.toAnyIPEndpoint, | ||
username: socksConfiguration.credential?.username, | ||
password: socksConfiguration.credential?.password | ||
), | ||
addressCache: addressCache | ||
) | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,40 @@ | ||
// | ||
// HeadRequestTests.swift | ||
// MullvadRESTTests | ||
// | ||
// Created by Marco Nikic on 2024-01-22. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
@testable import MullvadREST | ||
import XCTest | ||
|
||
class HeadRequestTests: XCTestCase { | ||
func testSuccessfulRequestHasNoError() throws { | ||
let transport = RESTTransportStub(data: Data(), response: HTTPURLResponse()) | ||
let request = REST.APIAvailabilityTestRequest(transport: transport) | ||
|
||
let successfulRequestExpectation = expectation(description: "HEAD request completed") | ||
_ = request.makeRequest { error in | ||
if error == nil { | ||
successfulRequestExpectation.fulfill() | ||
} | ||
} | ||
|
||
wait(for: [successfulRequestExpectation], timeout: 1) | ||
} | ||
|
||
func testRequestWithErrors() throws { | ||
let transport = RESTTransportStub(error: URLError(.timedOut)) | ||
let request = REST.APIAvailabilityTestRequest(transport: transport) | ||
|
||
let failedRequestExpectation = expectation(description: "HEAD request failed") | ||
_ = request.makeRequest { error in | ||
if error != nil { | ||
failedRequestExpectation.fulfill() | ||
} | ||
} | ||
|
||
wait(for: [failedRequestExpectation], timeout: 1) | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
// | ||
// RESTTransportStub.swift | ||
// MullvadRESTTests | ||
// | ||
// Created by Marco Nikic on 2024-01-22. | ||
// Copyright © 2024 Mullvad VPN AB. All rights reserved. | ||
// | ||
|
||
@testable import MullvadREST | ||
@testable import MullvadTypes | ||
import XCTest | ||
|
||
struct RESTTransportStub: RESTTransport { | ||
let name = "transport-stub" | ||
|
||
var data: Data? | ||
var response: URLResponse? | ||
var error: Error? | ||
|
||
func sendRequest( | ||
_ request: URLRequest, | ||
completion: @escaping (Data?, URLResponse?, Error?) -> Void | ||
) -> Cancellable { | ||
completion(data, response, error) | ||
return AnyCancellable() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.