react-native-nitro-fetch 0.1.7 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/android/src/main/java/com/margelo/nitro/nitrofetch/AutoPrefetcher.kt +3 -1
- package/android/src/main/java/com/margelo/nitro/nitrofetch/CronetExtensions.kt +31 -0
- package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroCronet.kt +89 -0
- package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroFetchClient.kt +115 -28
- package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroUrlRequest.kt +35 -0
- package/android/src/main/java/com/margelo/nitro/nitrofetch/NitroUrlRequestBuilder.kt +181 -0
- package/ios/HybridNitroCronet.swift +31 -0
- package/ios/HybridUrlRequest.swift +41 -0
- package/ios/HybridUrlRequestBuilder.swift +255 -0
- package/ios/NitroAutoPrefetcher.swift +3 -1
- package/ios/NitroFetchClient.swift +87 -5
- package/ios/URLSessionExtensions.swift +36 -0
- package/lib/module/NitroCronet.nitro.js +4 -0
- package/lib/module/NitroCronet.nitro.js.map +1 -0
- package/lib/module/NitroInstances.js +1 -0
- package/lib/module/NitroInstances.js.map +1 -1
- package/lib/module/fetch.js +179 -9
- package/lib/module/fetch.js.map +1 -1
- package/lib/typescript/src/NitroCronet.nitro.d.ts +53 -0
- package/lib/typescript/src/NitroCronet.nitro.d.ts.map +1 -0
- package/lib/typescript/src/NitroFetch.nitro.d.ts +10 -0
- package/lib/typescript/src/NitroFetch.nitro.d.ts.map +1 -1
- package/lib/typescript/src/NitroInstances.d.ts +3 -1
- package/lib/typescript/src/NitroInstances.d.ts.map +1 -1
- package/lib/typescript/src/fetch.d.ts +5 -2
- package/lib/typescript/src/fetch.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/nitro.json +34 -6
- package/nitrogen/generated/android/c++/JFunc_void_UrlResponseInfo.hpp +82 -0
- package/nitrogen/generated/android/c++/JFunc_void_UrlResponseInfo_std__shared_ptr_ArrayBuffer__double.hpp +84 -0
- package/nitrogen/generated/android/c++/JFunc_void_UrlResponseInfo_std__string.hpp +82 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_UrlResponseInfo_.hpp +83 -0
- package/nitrogen/generated/android/c++/JFunc_void_std__optional_UrlResponseInfo__RequestException.hpp +85 -0
- package/nitrogen/generated/android/c++/JHttpHeader.hpp +61 -0
- package/nitrogen/generated/android/c++/JHybridNativeStorageSpec.cpp +23 -16
- package/nitrogen/generated/android/c++/JHybridNativeStorageSpec.hpp +20 -21
- package/nitrogen/generated/android/c++/JHybridNitroCronetSpec.cpp +57 -0
- package/nitrogen/generated/android/c++/JHybridNitroCronetSpec.hpp +63 -0
- package/nitrogen/generated/android/c++/JHybridNitroFetchClientSpec.cpp +32 -16
- package/nitrogen/generated/android/c++/JHybridNitroFetchClientSpec.hpp +21 -21
- package/nitrogen/generated/android/c++/JHybridNitroFetchSpec.cpp +22 -15
- package/nitrogen/generated/android/c++/JHybridNitroFetchSpec.hpp +20 -21
- package/nitrogen/generated/android/c++/JHybridUrlRequestBuilderSpec.cpp +123 -0
- package/nitrogen/generated/android/c++/JHybridUrlRequestBuilderSpec.hpp +73 -0
- package/nitrogen/generated/android/c++/JHybridUrlRequestSpec.cpp +69 -0
- package/nitrogen/generated/android/c++/JHybridUrlRequestSpec.hpp +67 -0
- package/nitrogen/generated/android/c++/JNitroFormDataPart.hpp +74 -0
- package/nitrogen/generated/android/c++/JNitroHeader.hpp +7 -3
- package/nitrogen/generated/android/c++/JNitroRequest.hpp +39 -6
- package/nitrogen/generated/android/c++/JNitroRequestMethod.hpp +9 -10
- package/nitrogen/generated/android/c++/JNitroResponse.hpp +9 -4
- package/nitrogen/generated/android/c++/JRequestException.hpp +57 -0
- package/nitrogen/generated/android/c++/JUrlResponseInfo.hpp +146 -0
- package/nitrogen/generated/android/c++/JVariant_ArrayBuffer_String.cpp +26 -0
- package/nitrogen/generated/android/c++/JVariant_ArrayBuffer_String.hpp +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/Func_void_UrlResponseInfo.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/Func_void_UrlResponseInfo_std__shared_ptr_ArrayBuffer__double.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/Func_void_UrlResponseInfo_std__string.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/Func_void_std__optional_UrlResponseInfo_.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/Func_void_std__optional_UrlResponseInfo__RequestException.kt +80 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/HttpHeader.kt +41 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/HybridNativeStorageSpec.kt +18 -16
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/HybridNitroCronetSpec.kt +54 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/HybridNitroFetchClientSpec.kt +23 -16
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/HybridNitroFetchSpec.kt +18 -16
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/HybridUrlRequestBuilderSpec.kt +125 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/HybridUrlRequestSpec.kt +70 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/NitroFormDataPart.kt +50 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/NitroHeader.kt +19 -10
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/NitroRequest.kt +40 -25
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/NitroRequestMethod.kt +3 -1
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/NitroResponse.kt +39 -30
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/RequestException.kt +38 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/UrlResponseInfo.kt +65 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/Variant_ArrayBuffer_String.kt +53 -0
- package/nitrogen/generated/android/kotlin/com/margelo/nitro/nitrofetch/nitrofetchOnLoad.kt +1 -1
- package/nitrogen/generated/android/nitrofetch+autolinking.cmake +8 -1
- package/nitrogen/generated/android/nitrofetch+autolinking.gradle +1 -1
- package/nitrogen/generated/android/nitrofetchOnLoad.cpp +85 -33
- package/nitrogen/generated/android/nitrofetchOnLoad.hpp +14 -5
- package/nitrogen/generated/ios/NitroFetch+autolinking.rb +2 -2
- package/nitrogen/generated/ios/NitroFetch-Swift-Cxx-Bridge.cpp +102 -10
- package/nitrogen/generated/ios/NitroFetch-Swift-Cxx-Bridge.hpp +359 -24
- package/nitrogen/generated/ios/NitroFetch-Swift-Cxx-Umbrella.hpp +32 -1
- package/nitrogen/generated/ios/NitroFetchAutolinking.mm +9 -1
- package/nitrogen/generated/ios/NitroFetchAutolinking.swift +29 -22
- package/nitrogen/generated/ios/c++/HybridNativeStorageSpecSwift.cpp +1 -1
- package/nitrogen/generated/ios/c++/HybridNativeStorageSpecSwift.hpp +10 -1
- package/nitrogen/generated/ios/c++/HybridNitroCronetSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridNitroCronetSpecSwift.hpp +85 -0
- package/nitrogen/generated/ios/c++/HybridNitroFetchClientSpecSwift.cpp +1 -1
- package/nitrogen/generated/ios/c++/HybridNitroFetchClientSpecSwift.hpp +22 -4
- package/nitrogen/generated/ios/c++/HybridNitroFetchSpecSwift.cpp +1 -1
- package/nitrogen/generated/ios/c++/HybridNitroFetchSpecSwift.hpp +10 -1
- package/nitrogen/generated/ios/c++/HybridUrlRequestBuilderSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridUrlRequestBuilderSpecSwift.hpp +163 -0
- package/nitrogen/generated/ios/c++/HybridUrlRequestSpecSwift.cpp +11 -0
- package/nitrogen/generated/ios/c++/HybridUrlRequestSpecSwift.hpp +106 -0
- package/nitrogen/generated/ios/swift/Func_void.swift +1 -2
- package/nitrogen/generated/ios/swift/Func_void_NitroResponse.swift +1 -2
- package/nitrogen/generated/ios/swift/Func_void_UrlResponseInfo.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_UrlResponseInfo_std__shared_ptr_ArrayBuffer__double.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_UrlResponseInfo_std__string.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__exception_ptr.swift +1 -2
- package/nitrogen/generated/ios/swift/Func_void_std__optional_UrlResponseInfo_.swift +46 -0
- package/nitrogen/generated/ios/swift/Func_void_std__optional_UrlResponseInfo__RequestException.swift +46 -0
- package/nitrogen/generated/ios/swift/HttpHeader.swift +34 -0
- package/nitrogen/generated/ios/swift/HybridNativeStorageSpec.swift +10 -4
- package/nitrogen/generated/ios/swift/HybridNativeStorageSpec_cxx.swift +18 -3
- package/nitrogen/generated/ios/swift/HybridNitroCronetSpec.swift +55 -0
- package/nitrogen/generated/ios/swift/HybridNitroCronetSpec_cxx.swift +141 -0
- package/nitrogen/generated/ios/swift/HybridNitroFetchClientSpec.swift +11 -4
- package/nitrogen/generated/ios/swift/HybridNitroFetchClientSpec_cxx.swift +29 -3
- package/nitrogen/generated/ios/swift/HybridNitroFetchSpec.swift +10 -4
- package/nitrogen/generated/ios/swift/HybridNitroFetchSpec_cxx.swift +18 -3
- package/nitrogen/generated/ios/swift/HybridUrlRequestBuilderSpec.swift +65 -0
- package/nitrogen/generated/ios/swift/HybridUrlRequestBuilderSpec_cxx.swift +305 -0
- package/nitrogen/generated/ios/swift/HybridUrlRequestSpec.swift +59 -0
- package/nitrogen/generated/ios/swift/HybridUrlRequestSpec_cxx.swift +182 -0
- package/nitrogen/generated/ios/swift/NitroFormDataPart.swift +101 -0
- package/nitrogen/generated/ios/swift/NitroHeader.swift +5 -17
- package/nitrogen/generated/ios/swift/NitroRequest.swift +111 -121
- package/nitrogen/generated/ios/swift/NitroRequestMethod.swift +1 -1
- package/nitrogen/generated/ios/swift/NitroResponse.swift +40 -97
- package/nitrogen/generated/ios/swift/RequestException.swift +29 -0
- package/nitrogen/generated/ios/swift/UrlResponseInfo.swift +118 -0
- package/nitrogen/generated/ios/swift/Variant_ArrayBuffer_String.swift +18 -0
- package/nitrogen/generated/shared/c++/HttpHeader.hpp +87 -0
- package/nitrogen/generated/shared/c++/HybridNativeStorageSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridNativeStorageSpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridNitroCronetSpec.cpp +21 -0
- package/nitrogen/generated/shared/c++/HybridNitroCronetSpec.hpp +65 -0
- package/nitrogen/generated/shared/c++/HybridNitroFetchClientSpec.cpp +2 -1
- package/nitrogen/generated/shared/c++/HybridNitroFetchClientSpec.hpp +3 -1
- package/nitrogen/generated/shared/c++/HybridNitroFetchSpec.cpp +1 -1
- package/nitrogen/generated/shared/c++/HybridNitroFetchSpec.hpp +1 -1
- package/nitrogen/generated/shared/c++/HybridUrlRequestBuilderSpec.cpp +31 -0
- package/nitrogen/generated/shared/c++/HybridUrlRequestBuilderSpec.hpp +85 -0
- package/nitrogen/generated/shared/c++/HybridUrlRequestSpec.cpp +25 -0
- package/nitrogen/generated/shared/c++/HybridUrlRequestSpec.hpp +66 -0
- package/nitrogen/generated/shared/c++/NitroFormDataPart.hpp +100 -0
- package/nitrogen/generated/shared/c++/NitroHeader.hpp +24 -8
- package/nitrogen/generated/shared/c++/NitroRequest.hpp +51 -24
- package/nitrogen/generated/shared/c++/NitroRequestMethod.hpp +1 -1
- package/nitrogen/generated/shared/c++/NitroResponse.hpp +42 -26
- package/nitrogen/generated/shared/c++/RequestException.hpp +83 -0
- package/nitrogen/generated/shared/c++/UrlResponseInfo.hpp +123 -0
- package/package.json +13 -10
- package/src/NitroCronet.nitro.ts +72 -0
- package/src/NitroFetch.nitro.ts +28 -6
- package/src/NitroInstances.ts +4 -0
- package/src/fetch.ts +214 -13
- package/src/index.tsx +1 -1
|
@@ -0,0 +1,255 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import NitroModules
|
|
3
|
+
|
|
4
|
+
class HybridUrlRequestBuilder: HybridUrlRequestBuilderSpec {
|
|
5
|
+
private let url: String
|
|
6
|
+
private let session: URLSession
|
|
7
|
+
private let executor: DispatchQueue
|
|
8
|
+
|
|
9
|
+
// Callbacks stored as optionals and set via setter methods
|
|
10
|
+
private var onRedirectReceivedCallback: ((_ info: UrlResponseInfo, _ newLocationUrl: String) -> Void)?
|
|
11
|
+
private var onResponseStartedCallback: ((_ info: UrlResponseInfo) -> Void)?
|
|
12
|
+
private var onReadCompletedCallback: ((_ info: UrlResponseInfo, _ byteBuffer: ArrayBuffer, _ bytesRead: Double) -> Void)?
|
|
13
|
+
private var onSucceededCallback: ((_ info: UrlResponseInfo) -> Void)?
|
|
14
|
+
private var onFailedCallback: ((_ info: UrlResponseInfo?, _ error: RequestException) -> Void)?
|
|
15
|
+
private var onCanceledCallback: ((_ info: UrlResponseInfo?) -> Void)?
|
|
16
|
+
|
|
17
|
+
private var urlRequest: URLRequest
|
|
18
|
+
private var priority: Float = 0.5
|
|
19
|
+
|
|
20
|
+
init(
|
|
21
|
+
url: String,
|
|
22
|
+
session: URLSession,
|
|
23
|
+
executor: DispatchQueue
|
|
24
|
+
) {
|
|
25
|
+
self.url = url
|
|
26
|
+
self.session = session
|
|
27
|
+
self.executor = executor
|
|
28
|
+
|
|
29
|
+
guard let urlObj = URL(string: url) else {
|
|
30
|
+
fatalError("Invalid URL: \(url)")
|
|
31
|
+
}
|
|
32
|
+
self.urlRequest = URLRequest(url: urlObj)
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// MARK: - Callback Setters
|
|
36
|
+
// Each setter takes only 1 callback to avoid Swift compiler bug (crashes with 4+ callbacks)
|
|
37
|
+
|
|
38
|
+
func onSucceeded(callback: @escaping (_ info: UrlResponseInfo) -> Void) {
|
|
39
|
+
self.onSucceededCallback = callback
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
func onFailed(callback: @escaping (_ info: UrlResponseInfo?, _ error: RequestException) -> Void) {
|
|
43
|
+
self.onFailedCallback = callback
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
func onCanceled(callback: @escaping (_ info: UrlResponseInfo?) -> Void) {
|
|
47
|
+
self.onCanceledCallback = callback
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
func onRedirectReceived(callback: @escaping (_ info: UrlResponseInfo, _ newLocationUrl: String) -> Void) {
|
|
51
|
+
self.onRedirectReceivedCallback = callback
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
func onResponseStarted(callback: @escaping (_ info: UrlResponseInfo) -> Void) {
|
|
55
|
+
self.onResponseStartedCallback = callback
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
func onReadCompleted(callback: @escaping (_ info: UrlResponseInfo, _ byteBuffer: ArrayBuffer, _ bytesRead: Double) -> Void) {
|
|
59
|
+
self.onReadCompletedCallback = callback
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
func setHttpMethod(httpMethod: String) throws {
|
|
63
|
+
self.urlRequest.httpMethod = httpMethod
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
func addHeader(name: String, value: String) throws {
|
|
67
|
+
self.urlRequest.addValue(value, forHTTPHeaderField: name)
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
func setUploadBody(body: Variant_ArrayBuffer_String) throws {
|
|
71
|
+
switch body {
|
|
72
|
+
case .first(let arrayBuffer):
|
|
73
|
+
self.urlRequest.httpBody = arrayBuffer.toData(copyIfNeeded: true)
|
|
74
|
+
case .second(let string):
|
|
75
|
+
self.urlRequest.httpBody = string.data(using: .utf8)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
func disableCache() throws {
|
|
80
|
+
self.urlRequest.cachePolicy = .reloadIgnoringLocalAndRemoteCacheData
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
func build() throws -> any HybridUrlRequestSpec {
|
|
84
|
+
let delegate = URLSessionDelegateAdapter(
|
|
85
|
+
onRedirectReceived: onRedirectReceivedCallback,
|
|
86
|
+
onResponseStarted: onResponseStartedCallback,
|
|
87
|
+
onReadCompleted: onReadCompletedCallback,
|
|
88
|
+
onSucceeded: onSucceededCallback,
|
|
89
|
+
onFailed: onFailedCallback,
|
|
90
|
+
onCanceled: onCanceledCallback,
|
|
91
|
+
executor: executor,
|
|
92
|
+
hybridRequest: nil
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
let config = URLSessionConfiguration.default
|
|
96
|
+
config.urlCache = session.configuration.urlCache
|
|
97
|
+
config.requestCachePolicy = urlRequest.cachePolicy
|
|
98
|
+
|
|
99
|
+
let delegateSession = URLSession(
|
|
100
|
+
configuration: config,
|
|
101
|
+
delegate: delegate,
|
|
102
|
+
delegateQueue: nil
|
|
103
|
+
)
|
|
104
|
+
|
|
105
|
+
let task: URLSessionDataTask = delegateSession.dataTask(with: urlRequest)
|
|
106
|
+
|
|
107
|
+
task.priority = priority
|
|
108
|
+
delegate.task = task
|
|
109
|
+
|
|
110
|
+
let request = HybridUrlRequest(task: task, delegate: delegate)
|
|
111
|
+
delegate.hybridRequest = request
|
|
112
|
+
|
|
113
|
+
return request
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
// MARK: - URLSession Delegate Adapter
|
|
118
|
+
|
|
119
|
+
private class URLSessionDelegateAdapter: NSObject, URLSessionDataDelegate, URLSessionTaskDelegate {
|
|
120
|
+
let onRedirectReceived: ((_ info: UrlResponseInfo, _ newLocationUrl: String) -> Void)?
|
|
121
|
+
let onResponseStarted: ((_ info: UrlResponseInfo) -> Void)?
|
|
122
|
+
let onReadCompleted: ((_ info: UrlResponseInfo, _ byteBuffer: ArrayBuffer, _ bytesRead: Double) -> Void)?
|
|
123
|
+
let onSucceeded: ((_ info: UrlResponseInfo) -> Void)?
|
|
124
|
+
let onFailed: ((_ info: UrlResponseInfo?, _ error: RequestException) -> Void)?
|
|
125
|
+
let onCanceled: ((_ info: UrlResponseInfo?) -> Void)?
|
|
126
|
+
|
|
127
|
+
let executor: DispatchQueue
|
|
128
|
+
weak var task: URLSessionDataTask?
|
|
129
|
+
weak var hybridRequest: HybridUrlRequest?
|
|
130
|
+
|
|
131
|
+
private var response: HTTPURLResponse?
|
|
132
|
+
|
|
133
|
+
init(
|
|
134
|
+
onRedirectReceived: ((_ info: UrlResponseInfo, _ newLocationUrl: String) -> Void)?,
|
|
135
|
+
onResponseStarted: ((_ info: UrlResponseInfo) -> Void)?,
|
|
136
|
+
onReadCompleted: ((_ info: UrlResponseInfo, _ byteBuffer: ArrayBuffer, _ bytesRead: Double) -> Void)?,
|
|
137
|
+
onSucceeded: ((_ info: UrlResponseInfo) -> Void)?,
|
|
138
|
+
onFailed: ((_ info: UrlResponseInfo?, _ error: RequestException) -> Void)?,
|
|
139
|
+
onCanceled: ((_ info: UrlResponseInfo?) -> Void)?,
|
|
140
|
+
executor: DispatchQueue,
|
|
141
|
+
hybridRequest: HybridUrlRequest?
|
|
142
|
+
) {
|
|
143
|
+
self.onRedirectReceived = onRedirectReceived
|
|
144
|
+
self.onResponseStarted = onResponseStarted
|
|
145
|
+
self.onReadCompleted = onReadCompleted
|
|
146
|
+
self.onSucceeded = onSucceeded
|
|
147
|
+
self.onFailed = onFailed
|
|
148
|
+
self.onCanceled = onCanceled
|
|
149
|
+
self.executor = executor
|
|
150
|
+
self.hybridRequest = hybridRequest
|
|
151
|
+
super.init()
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
func urlSession(
|
|
155
|
+
_ session: URLSession,
|
|
156
|
+
task: URLSessionTask,
|
|
157
|
+
willPerformHTTPRedirection response: HTTPURLResponse,
|
|
158
|
+
newRequest request: URLRequest,
|
|
159
|
+
completionHandler: @escaping (URLRequest?) -> Void
|
|
160
|
+
) {
|
|
161
|
+
executor.sync { [weak self] in
|
|
162
|
+
guard let self = self else { return }
|
|
163
|
+
if let callback = self.onRedirectReceived {
|
|
164
|
+
let info = response.toNitro()
|
|
165
|
+
let newUrl = request.url?.absoluteString ?? ""
|
|
166
|
+
callback(info, newUrl)
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
completionHandler(request)
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
func urlSession(
|
|
173
|
+
_ session: URLSession,
|
|
174
|
+
task: URLSessionTask,
|
|
175
|
+
didCompleteWithError error: Error?
|
|
176
|
+
) {
|
|
177
|
+
executor.sync { [weak self] in
|
|
178
|
+
guard let self = self else { return }
|
|
179
|
+
self.hybridRequest?.markDone()
|
|
180
|
+
|
|
181
|
+
if let error = error {
|
|
182
|
+
let nsError = error as NSError
|
|
183
|
+
if nsError.code == NSURLErrorCancelled {
|
|
184
|
+
if let callback = self.onCanceled {
|
|
185
|
+
let nitroInfo = self.response?.toNitro()
|
|
186
|
+
callback(nitroInfo)
|
|
187
|
+
}
|
|
188
|
+
} else {
|
|
189
|
+
if let callback = self.onFailed {
|
|
190
|
+
let nitroError = error.toNitro()
|
|
191
|
+
let nitroInfo = self.response?.toNitro()
|
|
192
|
+
callback(nitroInfo, nitroError)
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
} else if let response = self.response {
|
|
196
|
+
if let callback = self.onSucceeded {
|
|
197
|
+
let info = response.toNitro()
|
|
198
|
+
callback(info)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
|
|
204
|
+
func urlSession(
|
|
205
|
+
_ session: URLSession,
|
|
206
|
+
dataTask: URLSessionDataTask,
|
|
207
|
+
didReceive response: URLResponse,
|
|
208
|
+
completionHandler: @escaping (URLSession.ResponseDisposition) -> Void
|
|
209
|
+
) {
|
|
210
|
+
guard let httpResponse = response as? HTTPURLResponse else {
|
|
211
|
+
completionHandler(.cancel)
|
|
212
|
+
return
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
self.response = httpResponse
|
|
216
|
+
|
|
217
|
+
executor.sync { [weak self] in
|
|
218
|
+
guard let self = self else { return }
|
|
219
|
+
if let callback = self.onResponseStarted {
|
|
220
|
+
let info = httpResponse.toNitro()
|
|
221
|
+
callback(info)
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
completionHandler(.allow)
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
func urlSession(
|
|
229
|
+
_ session: URLSession,
|
|
230
|
+
dataTask: URLSessionDataTask,
|
|
231
|
+
didReceive data: Data
|
|
232
|
+
) {
|
|
233
|
+
if let callback = self.onReadCompleted {
|
|
234
|
+
executor.sync { [weak self] in
|
|
235
|
+
guard let self = self, let response = self.response else { return }
|
|
236
|
+
|
|
237
|
+
let arrayBuffer: ArrayBuffer
|
|
238
|
+
do {
|
|
239
|
+
arrayBuffer = try ArrayBuffer.copy(data: data)
|
|
240
|
+
} catch {
|
|
241
|
+
if let failedCallback = self.onFailed {
|
|
242
|
+
let nitroError = error.toNitro()
|
|
243
|
+
let nitroInfo = response.toNitro()
|
|
244
|
+
failedCallback(nitroInfo, nitroError)
|
|
245
|
+
}
|
|
246
|
+
return
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
let info = response.toNitro()
|
|
250
|
+
let bytesRead = Double(data.count)
|
|
251
|
+
callback(info, arrayBuffer, bytesRead)
|
|
252
|
+
}
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
@@ -29,8 +29,10 @@ public final class NitroAutoPrefetcher: NSObject {
|
|
|
29
29
|
headers: headers,
|
|
30
30
|
bodyString: nil,
|
|
31
31
|
bodyBytes: nil,
|
|
32
|
+
bodyFormData: nil,
|
|
32
33
|
timeoutMs: nil,
|
|
33
|
-
followRedirects: true
|
|
34
|
+
followRedirects: true,
|
|
35
|
+
requestId: nil)
|
|
34
36
|
Task {
|
|
35
37
|
do { try await NitroFetchClient.prefetchStatic(req) } catch { /* ignore – best effort */ }
|
|
36
38
|
}
|
|
@@ -2,6 +2,29 @@ import Foundation
|
|
|
2
2
|
import NitroModules
|
|
3
3
|
|
|
4
4
|
final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
5
|
+
|
|
6
|
+
private var _lock = os_unfair_lock()
|
|
7
|
+
private var activeTasks: [String: Task<Void, Never>] = [:]
|
|
8
|
+
|
|
9
|
+
private func storeTask(_ task: Task<Void, Never>, forKey key: String) {
|
|
10
|
+
os_unfair_lock_lock(&_lock)
|
|
11
|
+
activeTasks[key] = task
|
|
12
|
+
os_unfair_lock_unlock(&_lock)
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
private func removeTask(forKey key: String) {
|
|
16
|
+
os_unfair_lock_lock(&_lock)
|
|
17
|
+
activeTasks.removeValue(forKey: key)
|
|
18
|
+
os_unfair_lock_unlock(&_lock)
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
func cancelRequest(requestId: String) throws {
|
|
22
|
+
os_unfair_lock_lock(&_lock)
|
|
23
|
+
let task = activeTasks.removeValue(forKey: requestId)
|
|
24
|
+
os_unfair_lock_unlock(&_lock)
|
|
25
|
+
task?.cancel()
|
|
26
|
+
}
|
|
27
|
+
|
|
5
28
|
func requestSync(req: NitroRequest) throws -> NitroResponse {
|
|
6
29
|
let semaphore = DispatchSemaphore(value: 0)
|
|
7
30
|
var result: Result<NitroResponse, Error>?
|
|
@@ -29,7 +52,14 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
29
52
|
// Async version - returns Promise<NitroResponse>
|
|
30
53
|
func request(req: NitroRequest) throws -> Promise<NitroResponse> {
|
|
31
54
|
let promise = Promise<NitroResponse>.init()
|
|
32
|
-
|
|
55
|
+
let requestId = req.requestId
|
|
56
|
+
|
|
57
|
+
let task = Task { [weak self] in
|
|
58
|
+
defer {
|
|
59
|
+
if let rid = requestId {
|
|
60
|
+
self?.removeTask(forKey: rid)
|
|
61
|
+
}
|
|
62
|
+
}
|
|
33
63
|
do {
|
|
34
64
|
let response = try await NitroFetchClient.requestStatic(req)
|
|
35
65
|
promise.resolve(withResult: response)
|
|
@@ -37,6 +67,10 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
37
67
|
promise.reject(withError: error)
|
|
38
68
|
}
|
|
39
69
|
}
|
|
70
|
+
|
|
71
|
+
if let rid = requestId {
|
|
72
|
+
storeTask(task, forKey: rid)
|
|
73
|
+
}
|
|
40
74
|
return promise
|
|
41
75
|
}
|
|
42
76
|
|
|
@@ -119,7 +153,7 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
119
153
|
}
|
|
120
154
|
}
|
|
121
155
|
|
|
122
|
-
let (urlRequest, finalURL) = try buildURLRequest(req)
|
|
156
|
+
let (urlRequest, finalURL) = try await buildURLRequest(req)
|
|
123
157
|
let (data, response) = try await session.data(for: urlRequest)
|
|
124
158
|
guard let http = response as? HTTPURLResponse else {
|
|
125
159
|
throw NSError(domain: "NitroFetch", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid response"])
|
|
@@ -167,7 +201,7 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
167
201
|
FetchCache.addPending(key) { _ in /* ignored here */ }
|
|
168
202
|
Task.detached {
|
|
169
203
|
do {
|
|
170
|
-
let (urlRequest, finalURL) = try buildURLRequest(req)
|
|
204
|
+
let (urlRequest, finalURL) = try await buildURLRequest(req)
|
|
171
205
|
let (data, response) = try await session.data(for: urlRequest)
|
|
172
206
|
guard let http = response as? HTTPURLResponse else {
|
|
173
207
|
throw NSError(domain: "NitroFetch", code: -1, userInfo: [NSLocalizedDescriptionKey: "Invalid response"])
|
|
@@ -199,7 +233,7 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
199
233
|
return req.method?.stringValue
|
|
200
234
|
}
|
|
201
235
|
|
|
202
|
-
private static func buildURLRequest(_ req: NitroRequest) throws -> (URLRequest, URL?) {
|
|
236
|
+
private static func buildURLRequest(_ req: NitroRequest) async throws -> (URLRequest, URL?) {
|
|
203
237
|
guard let url = URL(string: req.url) else {
|
|
204
238
|
throw NSError(domain: "NitroFetch", code: -3, userInfo: [NSLocalizedDescriptionKey: "Invalid URL: \(req.url)"])
|
|
205
239
|
}
|
|
@@ -208,13 +242,61 @@ final class NitroFetchClient: HybridNitroFetchClientSpec {
|
|
|
208
242
|
if let headers = req.headers {
|
|
209
243
|
for h in headers { r.addValue(h.value, forHTTPHeaderField: h.key) }
|
|
210
244
|
}
|
|
211
|
-
if let
|
|
245
|
+
if let parts = req.bodyFormData, !parts.isEmpty {
|
|
246
|
+
let (body, contentType) = try await buildMultipartBody(parts)
|
|
247
|
+
r.httpBody = body
|
|
248
|
+
r.setValue(contentType, forHTTPHeaderField: "Content-Type")
|
|
249
|
+
} else if let s = req.bodyString {
|
|
212
250
|
r.httpBody = s.data(using: .utf8)
|
|
213
251
|
}
|
|
214
252
|
if let t = req.timeoutMs, t > 0 { r.timeoutInterval = TimeInterval(t) / 1000.0 }
|
|
215
253
|
return (r, nil)
|
|
216
254
|
}
|
|
217
255
|
|
|
256
|
+
private static func buildMultipartBody(_ parts: [NitroFormDataPart]) async throws -> (Data, String) {
|
|
257
|
+
let boundary = "NitroFetch-\(UUID().uuidString)"
|
|
258
|
+
var body = Data()
|
|
259
|
+
let crlf = "\r\n"
|
|
260
|
+
|
|
261
|
+
for part in parts {
|
|
262
|
+
body.append("--\(boundary)\(crlf)".data(using: .utf8)!)
|
|
263
|
+
|
|
264
|
+
if let fileUri = part.fileUri {
|
|
265
|
+
let fileName = part.fileName ?? "file"
|
|
266
|
+
let mimeType = part.mimeType ?? "application/octet-stream"
|
|
267
|
+
body.append("Content-Disposition: form-data; name=\"\(part.name)\"; filename=\"\(fileName)\"\(crlf)".data(using: .utf8)!)
|
|
268
|
+
body.append("Content-Type: \(mimeType)\(crlf)\(crlf)".data(using: .utf8)!)
|
|
269
|
+
|
|
270
|
+
let fileData = try await readFileData(fileUri)
|
|
271
|
+
body.append(fileData)
|
|
272
|
+
} else {
|
|
273
|
+
let value = part.value ?? ""
|
|
274
|
+
body.append("Content-Disposition: form-data; name=\"\(part.name)\"\(crlf)\(crlf)".data(using: .utf8)!)
|
|
275
|
+
body.append(value.data(using: .utf8)!)
|
|
276
|
+
}
|
|
277
|
+
|
|
278
|
+
body.append(crlf.data(using: .utf8)!)
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
body.append("--\(boundary)--\(crlf)".data(using: .utf8)!)
|
|
282
|
+
return (body, "multipart/form-data; boundary=\(boundary)")
|
|
283
|
+
}
|
|
284
|
+
|
|
285
|
+
private static func readFileData(_ uri: String) async throws -> Data {
|
|
286
|
+
if uri.hasPrefix("http://") || uri.hasPrefix("https://") {
|
|
287
|
+
guard let url = URL(string: uri) else {
|
|
288
|
+
throw NSError(domain: "NitroFetch", code: -4, userInfo: [NSLocalizedDescriptionKey: "Invalid URL: \(uri)"])
|
|
289
|
+
}
|
|
290
|
+
let (data, _) = try await session.data(from: url)
|
|
291
|
+
return data
|
|
292
|
+
}
|
|
293
|
+
let path = uri.hasPrefix("file://") ? String(uri.dropFirst(7)) : uri
|
|
294
|
+
guard let data = FileManager.default.contents(atPath: path) else {
|
|
295
|
+
throw NSError(domain: "NitroFetch", code: -4, userInfo: [NSLocalizedDescriptionKey: "Cannot read file at: \(uri)"])
|
|
296
|
+
}
|
|
297
|
+
return data
|
|
298
|
+
}
|
|
299
|
+
|
|
218
300
|
private static func detectCharset(from http: HTTPURLResponse) -> String.Encoding? {
|
|
219
301
|
if let ct = http.value(forHTTPHeaderField: "Content-Type")?.lowercased() {
|
|
220
302
|
if let range = ct.range(of: "charset=") {
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import Foundation
|
|
2
|
+
import NitroModules
|
|
3
|
+
|
|
4
|
+
extension HTTPURLResponse {
|
|
5
|
+
func toNitro() -> UrlResponseInfo {
|
|
6
|
+
let headersMap = allHeaderFields.reduce(into: [String: String]()) { result, pair in
|
|
7
|
+
if let key = pair.key as? String {
|
|
8
|
+
result[key] = String(describing: pair.value)
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
let headersList = allHeaderFields.compactMap { pair -> HttpHeader? in
|
|
13
|
+
guard let key = pair.key as? String else { return nil }
|
|
14
|
+
return HttpHeader(key: key, value: String(describing: pair.value))
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
return UrlResponseInfo(
|
|
18
|
+
url: url?.absoluteString ?? "",
|
|
19
|
+
httpStatusCode: Double(statusCode),
|
|
20
|
+
httpStatusText: HTTPURLResponse.localizedString(forStatusCode: statusCode),
|
|
21
|
+
allHeaders: headersMap,
|
|
22
|
+
allHeadersAsList: headersList,
|
|
23
|
+
urlChain: [url?.absoluteString ?? ""],
|
|
24
|
+
negotiatedProtocol: "",
|
|
25
|
+
proxyServer: "",
|
|
26
|
+
receivedByteCount: Double(expectedContentLength),
|
|
27
|
+
wasCached: false
|
|
28
|
+
)
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
extension Error {
|
|
33
|
+
func toNitro() -> RequestException {
|
|
34
|
+
return RequestException(message: localizedDescription)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"names":[],"sourceRoot":"../../src","sources":["NitroCronet.nitro.ts"],"mappings":"","ignoreList":[]}
|
|
@@ -5,4 +5,5 @@ import { NitroModules } from 'react-native-nitro-modules';
|
|
|
5
5
|
export const NitroFetch = NitroModules.createHybridObject('NitroFetch');
|
|
6
6
|
export const NativeStorage = NitroModules.createHybridObject('NativeStorage');
|
|
7
7
|
export const boxedNitroFetch = NitroModules.box(NitroFetch);
|
|
8
|
+
export const NitroCronetSingleton = NitroModules.createHybridObject('NitroCronet');
|
|
8
9
|
//# sourceMappingURL=NitroInstances.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["NitroModules","NitroFetch","createHybridObject","NativeStorage","boxedNitroFetch","box"],"sourceRoot":"../../src","sources":["NitroInstances.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;
|
|
1
|
+
{"version":3,"names":["NitroModules","NitroFetch","createHybridObject","NativeStorage","boxedNitroFetch","box","NitroCronetSingleton"],"sourceRoot":"../../src","sources":["NitroInstances.ts"],"mappings":";;AAAA,SAASA,YAAY,QAAQ,4BAA4B;AAOzD;AACA,OAAO,MAAMC,UAA0B,GACrCD,YAAY,CAACE,kBAAkB,CAAiB,YAAY,CAAC;AAE/D,OAAO,MAAMC,aAAgC,GAC3CH,YAAY,CAACE,kBAAkB,CAAoB,eAAe,CAAC;AAErE,OAAO,MAAME,eAAe,GAAGJ,YAAY,CAACK,GAAG,CAACJ,UAAU,CAAC;AAE3D,OAAO,MAAMK,oBAAoB,GAC/BN,YAAY,CAACE,kBAAkB,CAAc,aAAa,CAAC","ignoreList":[]}
|