uws-react-native 0.0.3 → 0.0.5
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/README.md +2 -8
- package/cpp/CMakeLists.txt +0 -2
- package/cpp/UwsReactNativeModule.cpp +6 -2
- package/cpp/app/CMakeLists.txt +0 -1
- package/cpp/app/HttpRequestObject.h +7 -15
- package/cpp/app/HttpResponseObject.h +133 -264
- package/cpp/app/HttpResponseObjectProvider.h +118 -0
- package/cpp/app/TemplatedAppObject.h +33 -28
- package/lib/typescript/commonjs/types/HttpResponse.d.ts +2 -2
- package/lib/typescript/commonjs/types/HttpResponse.d.ts.map +1 -1
- package/lib/typescript/module/types/HttpResponse.d.ts +2 -2
- package/lib/typescript/module/types/HttpResponse.d.ts.map +1 -1
- package/lib/typescript/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/src/types/HttpResponse.ts +2 -2
- package/cpp/bridging/ArrayBuffer.h +0 -150
- package/cpp/bridging/CMakeLists.txt +0 -34
|
@@ -1,85 +1,33 @@
|
|
|
1
1
|
#pragma once
|
|
2
2
|
|
|
3
|
+
#include <ReactCommon/CallInvoker.h>
|
|
3
4
|
#include <jsi/Buffer.h>
|
|
4
5
|
#include <jsi/jsi.h>
|
|
5
6
|
#include <utility>
|
|
6
7
|
#include "RecognizedString.h"
|
|
7
|
-
#include "
|
|
8
|
+
#include "HttpResponseObjectProvider.h"
|
|
9
|
+
#include "uWebSockets/App.h"
|
|
8
10
|
|
|
9
11
|
namespace uws_react_native {
|
|
10
12
|
|
|
11
|
-
|
|
12
|
-
// bool disableBodyRead;
|
|
13
|
-
// unsigned long maxBodySize;
|
|
14
|
-
// };
|
|
15
|
-
|
|
13
|
+
/// Only use this in the JavaScript thread
|
|
16
14
|
class HttpResponseObject : public facebook::jsi::Object {
|
|
17
15
|
|
|
18
|
-
private:
|
|
19
|
-
struct {
|
|
20
|
-
std::shared_ptr<facebook::react::AsyncCallback<facebook::jsi::Value>> callback = nullptr;
|
|
21
|
-
bool alreadyAborted = false;
|
|
22
|
-
} OnAbortedAssignee;
|
|
23
|
-
|
|
24
|
-
struct {
|
|
25
|
-
/**
|
|
26
|
-
* For passing ArrayBuffer
|
|
27
|
-
* - onData
|
|
28
|
-
* - onDataV2
|
|
29
|
-
* - onFullData
|
|
30
|
-
*/
|
|
31
|
-
std::unique_ptr<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>> callback = nullptr;
|
|
32
|
-
|
|
33
|
-
/**
|
|
34
|
-
* For passing string, only for onFullDataText
|
|
35
|
-
*/
|
|
36
|
-
std::unique_ptr<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>> callbackStr = nullptr;
|
|
37
|
-
|
|
38
|
-
std::shared_ptr<std::vector<char>> buffer = nullptr;
|
|
39
|
-
|
|
40
|
-
unsigned long maxRemainingBodyLength = 0;
|
|
41
|
-
|
|
42
|
-
bool isCallbackForFullChunk = false;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* It's marked from TemplatedAppObject that predefined res->onDataV2 there
|
|
46
|
-
* want to stop collecting for certain condition.
|
|
47
|
-
*
|
|
48
|
-
* At the time, this boolean belong to the TemplatedAppObject only,
|
|
49
|
-
* but if the JS handler assignment for the onData, onDataText, onDataV2, onFullData, and onFullDataText is late,
|
|
50
|
-
* we invoke the handler immediately from the `this->setProperty`.
|
|
51
|
-
*/
|
|
52
|
-
bool isStopCollecting = false;
|
|
53
|
-
} OnDataV2Assignee;
|
|
54
|
-
|
|
55
|
-
// void preEnd(facebook::jsi::Runtime &rt) const {
|
|
56
|
-
// if(this->OnAbortedAssignee.alreadyAborted) {
|
|
57
|
-
// /// Stated from uWebSockets
|
|
58
|
-
// /// Every HttpResponse MUST have an attached abort handler.
|
|
59
|
-
// /// If you do not respond to it immediately inside of the callback.
|
|
60
|
-
// /// Returning from an Http request handler without attaching
|
|
61
|
-
// /// (by calling onAborted) an abort handler is ill-use and will terminate.
|
|
62
|
-
// /// When this event emits, the response has been aborted and may not be used.
|
|
63
|
-
// throw facebook::jsi::JSError(rt, "Cannot send response to aborted request");
|
|
64
|
-
// }
|
|
65
|
-
// }
|
|
66
|
-
|
|
67
16
|
public:
|
|
68
17
|
HttpResponseObject(facebook::jsi::Runtime &rt,
|
|
69
|
-
|
|
70
|
-
std::shared_ptr<facebook::react::CallInvoker> &jsInvoker
|
|
71
|
-
/* std::optional<HttpResponseObjectOptions> &&options = HttpResponseObjectOptions{ .disableBodyRead = false, .maxBodySize = 0 } */) : facebook::jsi::Object(rt) {
|
|
18
|
+
const std::shared_ptr<HttpResponseObjectProvider> &provider,
|
|
19
|
+
std::shared_ptr<facebook::react::CallInvoker> &jsInvoker) : facebook::jsi::Object(rt) {
|
|
72
20
|
|
|
73
21
|
this->setProperty(rt,
|
|
74
22
|
"close",
|
|
75
23
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
76
24
|
facebook::jsi::PropNameID::forUtf8(rt, "close"),
|
|
77
25
|
1,
|
|
78
|
-
[
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
res->close();
|
|
26
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
27
|
+
const facebook::jsi::Value &thisValue,
|
|
28
|
+
const facebook::jsi::Value *arguments,
|
|
29
|
+
size_t count) -> facebook::jsi::Value {
|
|
30
|
+
provider->res->close();
|
|
83
31
|
return {rt_1, thisValue};
|
|
84
32
|
}));
|
|
85
33
|
|
|
@@ -88,13 +36,13 @@ public:
|
|
|
88
36
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
89
37
|
facebook::jsi::PropNameID::forUtf8(rt, "cork"),
|
|
90
38
|
1,
|
|
91
|
-
[
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
39
|
+
[provider, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
40
|
+
const facebook::jsi::Value &thisValue,
|
|
41
|
+
const facebook::jsi::Value *arguments,
|
|
42
|
+
size_t count) -> facebook::jsi::Value {
|
|
95
43
|
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
96
44
|
|
|
97
|
-
res->cork([asyncCallback = facebook::react::AsyncCallback(rt_1, std::move(callback), jsInvoker)]() {
|
|
45
|
+
provider->res->cork([asyncCallback = facebook::react::AsyncCallback(rt_1, std::move(callback), jsInvoker)]() {
|
|
98
46
|
asyncCallback.call();
|
|
99
47
|
});
|
|
100
48
|
|
|
@@ -105,22 +53,21 @@ public:
|
|
|
105
53
|
"end", facebook::jsi::Function::createFromHostFunction(rt,
|
|
106
54
|
facebook::jsi::PropNameID::forUtf8(rt, "end"),
|
|
107
55
|
1,
|
|
108
|
-
[
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
56
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
57
|
+
const facebook::jsi::Value &thisValue,
|
|
58
|
+
const facebook::jsi::Value *arguments,
|
|
59
|
+
size_t count) -> facebook::jsi::Value {
|
|
112
60
|
/// Due to JS run at different thread
|
|
113
61
|
/// The race condition event is not avoidable under stress test
|
|
114
62
|
/// Our predefined `res->onAborted` call earlier than JS callback
|
|
115
63
|
/// This below makes JS side can call the "res.end" without attaching `onAborted` handler at all.
|
|
116
64
|
/// If we know how to make a sync call across the thread, please update this.
|
|
117
|
-
if(
|
|
65
|
+
if(provider->dataAbort.isAlreadyAborted) {
|
|
118
66
|
return {rt_1, thisValue};
|
|
119
67
|
}
|
|
120
68
|
|
|
121
69
|
auto body = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
122
|
-
res->end(body);
|
|
123
|
-
|
|
70
|
+
provider->res->end(body);
|
|
124
71
|
return {rt_1, thisValue};
|
|
125
72
|
}));
|
|
126
73
|
|
|
@@ -129,21 +76,21 @@ public:
|
|
|
129
76
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
130
77
|
facebook::jsi::PropNameID::forUtf8(rt, "endWithoutBody"),
|
|
131
78
|
2,
|
|
132
|
-
[
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
79
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
80
|
+
const facebook::jsi::Value &thisValue,
|
|
81
|
+
const facebook::jsi::Value *arguments,
|
|
82
|
+
size_t count) -> facebook::jsi::Value {
|
|
136
83
|
/// Due to JS run at different thread
|
|
137
84
|
/// The race condition event is not avoidable under stress test
|
|
138
85
|
/// Our predefined `res->onAborted` call earlier than JS callback
|
|
139
86
|
/// This below makes JS side can call the "res.end" without attaching `onAborted` handler at all.
|
|
140
87
|
/// If we know how to make a sync call across the thread, please update this.
|
|
141
|
-
if(
|
|
88
|
+
if(provider->dataAbort.isAlreadyAborted) {
|
|
142
89
|
return {rt_1, thisValue};
|
|
143
90
|
}
|
|
144
91
|
|
|
145
92
|
if(!arguments) {
|
|
146
|
-
res->endWithoutBody();
|
|
93
|
+
provider->res->endWithoutBody();
|
|
147
94
|
return {rt_1, thisValue};
|
|
148
95
|
}
|
|
149
96
|
|
|
@@ -158,7 +105,7 @@ public:
|
|
|
158
105
|
closeConnection = arguments[1].asBool();
|
|
159
106
|
}
|
|
160
107
|
|
|
161
|
-
res->endWithoutBody(reportedContentLength, closeConnection);
|
|
108
|
+
provider->res->endWithoutBody(reportedContentLength, closeConnection);
|
|
162
109
|
|
|
163
110
|
return {rt_1, thisValue};
|
|
164
111
|
}));
|
|
@@ -168,24 +115,24 @@ public:
|
|
|
168
115
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
169
116
|
facebook::jsi::PropNameID::forUtf8(rt, "getRemoteAddressAsText"),
|
|
170
117
|
0,
|
|
171
|
-
[
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
auto remoteAddress = res->getRemoteAddressAsText();
|
|
118
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
119
|
+
const facebook::jsi::Value &thisValue,
|
|
120
|
+
const facebook::jsi::Value *arguments,
|
|
121
|
+
size_t count) -> facebook::jsi::Value {
|
|
122
|
+
auto remoteAddress = provider->res->getRemoteAddressAsText();
|
|
176
123
|
return facebook::jsi::String::createFromUtf8(rt_1, std::string(remoteAddress));
|
|
177
124
|
}));
|
|
178
|
-
|
|
125
|
+
|
|
179
126
|
this->setProperty(rt,
|
|
180
127
|
"getRemotePort",
|
|
181
128
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
182
129
|
facebook::jsi::PropNameID::forUtf8(rt, "getRemotePort"),
|
|
183
130
|
0,
|
|
184
|
-
[
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
return facebook::jsi::BigInt::fromUint64(rt_1, res->getRemotePort());
|
|
131
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
132
|
+
const facebook::jsi::Value &thisValue,
|
|
133
|
+
const facebook::jsi::Value *arguments,
|
|
134
|
+
size_t count) -> facebook::jsi::Value {
|
|
135
|
+
return facebook::jsi::BigInt::fromUint64(rt_1, provider->res->getRemotePort());
|
|
189
136
|
}));
|
|
190
137
|
|
|
191
138
|
this->setProperty(rt,
|
|
@@ -193,11 +140,11 @@ public:
|
|
|
193
140
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
194
141
|
facebook::jsi::PropNameID::forUtf8(rt, "getWriteOffset"),
|
|
195
142
|
0,
|
|
196
|
-
[
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
return facebook::jsi::BigInt::fromUint64(rt_1, res->getWriteOffset());
|
|
143
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
144
|
+
const facebook::jsi::Value &thisValue,
|
|
145
|
+
const facebook::jsi::Value *arguments,
|
|
146
|
+
size_t count) -> facebook::jsi::Value {
|
|
147
|
+
return facebook::jsi::BigInt::fromUint64(rt_1, provider->res->getWriteOffset());
|
|
201
148
|
}));
|
|
202
149
|
|
|
203
150
|
this->setProperty(rt,
|
|
@@ -205,16 +152,16 @@ public:
|
|
|
205
152
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
206
153
|
facebook::jsi::PropNameID::forUtf8(rt, "onAborted"),
|
|
207
154
|
1,
|
|
208
|
-
[
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
155
|
+
[provider, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
156
|
+
const facebook::jsi::Value &thisValue,
|
|
157
|
+
const facebook::jsi::Value *arguments,
|
|
158
|
+
size_t count) -> facebook::jsi::Value {
|
|
212
159
|
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
213
160
|
|
|
214
|
-
if(
|
|
161
|
+
if(provider->dataAbort.isAlreadyAborted) {
|
|
215
162
|
facebook::react::AsyncCallback(rt_1, std::move(callback), jsInvoker).call();
|
|
216
163
|
} else {
|
|
217
|
-
|
|
164
|
+
provider->dataAbort.callback = std::make_shared<facebook::react::AsyncCallback<facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
218
165
|
}
|
|
219
166
|
|
|
220
167
|
return {rt_1, thisValue};
|
|
@@ -225,31 +172,30 @@ public:
|
|
|
225
172
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
226
173
|
facebook::jsi::PropNameID::forUtf8(rt, "onData"),
|
|
227
174
|
1,
|
|
228
|
-
[
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
if(
|
|
175
|
+
[provider, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
176
|
+
const facebook::jsi::Value &thisValue,
|
|
177
|
+
const facebook::jsi::Value *arguments,
|
|
178
|
+
size_t count) -> facebook::jsi::Value {
|
|
179
|
+
if(provider->dataBody.callback) {
|
|
233
180
|
throw facebook::jsi::JSError(rt_1, "Cannot reassign onData or assign it with existing onDataV2 and/or onFullData handler");
|
|
234
181
|
}
|
|
235
182
|
|
|
236
183
|
/// Same usage as the onDataV2
|
|
237
184
|
/// except the second parameter to the JS handler is the boolean `isLast`
|
|
238
185
|
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
239
|
-
|
|
186
|
+
provider->dataBody.callback = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
240
187
|
|
|
241
188
|
/// This a late call
|
|
242
189
|
if(
|
|
243
|
-
|
|
244
|
-
|
|
190
|
+
provider->dataBody.isStopCollecting ||
|
|
191
|
+
provider->dataBody.maxRemainingBodyLength == 0
|
|
245
192
|
) {
|
|
246
|
-
|
|
247
|
-
|
|
248
|
-
|
|
249
|
-
auto mutableBuffer = CharsMutableBuffer(this->OnDataV2Assignee.buffer.get());
|
|
193
|
+
provider->dataBody.callback->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
194
|
+
[provider](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
195
|
+
auto mutableBuffer = CharsMutableBuffer(provider->dataBody.buffer.get());
|
|
250
196
|
cb.call(rt,
|
|
251
197
|
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))),
|
|
252
|
-
|
|
198
|
+
provider->dataBody.maxRemainingBodyLength == 0);
|
|
253
199
|
});
|
|
254
200
|
}
|
|
255
201
|
|
|
@@ -261,32 +207,31 @@ public:
|
|
|
261
207
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
262
208
|
facebook::jsi::PropNameID::forUtf8(rt, "onDataV2"),
|
|
263
209
|
1,
|
|
264
|
-
[
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
if(
|
|
210
|
+
[provider, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
211
|
+
const facebook::jsi::Value &thisValue,
|
|
212
|
+
const facebook::jsi::Value *arguments,
|
|
213
|
+
size_t count) -> facebook::jsi::Value {
|
|
214
|
+
if(provider->dataBody.callback) {
|
|
269
215
|
throw facebook::jsi::JSError(rt_1, "Cannot reassign onDataV2 or assign it with existing onData and/or onFullData handler");
|
|
270
216
|
}
|
|
271
217
|
|
|
272
218
|
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
273
|
-
|
|
219
|
+
provider->dataBody.callback = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
274
220
|
|
|
275
221
|
/// This is a late call to the onDataV2 callback
|
|
276
222
|
/// due to the onDataV2 predefined lambda has finished earlier
|
|
277
223
|
/// or isStopCollecting is already marked
|
|
278
224
|
if(
|
|
279
|
-
|
|
280
|
-
(
|
|
225
|
+
provider->dataBody.buffer &&
|
|
226
|
+
(provider->dataBody.isStopCollecting || provider->dataBody.maxRemainingBodyLength == 0)
|
|
281
227
|
) {
|
|
282
|
-
|
|
228
|
+
provider->dataBody.callback
|
|
283
229
|
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
284
|
-
[
|
|
285
|
-
|
|
286
|
-
auto mutableBuffer = CharsMutableBuffer(this->OnDataV2Assignee.buffer.get());
|
|
230
|
+
[provider](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
231
|
+
auto mutableBuffer = CharsMutableBuffer(provider->dataBody.buffer.get());
|
|
287
232
|
cb.call(rt,
|
|
288
|
-
|
|
289
|
-
|
|
233
|
+
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))),
|
|
234
|
+
facebook::jsi::BigInt::fromUint64(rt, provider->dataBody.maxRemainingBodyLength));
|
|
290
235
|
});
|
|
291
236
|
}
|
|
292
237
|
|
|
@@ -298,29 +243,29 @@ public:
|
|
|
298
243
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
299
244
|
facebook::jsi::PropNameID::forUtf8(rt, "onFullData"),
|
|
300
245
|
1,
|
|
301
|
-
[
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
if(
|
|
246
|
+
[provider, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
247
|
+
const facebook::jsi::Value &thisValue,
|
|
248
|
+
const facebook::jsi::Value *arguments,
|
|
249
|
+
size_t count) -> facebook::jsi::Value {
|
|
250
|
+
if(provider->dataBody.callback) {
|
|
306
251
|
throw facebook::jsi::JSError(rt_1, "Cannot reassign onFullData or assign it with existing onData and/or onDataV2 handler");
|
|
307
252
|
}
|
|
308
253
|
|
|
309
254
|
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
310
|
-
|
|
311
|
-
|
|
255
|
+
provider->dataBody.isCallbackForFullChunk = true;
|
|
256
|
+
provider->dataBody.callback = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
312
257
|
|
|
313
258
|
/// This is a late call to the onFullData callback
|
|
314
259
|
/// due to the onDataV2 predefined lambda has finished earlier
|
|
315
260
|
/// or isStopCollecting is already marked
|
|
316
261
|
if(
|
|
317
|
-
|
|
318
|
-
(
|
|
262
|
+
provider->dataBody.buffer &&
|
|
263
|
+
(provider->dataBody.isStopCollecting || provider->dataBody.maxRemainingBodyLength == 0)
|
|
319
264
|
) {
|
|
320
|
-
|
|
265
|
+
provider->dataBody.callback
|
|
321
266
|
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
322
|
-
[
|
|
323
|
-
auto mutableBuffer = CharsMutableBuffer(
|
|
267
|
+
[provider](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
268
|
+
auto mutableBuffer = CharsMutableBuffer(provider->dataBody.buffer.get());
|
|
324
269
|
cb.call(rt,
|
|
325
270
|
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))));
|
|
326
271
|
});
|
|
@@ -334,30 +279,30 @@ public:
|
|
|
334
279
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
335
280
|
facebook::jsi::PropNameID::forUtf8(rt, "onFullDataText"),
|
|
336
281
|
1,
|
|
337
|
-
[
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
if(
|
|
282
|
+
[provider, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
283
|
+
const facebook::jsi::Value &thisValue,
|
|
284
|
+
const facebook::jsi::Value *arguments,
|
|
285
|
+
size_t count) -> facebook::jsi::Value {
|
|
286
|
+
if(provider->dataBody.callbackStr) {
|
|
342
287
|
throw facebook::jsi::JSError(rt_1, "Cannot reassign onFullDataText handler");
|
|
343
288
|
}
|
|
344
289
|
|
|
345
290
|
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
346
|
-
|
|
347
|
-
|
|
291
|
+
provider->dataBody.isCallbackForFullChunk = true;
|
|
292
|
+
provider->dataBody.callbackStr = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
348
293
|
|
|
349
294
|
/// This is a late call to the onFullDataText callback
|
|
350
295
|
/// due to the onDataV2 predefined lambda has finished earlier
|
|
351
296
|
/// or isStopCollecting is already marked
|
|
352
297
|
if(
|
|
353
|
-
|
|
354
|
-
(
|
|
298
|
+
provider->dataBody.buffer &&
|
|
299
|
+
(provider->dataBody.isStopCollecting || provider->dataBody.maxRemainingBodyLength == 0)
|
|
355
300
|
) {
|
|
356
|
-
|
|
301
|
+
provider->dataBody.callbackStr
|
|
357
302
|
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
358
|
-
[
|
|
303
|
+
[provider](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
359
304
|
cb.call(rt,
|
|
360
|
-
std::string(
|
|
305
|
+
std::string(provider->dataBody.buffer->begin(), provider->dataBody.buffer->end()));
|
|
361
306
|
});
|
|
362
307
|
}
|
|
363
308
|
|
|
@@ -369,11 +314,11 @@ public:
|
|
|
369
314
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
370
315
|
facebook::jsi::PropNameID::forUtf8(rt, "pause"),
|
|
371
316
|
0,
|
|
372
|
-
[
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
res->pause();
|
|
317
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
318
|
+
const facebook::jsi::Value &thisValue,
|
|
319
|
+
const facebook::jsi::Value *arguments,
|
|
320
|
+
size_t count) -> facebook::jsi::Value {
|
|
321
|
+
provider->res->pause();
|
|
377
322
|
return facebook::jsi::Value::undefined();
|
|
378
323
|
}));
|
|
379
324
|
|
|
@@ -382,11 +327,11 @@ public:
|
|
|
382
327
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
383
328
|
facebook::jsi::PropNameID::forUtf8(rt, "resume"),
|
|
384
329
|
0,
|
|
385
|
-
[
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
res->resume();
|
|
330
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
331
|
+
const facebook::jsi::Value &thisValue,
|
|
332
|
+
const facebook::jsi::Value *arguments,
|
|
333
|
+
size_t count) -> facebook::jsi::Value {
|
|
334
|
+
provider->res->resume();
|
|
390
335
|
return facebook::jsi::Value::undefined();
|
|
391
336
|
}));
|
|
392
337
|
|
|
@@ -395,23 +340,23 @@ public:
|
|
|
395
340
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
396
341
|
facebook::jsi::PropNameID::forUtf8(rt, "tryEnd"),
|
|
397
342
|
2,
|
|
398
|
-
[
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
343
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
344
|
+
const facebook::jsi::Value &thisValue,
|
|
345
|
+
const facebook::jsi::Value *arguments,
|
|
346
|
+
size_t count) -> facebook::jsi::Value {
|
|
402
347
|
/// Due to JS run at different thread
|
|
403
348
|
/// The race condition event is not avoidable under stress test
|
|
404
349
|
/// Our predefined `res->onAborted` call earlier than JS callback
|
|
405
350
|
/// This below makes JS side can call the "res.end" without attaching `onAborted` handler at all.
|
|
406
351
|
/// If we know how to make a JS sync call across the thread, please update this.
|
|
407
|
-
if(
|
|
352
|
+
if(provider->dataAbort.isAlreadyAborted) {
|
|
408
353
|
return {rt_1, thisValue};
|
|
409
354
|
}
|
|
410
355
|
|
|
411
356
|
auto fullBodyOrChunk = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
412
357
|
auto totalSize = arguments[1].asNumber();
|
|
413
358
|
|
|
414
|
-
auto tryEndResult = res->tryEnd(fullBodyOrChunk, static_cast<uintmax_t>(totalSize));
|
|
359
|
+
auto tryEndResult = provider->res->tryEnd(fullBodyOrChunk, static_cast<uintmax_t>(totalSize));
|
|
415
360
|
|
|
416
361
|
return facebook::jsi::Array::createWithElements(rt_1, {tryEndResult.first, tryEndResult.second});
|
|
417
362
|
}));
|
|
@@ -461,12 +406,12 @@ public:
|
|
|
461
406
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
462
407
|
facebook::jsi::PropNameID::forUtf8(rt, "write"),
|
|
463
408
|
2,
|
|
464
|
-
[
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
409
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
410
|
+
const facebook::jsi::Value &thisValue,
|
|
411
|
+
const facebook::jsi::Value *arguments,
|
|
412
|
+
size_t count) -> facebook::jsi::Value {
|
|
468
413
|
auto chunk = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
469
|
-
return res->write(
|
|
414
|
+
return provider->res->write(chunk);
|
|
470
415
|
}));
|
|
471
416
|
|
|
472
417
|
this->setProperty(rt,
|
|
@@ -474,13 +419,13 @@ public:
|
|
|
474
419
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
475
420
|
facebook::jsi::PropNameID::forUtf8(rt, "writeHeader"),
|
|
476
421
|
2,
|
|
477
|
-
[
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
422
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
423
|
+
const facebook::jsi::Value &thisValue,
|
|
424
|
+
const facebook::jsi::Value *arguments,
|
|
425
|
+
size_t count) -> facebook::jsi::Value {
|
|
481
426
|
auto headerKey = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
482
427
|
auto headerVal = RecognizedString(rt_1, arguments[1]).getStringView();
|
|
483
|
-
res->writeHeader(headerKey, headerVal);
|
|
428
|
+
provider->res->writeHeader(headerKey, headerVal);
|
|
484
429
|
|
|
485
430
|
return {rt_1, thisValue};
|
|
486
431
|
}));
|
|
@@ -490,94 +435,18 @@ public:
|
|
|
490
435
|
facebook::jsi::Function::createFromHostFunction(rt,
|
|
491
436
|
facebook::jsi::PropNameID::forUtf8(rt, "writeStatus"),
|
|
492
437
|
1,
|
|
493
|
-
[
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
438
|
+
[provider](facebook::jsi::Runtime &rt_1,
|
|
439
|
+
const facebook::jsi::Value &thisValue,
|
|
440
|
+
const facebook::jsi::Value *arguments,
|
|
441
|
+
size_t count) -> facebook::jsi::Value {
|
|
497
442
|
auto status = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
498
|
-
res->writeStatus(status);
|
|
443
|
+
provider->res->writeStatus(status);
|
|
499
444
|
|
|
500
445
|
return {rt_1, thisValue};
|
|
501
446
|
}));
|
|
502
447
|
|
|
503
448
|
} // HttpResponseObject
|
|
504
449
|
|
|
505
|
-
|
|
506
|
-
this->OnAbortedAssignee.alreadyAborted = true;
|
|
507
|
-
|
|
508
|
-
if(this->OnAbortedAssignee.callback) {
|
|
509
|
-
this->OnAbortedAssignee.callback->call(facebook::jsi::Value::undefined());
|
|
510
|
-
}
|
|
511
|
-
}
|
|
512
|
-
|
|
513
|
-
bool isStopCollectingData() const {
|
|
514
|
-
return this->OnDataV2Assignee.isStopCollecting;
|
|
515
|
-
}
|
|
516
|
-
|
|
517
|
-
void stopCollectingData() {
|
|
518
|
-
this->OnDataV2Assignee.isStopCollecting = true;
|
|
519
|
-
}
|
|
520
|
-
|
|
521
|
-
void updateBuffer(std::string_view chunk,
|
|
522
|
-
unsigned long maxRemainingBodyLength) {
|
|
523
|
-
if(!this->OnDataV2Assignee.buffer) {
|
|
524
|
-
this->OnDataV2Assignee.buffer = std::make_shared<std::vector<char>>();
|
|
525
|
-
this->OnDataV2Assignee.buffer->reserve(maxRemainingBodyLength + chunk.size()); // preallocate with hint
|
|
526
|
-
}
|
|
527
|
-
this->OnDataV2Assignee.buffer->insert(this->OnDataV2Assignee.buffer->end(), chunk.begin(), chunk.end());
|
|
528
|
-
this->OnDataV2Assignee.maxRemainingBodyLength = maxRemainingBodyLength;
|
|
529
|
-
}
|
|
530
|
-
|
|
531
|
-
size_t getBufferSize() const {
|
|
532
|
-
return this->OnDataV2Assignee.buffer->size();
|
|
533
|
-
}
|
|
534
|
-
|
|
535
|
-
/**
|
|
536
|
-
* Probably bad name,
|
|
537
|
-
* it's used either for "onData", "onDataV2", or "onFullData", and combined for "onFullDataText"
|
|
538
|
-
*/
|
|
539
|
-
void invokeOnDataHandler() {
|
|
540
|
-
if(
|
|
541
|
-
!this->OnDataV2Assignee.isCallbackForFullChunk ||
|
|
542
|
-
this->OnDataV2Assignee.maxRemainingBodyLength == 0
|
|
543
|
-
) {
|
|
544
|
-
/// HELP me the better way to pass JSI ArrayBuffer here.
|
|
545
|
-
/// with faster buffer or anything
|
|
546
|
-
|
|
547
|
-
/// I have tested that,
|
|
548
|
-
/// when we captured the buffer by reference into the lambda,
|
|
549
|
-
/// in the middle of stream, it is often giving inaccuracy of
|
|
550
|
-
/// JS ArrayBuffer.byteLength in the `onDataV2` argument
|
|
551
|
-
/// when it's compared to the maxRemainingBodyLength differentiation that captured by value.
|
|
552
|
-
/// It's still accurate when it's finished.
|
|
553
|
-
|
|
554
|
-
/// While capturing the buffer by value is often accurate.
|
|
555
|
-
/// but is it slower?
|
|
556
|
-
|
|
557
|
-
if(this->OnDataV2Assignee.callback) {
|
|
558
|
-
this->OnDataV2Assignee.callback
|
|
559
|
-
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
560
|
-
[buffer = this->OnDataV2Assignee.buffer, maxRemainingBodyLength = this->OnDataV2Assignee.maxRemainingBodyLength](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
561
|
-
auto mutableBuffer = CharsMutableBuffer(buffer);
|
|
562
|
-
|
|
563
|
-
cb.call(rt,
|
|
564
|
-
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))),
|
|
565
|
-
facebook::jsi::BigInt::fromUint64(rt, maxRemainingBodyLength));
|
|
566
|
-
});
|
|
567
|
-
}
|
|
568
|
-
|
|
569
|
-
if(this->OnDataV2Assignee.callbackStr) {
|
|
570
|
-
this->OnDataV2Assignee.callbackStr
|
|
571
|
-
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
572
|
-
[buffer = this->OnDataV2Assignee.buffer, maxRemainingBodyLength = this->OnDataV2Assignee.maxRemainingBodyLength](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
573
|
-
cb.call(rt,
|
|
574
|
-
std::string(buffer->begin(), buffer->end()),
|
|
575
|
-
facebook::jsi::BigInt::fromUint64(rt, maxRemainingBodyLength));
|
|
576
|
-
});
|
|
577
|
-
}
|
|
578
|
-
}
|
|
579
|
-
}
|
|
580
|
-
|
|
581
|
-
};
|
|
450
|
+
}; // HttpResponseObject
|
|
582
451
|
|
|
583
|
-
}
|
|
452
|
+
} // namespace uws_react_native
|