Skip to content

Commit 4731816

Browse files
authored
Use ephemeral URLSession to send .org REST API requests (#23715)
* Use ephemeral URLSession to send .org REST API requests * Fix grammar issues in code comment * Change static functions to initialisers * Remove an unnecessary throw
1 parent df1ad84 commit 4731816

File tree

3 files changed

+29
-13
lines changed

3 files changed

+29
-13
lines changed

WordPress/Classes/Networking/WordPressClient.swift

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -8,20 +8,20 @@ struct WordPressSite {
88
case selfHosted(username: String, authToken: String)
99
}
1010

11-
let baseUrl: String
11+
let baseUrl: URL
1212
let type: WordPressSite.SiteType
1313

1414
init(baseUrl: ParsedUrl, type: WordPressSite.SiteType) {
15-
self.baseUrl = baseUrl.url()
15+
self.baseUrl = baseUrl.asURL()
1616
self.type = type
1717
}
1818

19-
static func from(blog: Blog) throws -> WordPressSite {
19+
init(blog: Blog) throws {
2020
let url = try ParsedUrl.parse(input: blog.getUrlString())
2121
if let account = blog.account {
22-
return WordPressSite(baseUrl: url, type: .dotCom(authToken: account.authToken))
22+
self.init(baseUrl: url, type: .dotCom(authToken: account.authToken))
2323
} else {
24-
return WordPressSite(baseUrl: url, type: .selfHosted(
24+
self.init(baseUrl: url, type: .selfHosted(
2525
username: try blog.getUsername(),
2626
authToken: try blog.getApplicationToken())
2727
)
@@ -45,16 +45,32 @@ actor WordPressClient {
4545
self.rootUrl = rootUrl.url()
4646
}
4747

48-
static func `for`(site: WordPressSite, in session: URLSession) throws -> WordPressClient {
49-
let parsedUrl = try ParsedUrl.parse(input: site.baseUrl)
48+
init(site: WordPressSite) {
49+
// `site.barUrl` is a legal HTTP URL, which should be convertable to the `ParsedUrl` type.
50+
let parsedUrl: ParsedUrl
51+
do {
52+
parsedUrl = try ParsedUrl.parse(input: site.baseUrl.absoluteString)
53+
} catch {
54+
fatalError("Failed to cast URL (\(site.baseUrl.absoluteString)) to ParsedUrl: \(error)")
55+
}
56+
57+
// Currently, the app supports both account passwords and application passwords.
58+
// When a site is initially signed in with an account password, WordPress login cookies are stored
59+
// in `URLSession.shared`. After switching the site to application password authentication,
60+
// the stored cookies may interfere with application-password authentication, resulting in 401
61+
// errors from the REST API.
62+
//
63+
// To avoid this issue, we'll use an ephemeral URLSession for now (which stores cookies in memory
64+
// rather than using the shared one on disk).
65+
let session = URLSession(configuration: .ephemeral)
5066

5167
switch site.type {
5268
case let .dotCom(authToken):
5369
let api = WordPressAPI(urlSession: session, baseUrl: parsedUrl, authenticationStategy: .authorizationHeader(token: authToken))
54-
return WordPressClient(api: api, rootUrl: parsedUrl)
70+
self.init(api: api, rootUrl: parsedUrl)
5571
case .selfHosted(let username, let authToken):
5672
let api = WordPressAPI.init(urlSession: session, baseUrl: parsedUrl, authenticationStategy: .init(username: username, password: authToken))
57-
return WordPressClient(api: api, rootUrl: parsedUrl)
73+
self.init(api: api, rootUrl: parsedUrl)
5874
}
5975
}
6076

WordPress/Classes/ViewRelated/Blog/Blog Dashboard/ViewModel/BlogDashboardViewModel.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ final class BlogDashboardViewModel {
108108
var _error: Error?
109109

110110
do {
111-
self.wordpressClient = try WordPressClient.for(site: .from(blog: self.blog), in: .shared)
111+
self.wordpressClient = try WordPressClient(site: .init(blog: self.blog))
112112
} catch {
113113
_error = error
114114
self.wordpressClient = nil

WordPress/Classes/ViewRelated/Blog/Blog Details/BlogDetailsViewController+SectionHelpers.swift

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -120,7 +120,7 @@ extension BlogDetailsViewController {
120120

121121
@objc func shouldShowApplicationPasswordRow() -> Bool {
122122
// Only available for application-password authenticated self-hosted sites.
123-
return self.blog.account == nil && self.blog.userID != nil && (try? WordPressSite.from(blog: self.blog)) != nil
123+
return self.blog.account == nil && self.blog.userID != nil && (try? WordPressSite(blog: self.blog)) != nil
124124
}
125125

126126
private func createApplicationPasswordService() -> ApplicationPasswordService? {
@@ -129,8 +129,8 @@ extension BlogDetailsViewController {
129129
}
130130

131131
do {
132-
let site = try WordPressSite.from(blog: self.blog)
133-
let client = try WordPressClient.for(site: site, in: .shared)
132+
let site = try WordPressSite(blog: self.blog)
133+
let client = WordPressClient(site: site)
134134
return ApplicationPasswordService(api: client, currentUserId: userId)
135135
} catch {
136136
DDLogError("Failed to create WordPressClient: \(error)")

0 commit comments

Comments
 (0)