@@ -18,6 +18,12 @@ public protocol APIQuerying: Sendable {
18
18
completionHandler: @escaping @Sendable ProxyCompletionHandler < [ AnyIPEndpoint ] >
19
19
) -> Cancellable
20
20
21
+ func mullvadApiGetRelayList(
22
+ retryStrategy: REST . RetryStrategy ,
23
+ etag: String ? ,
24
+ completionHandler: @escaping @Sendable ProxyCompletionHandler < REST . ServerRelaysCacheResponse >
25
+ ) -> Cancellable
26
+
21
27
func getAddressList(
22
28
retryStrategy: REST . RetryStrategy ,
23
29
completionHandler: @escaping @Sendable ProxyCompletionHandler < [ AnyIPEndpoint ] >
@@ -71,10 +77,56 @@ extension REST {
71
77
with: responseDecoder
72
78
)
73
79
80
+ return createNetworkOperation (
81
+ request: . getAddressList( retryStrategy) ,
82
+ responseHandler: responseHandler,
83
+ completionHandler: completionHandler
84
+ )
85
+ }
86
+
87
+ public func mullvadApiGetRelayList(
88
+ retryStrategy: REST . RetryStrategy ,
89
+ etag: String ? ,
90
+ completionHandler: @escaping @Sendable ProxyCompletionHandler < REST . ServerRelaysCacheResponse >
91
+ ) -> Cancellable {
92
+ if var etag {
93
+ // Enforce weak validator to account for some backend caching quirks.
94
+ if etag. starts ( with: " \" " ) {
95
+ etag. insert ( contentsOf: " W/ " , at: etag. startIndex)
96
+ }
97
+ }
98
+
99
+ let responseHandler = rustCustomResponseHandler { [ weak self] ( data, responseEtag) in
100
+ // Discarding result since we're only interested in knowing that it's parseable.
101
+ let canDecodeResponse = ( try ? self ? . responseDecoder. decode ( REST . ServerRelaysResponse. self, from: data) ) != nil
102
+
103
+ return if canDecodeResponse {
104
+ if let responseEtag, responseEtag == etag {
105
+ REST . ServerRelaysCacheResponse. notModified
106
+ } else {
107
+ REST . ServerRelaysCacheResponse. newContent ( responseEtag, data)
108
+ }
109
+ } else {
110
+ nil
111
+ }
112
+ }
113
+
114
+ return createNetworkOperation (
115
+ request: . getRelayList( retryStrategy, etag: etag) ,
116
+ responseHandler: responseHandler,
117
+ completionHandler: completionHandler
118
+ )
119
+ }
120
+
121
+ private func createNetworkOperation< Success: Decodable > (
122
+ request: APIRequest ,
123
+ responseHandler: RustResponseHandler < Success > ,
124
+ completionHandler: @escaping @Sendable ProxyCompletionHandler < Success >
125
+ ) -> MullvadApiNetworkOperation < Success > {
74
126
let networkOperation = MullvadApiNetworkOperation (
75
- name: " get-api-addrs " ,
127
+ name: request . name ,
76
128
dispatchQueue: dispatchQueue,
77
- request: . getAddressList ( retryStrategy ) ,
129
+ request: request ,
78
130
transportProvider: configuration. apiTransportProvider,
79
131
responseDecoder: responseDecoder,
80
132
responseHandler: responseHandler,
@@ -314,7 +366,7 @@ extension REST {
314
366
315
367
// MARK: - Response types
316
368
317
- public enum ServerRelaysCacheResponse : Sendable {
369
+ public enum ServerRelaysCacheResponse : Sendable , Decodable {
318
370
case notModified
319
371
case newContent( _ etag: String ? , _ rawData: Data )
320
372
}
0 commit comments