@@ -11,7 +11,12 @@ public protocol EditorHTTPClientProtocol: Sendable {
1111///
1212/// Implement this protocol to inspect or log all network requests.
1313public protocol EditorHTTPClientDelegate {
14- func didPerformRequest( _ request: URLRequest , response: URLResponse , data: Data )
14+ func didPerformRequest( _ request: URLRequest , response: URLResponse , data: EditorResponseData )
15+ }
16+
17+ public enum EditorResponseData {
18+ case bytes( Data )
19+ case file( URL )
1520}
1621
1722/// A WordPress REST API error response.
@@ -35,17 +40,17 @@ public actor EditorHTTPClient: EditorHTTPClientProtocol {
3540 /// An unexpected error occurred with the given response data and status code.
3641 case unknown( response: Data , statusCode: Int )
3742 }
38-
39- private let urlSession : URLSession
43+
44+ private let urlSession : URLSessionProtocol
4045 private let authHeader : String
4146 private let delegate : EditorHTTPClientDelegate ?
42- private let requestTimeout : TimeInterval
47+ private let requestTimeout : TimeInterval ?
4348
4449 public init (
45- urlSession: URLSession ,
50+ urlSession: URLSessionProtocol ,
4651 authHeader: String ,
4752 delegate: EditorHTTPClientDelegate ? = nil ,
48- requestTimeout: TimeInterval = 60 // `URLRequest` default
53+ requestTimeout: TimeInterval ? = nil
4954 ) {
5055 self . urlSession = urlSession
5156 self . authHeader = authHeader
@@ -54,17 +59,15 @@ public actor EditorHTTPClient: EditorHTTPClientProtocol {
5459 }
5560
5661 public func perform( _ urlRequest: URLRequest ) async throws -> ( Data , HTTPURLResponse ) {
57- var mutableRequest = urlRequest
58- mutableRequest. setValue ( self . authHeader, forHTTPHeaderField: " Authorization " )
59- mutableRequest. timeoutInterval = self . requestTimeout
6062
61- let ( data, response) = try await self . urlSession. data ( for: mutableRequest)
62- self . delegate? . didPerformRequest ( mutableRequest, response: response, data: data)
63+ let configuredRequest = self . configureRequest ( urlRequest)
64+ let ( data, response) = try await self . urlSession. data ( for: configuredRequest)
65+ self . delegate? . didPerformRequest ( configuredRequest, response: response, data: . bytes( data) )
6366
6467 let httpResponse = response as! HTTPURLResponse
6568
6669 guard 200 ... 299 ~= httpResponse. statusCode else {
67- Logger . http. error ( " 📡 HTTP error fetching \( mutableRequest . url!. absoluteString) : \( httpResponse. statusCode) " )
70+ Logger . http. error ( " 📡 HTTP error fetching \( configuredRequest . url!. absoluteString) : \( httpResponse. statusCode) " )
6871
6972 if let wpError = try ? JSONDecoder ( ) . decode ( WPError . self, from: data) {
7073 throw ClientError . wpError ( wpError)
@@ -77,20 +80,35 @@ public actor EditorHTTPClient: EditorHTTPClientProtocol {
7780 }
7881
7982 public func download( _ urlRequest: URLRequest ) async throws -> ( URL , HTTPURLResponse ) {
80- var mutableRequest = urlRequest
81- mutableRequest. addValue ( self . authHeader, forHTTPHeaderField: " Authorization " )
82- mutableRequest. timeoutInterval = self . requestTimeout
8383
84- let ( url, response) = try await self . urlSession. download ( for: mutableRequest)
84+ let configuredRequest = self . configureRequest ( urlRequest)
85+ let ( url, response) = try await self . urlSession. download ( for: configuredRequest, delegate: nil )
86+ self . delegate? . didPerformRequest ( configuredRequest, response: response, data: . file( url) )
8587
8688 let httpResponse = response as! HTTPURLResponse
8789
8890 guard 200 ... 299 ~= httpResponse. statusCode else {
89- Logger . http. error ( " 📡 HTTP error fetching \( mutableRequest . url!. absoluteString) : \( httpResponse. statusCode) " )
91+ Logger . http. error ( " 📡 HTTP error fetching \( configuredRequest . url!. absoluteString) : \( httpResponse. statusCode) " )
9092
9193 throw ClientError . downloadFailed ( statusCode: httpResponse. statusCode)
9294 }
9395
9496 return ( url, response as! HTTPURLResponse )
9597 }
98+
99+ private func configureRequest( _ request: URLRequest ) -> URLRequest {
100+ var mutableRequest = request
101+ mutableRequest. addValue ( self . authHeader, forHTTPHeaderField: " Authorization " )
102+
103+ if let requestTimeout {
104+ mutableRequest. timeoutInterval = requestTimeout
105+ }
106+
107+ // Prevent wordpress_logged_in cookies from being sent, which could interfere with
108+ // application password authentication in the Authorization header.
109+ // See: https://github.com/wordpress-mobile/GutenbergKit/commit/30ebac210924ecc8e9dee3980c101ef24b1befa6
110+ mutableRequest. httpShouldHandleCookies = false
111+
112+ return mutableRequest
113+ }
96114}
0 commit comments