uws-react-native 0.0.1-alpha.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/LICENSE +201 -0
- package/README.md +84 -0
- package/UwsReactNative.podspec +71 -0
- package/android/build.gradle.kts +138 -0
- package/android/src/main/AndroidManifest.xml +2 -0
- package/android/src/main/java/id/sufeni/oss/uwsreactnative/UwsReactNativePackage.kt +18 -0
- package/apple/OnLoad.mm +17 -0
- package/cpp/CMakeLists.txt +154 -0
- package/cpp/UwsReactNativeModule.cpp +191 -0
- package/cpp/UwsReactNativeModule.h +30 -0
- package/cpp/app/AppHost.h +37 -0
- package/cpp/app/AppRunner.h +88 -0
- package/cpp/app/CMakeLists.txt +39 -0
- package/cpp/app/HttpRequestObject.h +173 -0
- package/cpp/app/HttpResponseObject.h +623 -0
- package/cpp/app/RecognizedString.h +71 -0
- package/cpp/app/TemplatedAppObject.h +472 -0
- package/cpp/bridging/ArrayBuffer.h +150 -0
- package/cpp/bridging/CMakeLists.txt +34 -0
- package/cpp/jsi/Buffer.h +91 -0
- package/cpp/jsi/CMakeLists.txt +34 -0
- package/cpp/uSockets/bsd.c +767 -0
- package/cpp/uSockets/context.c +524 -0
- package/cpp/uSockets/crypto/openssl.c +858 -0
- package/cpp/uSockets/crypto/sni_tree.cpp +218 -0
- package/cpp/uSockets/eventing/asio.cpp +475 -0
- package/cpp/uSockets/eventing/epoll_kqueue.c +458 -0
- package/cpp/uSockets/eventing/gcd.c +278 -0
- package/cpp/uSockets/eventing/libuv.c +305 -0
- package/cpp/uSockets/internal/eventing/asio.h +45 -0
- package/cpp/uSockets/internal/eventing/epoll_kqueue.h +67 -0
- package/cpp/uSockets/internal/eventing/gcd.h +40 -0
- package/cpp/uSockets/internal/eventing/libuv.h +45 -0
- package/cpp/uSockets/internal/internal.h +224 -0
- package/cpp/uSockets/internal/loop_data.h +38 -0
- package/cpp/uSockets/internal/networking/bsd.h +109 -0
- package/cpp/uSockets/io_uring/internal.h +98 -0
- package/cpp/uSockets/io_uring/io_context.c +302 -0
- package/cpp/uSockets/io_uring/io_loop.c +422 -0
- package/cpp/uSockets/io_uring/io_socket.c +139 -0
- package/cpp/uSockets/libusockets.h +350 -0
- package/cpp/uSockets/loop.c +396 -0
- package/cpp/uSockets/quic.c +1071 -0
- package/cpp/uSockets/quic.h +68 -0
- package/cpp/uSockets/socket.c +231 -0
- package/cpp/uSockets/udp.c +151 -0
- package/cpp/uWebSockets/uWebSockets/App.h +676 -0
- package/cpp/uWebSockets/uWebSockets/AsyncSocket.h +376 -0
- package/cpp/uWebSockets/uWebSockets/AsyncSocketData.h +94 -0
- package/cpp/uWebSockets/uWebSockets/BloomFilter.h +83 -0
- package/cpp/uWebSockets/uWebSockets/CachingApp.h +115 -0
- package/cpp/uWebSockets/uWebSockets/ChunkedEncoding.h +237 -0
- package/cpp/uWebSockets/uWebSockets/ClientApp.h +36 -0
- package/cpp/uWebSockets/uWebSockets/Http3App.h +140 -0
- package/cpp/uWebSockets/uWebSockets/Http3Context.h +157 -0
- package/cpp/uWebSockets/uWebSockets/Http3ContextData.h +21 -0
- package/cpp/uWebSockets/uWebSockets/Http3Request.h +22 -0
- package/cpp/uWebSockets/uWebSockets/Http3Response.h +120 -0
- package/cpp/uWebSockets/uWebSockets/Http3ResponseData.h +25 -0
- package/cpp/uWebSockets/uWebSockets/HttpContext.h +521 -0
- package/cpp/uWebSockets/uWebSockets/HttpContextData.h +60 -0
- package/cpp/uWebSockets/uWebSockets/HttpErrors.h +53 -0
- package/cpp/uWebSockets/uWebSockets/HttpParser.h +747 -0
- package/cpp/uWebSockets/uWebSockets/HttpResponse.h +605 -0
- package/cpp/uWebSockets/uWebSockets/HttpResponseData.h +123 -0
- package/cpp/uWebSockets/uWebSockets/HttpRouter.h +384 -0
- package/cpp/uWebSockets/uWebSockets/LocalCluster.h +64 -0
- package/cpp/uWebSockets/uWebSockets/Loop.h +238 -0
- package/cpp/uWebSockets/uWebSockets/LoopData.h +113 -0
- package/cpp/uWebSockets/uWebSockets/MessageParser.h +64 -0
- package/cpp/uWebSockets/uWebSockets/MoveOnlyFunction.h +389 -0
- package/cpp/uWebSockets/uWebSockets/Multipart.h +231 -0
- package/cpp/uWebSockets/uWebSockets/PerMessageDeflate.h +303 -0
- package/cpp/uWebSockets/uWebSockets/ProxyParser.h +187 -0
- package/cpp/uWebSockets/uWebSockets/QueryParser.h +120 -0
- package/cpp/uWebSockets/uWebSockets/TopicTree.h +364 -0
- package/cpp/uWebSockets/uWebSockets/Utilities.h +66 -0
- package/cpp/uWebSockets/uWebSockets/WebSocket.h +407 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketContext.h +436 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketContextData.h +109 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketData.h +86 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketExtensions.h +256 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketHandshake.h +145 -0
- package/cpp/uWebSockets/uWebSockets/WebSocketProtocol.h +525 -0
- package/lib/commonjs/_internal/native-modules/NativeReactNativeUws.js +12 -0
- package/lib/commonjs/_internal/native-modules/NativeReactNativeUws.js.map +1 -0
- package/lib/commonjs/index.js +28 -0
- package/lib/commonjs/index.js.map +1 -0
- package/lib/commonjs/modules/App.js +17 -0
- package/lib/commonjs/modules/App.js.map +1 -0
- package/lib/commonjs/modules/CompressOptions.js +103 -0
- package/lib/commonjs/modules/CompressOptions.js.map +1 -0
- package/lib/commonjs/modules/EnvironmentVariables.js +17 -0
- package/lib/commonjs/modules/EnvironmentVariables.js.map +1 -0
- package/lib/commonjs/modules/ListenOptions.js +12 -0
- package/lib/commonjs/modules/ListenOptions.js.map +1 -0
- package/lib/commonjs/modules/SSLApp.js +15 -0
- package/lib/commonjs/modules/SSLApp.js.map +1 -0
- package/lib/commonjs/modules/getParts.js +28 -0
- package/lib/commonjs/modules/getParts.js.map +1 -0
- package/lib/commonjs/modules/index.js +61 -0
- package/lib/commonjs/modules/index.js.map +1 -0
- package/lib/commonjs/modules/us_listen_socket_close.js +21 -0
- package/lib/commonjs/modules/us_listen_socket_close.js.map +1 -0
- package/lib/commonjs/modules/us_socket_local_port.js +22 -0
- package/lib/commonjs/modules/us_socket_local_port.js.map +1 -0
- package/lib/commonjs/package.json +1 -0
- package/lib/commonjs/types/AppDescriptor.js +2 -0
- package/lib/commonjs/types/AppDescriptor.js.map +1 -0
- package/lib/commonjs/types/AppOptions.js +2 -0
- package/lib/commonjs/types/AppOptions.js.map +1 -0
- package/lib/commonjs/types/HttpRequest.js +6 -0
- package/lib/commonjs/types/HttpRequest.js.map +1 -0
- package/lib/commonjs/types/HttpResponse.js +6 -0
- package/lib/commonjs/types/HttpResponse.js.map +1 -0
- package/lib/commonjs/types/HttpRouterOptions.js +2 -0
- package/lib/commonjs/types/HttpRouterOptions.js.map +1 -0
- package/lib/commonjs/types/MultipartField.js +2 -0
- package/lib/commonjs/types/MultipartField.js.map +1 -0
- package/lib/commonjs/types/RecognizedString.js +2 -0
- package/lib/commonjs/types/RecognizedString.js.map +1 -0
- package/lib/commonjs/types/TemplatedApp.js +6 -0
- package/lib/commonjs/types/TemplatedApp.js.map +1 -0
- package/lib/commonjs/types/WebSocket.js +6 -0
- package/lib/commonjs/types/WebSocket.js.map +1 -0
- package/lib/commonjs/types/WebSocketBehaviour.js +139 -0
- package/lib/commonjs/types/WebSocketBehaviour.js.map +1 -0
- package/lib/commonjs/types/index.js +2 -0
- package/lib/commonjs/types/index.js.map +1 -0
- package/lib/commonjs/types/us_listen_socket.js +2 -0
- package/lib/commonjs/types/us_listen_socket.js.map +1 -0
- package/lib/commonjs/types/us_socket.js +2 -0
- package/lib/commonjs/types/us_socket.js.map +1 -0
- package/lib/commonjs/types/us_socket_context_t.js +2 -0
- package/lib/commonjs/types/us_socket_context_t.js.map +1 -0
- package/lib/module/_internal/native-modules/NativeReactNativeUws.js +10 -0
- package/lib/module/_internal/native-modules/NativeReactNativeUws.js.map +1 -0
- package/lib/module/index.js +5 -0
- package/lib/module/index.js.map +1 -0
- package/lib/module/modules/App.js +12 -0
- package/lib/module/modules/App.js.map +1 -0
- package/lib/module/modules/CompressOptions.js +103 -0
- package/lib/module/modules/CompressOptions.js.map +1 -0
- package/lib/module/modules/EnvironmentVariables.js +13 -0
- package/lib/module/modules/EnvironmentVariables.js.map +1 -0
- package/lib/module/modules/ListenOptions.js +8 -0
- package/lib/module/modules/ListenOptions.js.map +1 -0
- package/lib/module/modules/SSLApp.js +15 -0
- package/lib/module/modules/SSLApp.js.map +1 -0
- package/lib/module/modules/getParts.js +23 -0
- package/lib/module/modules/getParts.js.map +1 -0
- package/lib/module/modules/index.js +11 -0
- package/lib/module/modules/index.js.map +1 -0
- package/lib/module/modules/us_listen_socket_close.js +17 -0
- package/lib/module/modules/us_listen_socket_close.js.map +1 -0
- package/lib/module/modules/us_socket_local_port.js +18 -0
- package/lib/module/modules/us_socket_local_port.js.map +1 -0
- package/lib/module/package.json +1 -0
- package/lib/module/types/AppDescriptor.js +2 -0
- package/lib/module/types/AppDescriptor.js.map +1 -0
- package/lib/module/types/AppOptions.js +2 -0
- package/lib/module/types/AppOptions.js.map +1 -0
- package/lib/module/types/HttpRequest.js +4 -0
- package/lib/module/types/HttpRequest.js.map +1 -0
- package/lib/module/types/HttpResponse.js +4 -0
- package/lib/module/types/HttpResponse.js.map +1 -0
- package/lib/module/types/HttpRouterOptions.js +2 -0
- package/lib/module/types/HttpRouterOptions.js.map +1 -0
- package/lib/module/types/MultipartField.js +2 -0
- package/lib/module/types/MultipartField.js.map +1 -0
- package/lib/module/types/RecognizedString.js +2 -0
- package/lib/module/types/RecognizedString.js.map +1 -0
- package/lib/module/types/TemplatedApp.js +4 -0
- package/lib/module/types/TemplatedApp.js.map +1 -0
- package/lib/module/types/WebSocket.js +4 -0
- package/lib/module/types/WebSocket.js.map +1 -0
- package/lib/module/types/WebSocketBehaviour.js +139 -0
- package/lib/module/types/WebSocketBehaviour.js.map +1 -0
- package/lib/module/types/index.js +2 -0
- package/lib/module/types/index.js.map +1 -0
- package/lib/module/types/us_listen_socket.js +2 -0
- package/lib/module/types/us_listen_socket.js.map +1 -0
- package/lib/module/types/us_socket.js +2 -0
- package/lib/module/types/us_socket.js.map +1 -0
- package/lib/module/types/us_socket_context_t.js +2 -0
- package/lib/module/types/us_socket_context_t.js.map +1 -0
- package/lib/typescript/commonjs/_internal/native-modules/NativeReactNativeUws.d.ts +22 -0
- package/lib/typescript/commonjs/_internal/native-modules/NativeReactNativeUws.d.ts.map +1 -0
- package/lib/typescript/commonjs/index.d.ts +3 -0
- package/lib/typescript/commonjs/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/App.d.ts +7 -0
- package/lib/typescript/commonjs/modules/App.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/CompressOptions.d.ts +1 -0
- package/lib/typescript/commonjs/modules/CompressOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/EnvironmentVariables.d.ts +16 -0
- package/lib/typescript/commonjs/modules/EnvironmentVariables.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/ListenOptions.d.ts +5 -0
- package/lib/typescript/commonjs/modules/ListenOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/SSLApp.d.ts +1 -0
- package/lib/typescript/commonjs/modules/SSLApp.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/getParts.d.ts +6 -0
- package/lib/typescript/commonjs/modules/getParts.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/index.d.ts +6 -0
- package/lib/typescript/commonjs/modules/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/us_listen_socket_close.d.ts +5 -0
- package/lib/typescript/commonjs/modules/us_listen_socket_close.d.ts.map +1 -0
- package/lib/typescript/commonjs/modules/us_socket_local_port.d.ts +5 -0
- package/lib/typescript/commonjs/modules/us_socket_local_port.d.ts.map +1 -0
- package/lib/typescript/commonjs/package.json +1 -0
- package/lib/typescript/commonjs/types/AppDescriptor.d.ts +8 -0
- package/lib/typescript/commonjs/types/AppDescriptor.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/AppOptions.d.ts +17 -0
- package/lib/typescript/commonjs/types/AppOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/HttpRequest.d.ts +54 -0
- package/lib/typescript/commonjs/types/HttpRequest.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/HttpResponse.d.ts +169 -0
- package/lib/typescript/commonjs/types/HttpResponse.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/HttpRouterOptions.d.ts +24 -0
- package/lib/typescript/commonjs/types/HttpRouterOptions.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/MultipartField.d.ts +7 -0
- package/lib/typescript/commonjs/types/MultipartField.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/RecognizedString.d.ts +10 -0
- package/lib/typescript/commonjs/types/RecognizedString.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/TemplatedApp.d.ts +108 -0
- package/lib/typescript/commonjs/types/TemplatedApp.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/WebSocket.d.ts +96 -0
- package/lib/typescript/commonjs/types/WebSocket.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/WebSocketBehaviour.d.ts +1 -0
- package/lib/typescript/commonjs/types/WebSocketBehaviour.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/index.d.ts +6 -0
- package/lib/typescript/commonjs/types/index.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/us_listen_socket.d.ts +7 -0
- package/lib/typescript/commonjs/types/us_listen_socket.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/us_socket.d.ts +7 -0
- package/lib/typescript/commonjs/types/us_socket.d.ts.map +1 -0
- package/lib/typescript/commonjs/types/us_socket_context_t.d.ts +7 -0
- package/lib/typescript/commonjs/types/us_socket_context_t.d.ts.map +1 -0
- package/lib/typescript/module/_internal/native-modules/NativeReactNativeUws.d.ts +22 -0
- package/lib/typescript/module/_internal/native-modules/NativeReactNativeUws.d.ts.map +1 -0
- package/lib/typescript/module/index.d.ts +3 -0
- package/lib/typescript/module/index.d.ts.map +1 -0
- package/lib/typescript/module/modules/App.d.ts +7 -0
- package/lib/typescript/module/modules/App.d.ts.map +1 -0
- package/lib/typescript/module/modules/CompressOptions.d.ts +1 -0
- package/lib/typescript/module/modules/CompressOptions.d.ts.map +1 -0
- package/lib/typescript/module/modules/EnvironmentVariables.d.ts +16 -0
- package/lib/typescript/module/modules/EnvironmentVariables.d.ts.map +1 -0
- package/lib/typescript/module/modules/ListenOptions.d.ts +5 -0
- package/lib/typescript/module/modules/ListenOptions.d.ts.map +1 -0
- package/lib/typescript/module/modules/SSLApp.d.ts +1 -0
- package/lib/typescript/module/modules/SSLApp.d.ts.map +1 -0
- package/lib/typescript/module/modules/getParts.d.ts +6 -0
- package/lib/typescript/module/modules/getParts.d.ts.map +1 -0
- package/lib/typescript/module/modules/index.d.ts +6 -0
- package/lib/typescript/module/modules/index.d.ts.map +1 -0
- package/lib/typescript/module/modules/us_listen_socket_close.d.ts +5 -0
- package/lib/typescript/module/modules/us_listen_socket_close.d.ts.map +1 -0
- package/lib/typescript/module/modules/us_socket_local_port.d.ts +5 -0
- package/lib/typescript/module/modules/us_socket_local_port.d.ts.map +1 -0
- package/lib/typescript/module/package.json +1 -0
- package/lib/typescript/module/types/AppDescriptor.d.ts +8 -0
- package/lib/typescript/module/types/AppDescriptor.d.ts.map +1 -0
- package/lib/typescript/module/types/AppOptions.d.ts +17 -0
- package/lib/typescript/module/types/AppOptions.d.ts.map +1 -0
- package/lib/typescript/module/types/HttpRequest.d.ts +54 -0
- package/lib/typescript/module/types/HttpRequest.d.ts.map +1 -0
- package/lib/typescript/module/types/HttpResponse.d.ts +169 -0
- package/lib/typescript/module/types/HttpResponse.d.ts.map +1 -0
- package/lib/typescript/module/types/HttpRouterOptions.d.ts +24 -0
- package/lib/typescript/module/types/HttpRouterOptions.d.ts.map +1 -0
- package/lib/typescript/module/types/MultipartField.d.ts +7 -0
- package/lib/typescript/module/types/MultipartField.d.ts.map +1 -0
- package/lib/typescript/module/types/RecognizedString.d.ts +10 -0
- package/lib/typescript/module/types/RecognizedString.d.ts.map +1 -0
- package/lib/typescript/module/types/TemplatedApp.d.ts +108 -0
- package/lib/typescript/module/types/TemplatedApp.d.ts.map +1 -0
- package/lib/typescript/module/types/WebSocket.d.ts +96 -0
- package/lib/typescript/module/types/WebSocket.d.ts.map +1 -0
- package/lib/typescript/module/types/WebSocketBehaviour.d.ts +1 -0
- package/lib/typescript/module/types/WebSocketBehaviour.d.ts.map +1 -0
- package/lib/typescript/module/types/index.d.ts +6 -0
- package/lib/typescript/module/types/index.d.ts.map +1 -0
- package/lib/typescript/module/types/us_listen_socket.d.ts +7 -0
- package/lib/typescript/module/types/us_listen_socket.d.ts.map +1 -0
- package/lib/typescript/module/types/us_socket.d.ts +7 -0
- package/lib/typescript/module/types/us_socket.d.ts.map +1 -0
- package/lib/typescript/module/types/us_socket_context_t.d.ts +7 -0
- package/lib/typescript/module/types/us_socket_context_t.d.ts.map +1 -0
- package/lib/typescript/tsconfig.tsbuildinfo +1 -0
- package/package.json +62 -0
- package/src/_internal/native-modules/NativeUwsReactNative.ts +40 -0
- package/src/index.ts +2 -0
- package/src/modules/App.ts +14 -0
- package/src/modules/CompressOptions.ts +101 -0
- package/src/modules/EnvironmentVariables.ts +16 -0
- package/src/modules/ListenOptions.ts +4 -0
- package/src/modules/SSLApp.ts +13 -0
- package/src/modules/getParts.ts +29 -0
- package/src/modules/index.ts +8 -0
- package/src/modules/us_listen_socket_close.ts +15 -0
- package/src/modules/us_socket_local_port.ts +16 -0
- package/src/types/AppDescriptor.ts +7 -0
- package/src/types/AppOptions.ts +22 -0
- package/src/types/HttpRequest.ts +74 -0
- package/src/types/HttpResponse.ts +309 -0
- package/src/types/HttpRouterOptions.ts +24 -0
- package/src/types/MultipartField.ts +6 -0
- package/src/types/RecognizedString.ts +11 -0
- package/src/types/TemplatedApp.ts +285 -0
- package/src/types/WebSocket.ts +147 -0
- package/src/types/WebSocketBehaviour.ts +137 -0
- package/src/types/index.ts +12 -0
- package/src/types/us_listen_socket.ts +6 -0
- package/src/types/us_socket.ts +6 -0
- package/src/types/us_socket_context_t.ts +6 -0
|
@@ -0,0 +1,623 @@
|
|
|
1
|
+
#pragma once
|
|
2
|
+
|
|
3
|
+
#include <jsi/Buffer.h>
|
|
4
|
+
#include <jsi/jsi.h>
|
|
5
|
+
#include <utility>
|
|
6
|
+
#include "RecognizedString.h"
|
|
7
|
+
#include "uWebSockets/HttpResponse.h"
|
|
8
|
+
|
|
9
|
+
namespace uws_react_native {
|
|
10
|
+
|
|
11
|
+
struct HttpResponseObjectOptions {
|
|
12
|
+
bool disableBodyRead;
|
|
13
|
+
unsigned long maxBodySize;
|
|
14
|
+
};
|
|
15
|
+
|
|
16
|
+
class HttpResponseObject : public facebook::jsi::Object {
|
|
17
|
+
|
|
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 setChunk(std::string_view chunk,
|
|
56
|
+
unsigned long maxRemainingBodyLength) {
|
|
57
|
+
if(!this->OnDataV2Assignee.buffer) {
|
|
58
|
+
this->OnDataV2Assignee.buffer = std::make_shared<std::vector<char>>();
|
|
59
|
+
this->OnDataV2Assignee.buffer->reserve(maxRemainingBodyLength + chunk.size()); // preallocate with hint
|
|
60
|
+
}
|
|
61
|
+
this->OnDataV2Assignee.buffer->insert(this->OnDataV2Assignee.buffer->end(), chunk.begin(), chunk.end());
|
|
62
|
+
// this->OnDataV2Assignee.chunk.append(chunk.data(), chunk.size());
|
|
63
|
+
this->OnDataV2Assignee.maxRemainingBodyLength = maxRemainingBodyLength;
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
/**
|
|
67
|
+
* Probably bad name,
|
|
68
|
+
* it's used either for "onData", "onDataV2", or "onFullData", and combined for "onFullDataText"
|
|
69
|
+
*/
|
|
70
|
+
void invokeOnDataHandler() {
|
|
71
|
+
if(
|
|
72
|
+
!this->OnDataV2Assignee.isCallbackForFullChunk ||
|
|
73
|
+
this->OnDataV2Assignee.maxRemainingBodyLength == 0
|
|
74
|
+
) {
|
|
75
|
+
/// HELP me the better way to pass JSI ArrayBuffer here.
|
|
76
|
+
/// with faster buffer or anything
|
|
77
|
+
|
|
78
|
+
/// I have tested that,
|
|
79
|
+
/// when we captured the buffer by reference into the lambda,
|
|
80
|
+
/// in the middle of stream, it is often giving inaccuracy of
|
|
81
|
+
/// JS ArrayBuffer.byteLength in the `onDataV2` argument
|
|
82
|
+
/// when it's compared to the maxRemainingBodyLength differentiation that captured by value.
|
|
83
|
+
/// It's still accurate when it's finished.
|
|
84
|
+
|
|
85
|
+
/// While capturing the buffer by value is often accurate.
|
|
86
|
+
/// but is it slower?
|
|
87
|
+
|
|
88
|
+
if(this->OnDataV2Assignee.callback) {
|
|
89
|
+
this->OnDataV2Assignee.callback
|
|
90
|
+
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
91
|
+
[buffer = this->OnDataV2Assignee.buffer, maxRemainingBodyLength = this->OnDataV2Assignee.maxRemainingBodyLength](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
92
|
+
auto mutableBuffer = CharsMutableBuffer(buffer);
|
|
93
|
+
|
|
94
|
+
cb.call(rt,
|
|
95
|
+
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))),
|
|
96
|
+
facebook::jsi::BigInt::fromUint64(rt, maxRemainingBodyLength));
|
|
97
|
+
});
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
if(this->OnDataV2Assignee.callbackStr) {
|
|
101
|
+
this->OnDataV2Assignee.callbackStr
|
|
102
|
+
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
103
|
+
[buffer = this->OnDataV2Assignee.buffer, maxRemainingBodyLength = this->OnDataV2Assignee.maxRemainingBodyLength](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
104
|
+
cb.call(rt,
|
|
105
|
+
std::string(buffer->begin(), buffer->end()),
|
|
106
|
+
facebook::jsi::BigInt::fromUint64(rt, maxRemainingBodyLength));
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
// void preEnd(facebook::jsi::Runtime &rt) const {
|
|
113
|
+
// if(this->OnAbortedAssignee.alreadyAborted) {
|
|
114
|
+
// /// Stated from uWebSockets
|
|
115
|
+
// /// Every HttpResponse MUST have an attached abort handler.
|
|
116
|
+
// /// If you do not respond to it immediately inside of the callback.
|
|
117
|
+
// /// Returning from an Http request handler without attaching
|
|
118
|
+
// /// (by calling onAborted) an abort handler is ill-use and will terminate.
|
|
119
|
+
// /// When this event emits, the response has been aborted and may not be used.
|
|
120
|
+
// throw facebook::jsi::JSError(rt, "Cannot send response to aborted request");
|
|
121
|
+
// }
|
|
122
|
+
// }
|
|
123
|
+
|
|
124
|
+
public:
|
|
125
|
+
HttpResponseObject(facebook::jsi::Runtime &rt,
|
|
126
|
+
uWS::HttpResponse<false> *res,
|
|
127
|
+
std::shared_ptr<facebook::react::CallInvoker> &jsInvoker,
|
|
128
|
+
std::optional<HttpResponseObjectOptions> &&options = HttpResponseObjectOptions{ .disableBodyRead = false, .maxBodySize = 0 }) : facebook::jsi::Object(rt) {
|
|
129
|
+
|
|
130
|
+
this->setProperty(rt,
|
|
131
|
+
"close",
|
|
132
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
133
|
+
facebook::jsi::PropNameID::forUtf8(rt, "close"),
|
|
134
|
+
1,
|
|
135
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
136
|
+
const facebook::jsi::Value &thisValue,
|
|
137
|
+
const facebook::jsi::Value *arguments,
|
|
138
|
+
size_t count) -> facebook::jsi::Value {
|
|
139
|
+
res->close();
|
|
140
|
+
return {rt_1, thisValue};
|
|
141
|
+
}));
|
|
142
|
+
|
|
143
|
+
this->setProperty(rt,
|
|
144
|
+
"cork",
|
|
145
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
146
|
+
facebook::jsi::PropNameID::forUtf8(rt, "cork"),
|
|
147
|
+
1,
|
|
148
|
+
[res, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
149
|
+
const facebook::jsi::Value &thisValue,
|
|
150
|
+
const facebook::jsi::Value *arguments,
|
|
151
|
+
size_t count) -> facebook::jsi::Value {
|
|
152
|
+
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
153
|
+
|
|
154
|
+
res->cork([asyncCallback = facebook::react::AsyncCallback(rt_1, std::move(callback), jsInvoker)]() {
|
|
155
|
+
asyncCallback.call();
|
|
156
|
+
});
|
|
157
|
+
|
|
158
|
+
return {rt_1, thisValue};
|
|
159
|
+
}));
|
|
160
|
+
|
|
161
|
+
this->setProperty(rt,
|
|
162
|
+
"end", facebook::jsi::Function::createFromHostFunction(rt,
|
|
163
|
+
facebook::jsi::PropNameID::forUtf8(rt, "end"),
|
|
164
|
+
1,
|
|
165
|
+
[this, res](facebook::jsi::Runtime &rt_1,
|
|
166
|
+
const facebook::jsi::Value &thisValue,
|
|
167
|
+
const facebook::jsi::Value *arguments,
|
|
168
|
+
size_t count) -> facebook::jsi::Value {
|
|
169
|
+
/// Due to JS run at different thread
|
|
170
|
+
/// The race condition event is not avoidable under stress test
|
|
171
|
+
/// Our predefined `res->onAborted` call earlier than JS callback
|
|
172
|
+
/// This below makes JS side can call the "res.end" without attaching `onAborted` handler at all.
|
|
173
|
+
/// If we know how to make a sync call across the thread, please update this.
|
|
174
|
+
if(this->OnAbortedAssignee.alreadyAborted) {
|
|
175
|
+
return {rt_1, thisValue};
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
auto body = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
179
|
+
res->end(body);
|
|
180
|
+
|
|
181
|
+
return {rt_1, thisValue};
|
|
182
|
+
}));
|
|
183
|
+
|
|
184
|
+
this->setProperty(rt,
|
|
185
|
+
"endWithoutBody",
|
|
186
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
187
|
+
facebook::jsi::PropNameID::forUtf8(rt, "endWithoutBody"),
|
|
188
|
+
2,
|
|
189
|
+
[this, res](facebook::jsi::Runtime &rt_1,
|
|
190
|
+
const facebook::jsi::Value &thisValue,
|
|
191
|
+
const facebook::jsi::Value *arguments,
|
|
192
|
+
size_t count) -> facebook::jsi::Value {
|
|
193
|
+
/// Due to JS run at different thread
|
|
194
|
+
/// The race condition event is not avoidable under stress test
|
|
195
|
+
/// Our predefined `res->onAborted` call earlier than JS callback
|
|
196
|
+
/// This below makes JS side can call the "res.end" without attaching `onAborted` handler at all.
|
|
197
|
+
/// If we know how to make a sync call across the thread, please update this.
|
|
198
|
+
if(this->OnAbortedAssignee.alreadyAborted) {
|
|
199
|
+
return {rt_1, thisValue};
|
|
200
|
+
}
|
|
201
|
+
|
|
202
|
+
if(!arguments) {
|
|
203
|
+
res->endWithoutBody();
|
|
204
|
+
return {rt_1, thisValue};
|
|
205
|
+
}
|
|
206
|
+
|
|
207
|
+
std::optional<double> reportedContentLength = std::nullopt;
|
|
208
|
+
bool closeConnection = false;
|
|
209
|
+
|
|
210
|
+
if(arguments[0].isNumber()) {
|
|
211
|
+
reportedContentLength = arguments[0].asNumber();
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
if(arguments[1].isBool()) {
|
|
215
|
+
closeConnection = arguments[1].asBool();
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
res->endWithoutBody(reportedContentLength, closeConnection);
|
|
219
|
+
|
|
220
|
+
return {rt_1, thisValue};
|
|
221
|
+
}));
|
|
222
|
+
|
|
223
|
+
this->setProperty(rt,
|
|
224
|
+
"getRemoteAddressAsText",
|
|
225
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
226
|
+
facebook::jsi::PropNameID::forUtf8(rt, "getRemoteAddressAsText"),
|
|
227
|
+
0,
|
|
228
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
229
|
+
const facebook::jsi::Value &thisValue,
|
|
230
|
+
const facebook::jsi::Value *arguments,
|
|
231
|
+
size_t count) -> facebook::jsi::Value {
|
|
232
|
+
auto remoteAddress = res->getRemoteAddressAsText();
|
|
233
|
+
return facebook::jsi::String::createFromUtf8(rt_1, std::string(remoteAddress));
|
|
234
|
+
}));
|
|
235
|
+
|
|
236
|
+
this->setProperty(rt,
|
|
237
|
+
"getRemotePort",
|
|
238
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
239
|
+
facebook::jsi::PropNameID::forUtf8(rt, "getRemotePort"),
|
|
240
|
+
0,
|
|
241
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
242
|
+
const facebook::jsi::Value &thisValue,
|
|
243
|
+
const facebook::jsi::Value *arguments,
|
|
244
|
+
size_t count) -> facebook::jsi::Value {
|
|
245
|
+
return facebook::jsi::BigInt::fromUint64(rt_1, res->getRemotePort());
|
|
246
|
+
}));
|
|
247
|
+
|
|
248
|
+
this->setProperty(rt,
|
|
249
|
+
"getWriteOffset",
|
|
250
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
251
|
+
facebook::jsi::PropNameID::forUtf8(rt, "getWriteOffset"),
|
|
252
|
+
0,
|
|
253
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
254
|
+
const facebook::jsi::Value &thisValue,
|
|
255
|
+
const facebook::jsi::Value *arguments,
|
|
256
|
+
size_t count) -> facebook::jsi::Value {
|
|
257
|
+
return facebook::jsi::BigInt::fromUint64(rt_1, res->getWriteOffset());
|
|
258
|
+
}));
|
|
259
|
+
|
|
260
|
+
this->setProperty(rt,
|
|
261
|
+
"onAborted",
|
|
262
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
263
|
+
facebook::jsi::PropNameID::forUtf8(rt, "onAborted"),
|
|
264
|
+
1,
|
|
265
|
+
[this, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
266
|
+
const facebook::jsi::Value &thisValue,
|
|
267
|
+
const facebook::jsi::Value *arguments,
|
|
268
|
+
size_t count) -> facebook::jsi::Value {
|
|
269
|
+
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
270
|
+
|
|
271
|
+
if(this->OnAbortedAssignee.alreadyAborted) {
|
|
272
|
+
facebook::react::AsyncCallback(rt_1, std::move(callback), jsInvoker).call();
|
|
273
|
+
} else {
|
|
274
|
+
this->OnAbortedAssignee.callback = std::make_shared<facebook::react::AsyncCallback<facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
275
|
+
}
|
|
276
|
+
|
|
277
|
+
return {rt_1, thisValue};
|
|
278
|
+
}));
|
|
279
|
+
|
|
280
|
+
this->setProperty(rt,
|
|
281
|
+
"onData",
|
|
282
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
283
|
+
facebook::jsi::PropNameID::forUtf8(rt, "onData"),
|
|
284
|
+
1,
|
|
285
|
+
[this, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
286
|
+
const facebook::jsi::Value &thisValue,
|
|
287
|
+
const facebook::jsi::Value *arguments,
|
|
288
|
+
size_t count) -> facebook::jsi::Value {
|
|
289
|
+
if(this->OnDataV2Assignee.callback) {
|
|
290
|
+
throw facebook::jsi::JSError(rt_1, "Cannot reassign onData or assign it with existing onDataV2 and/or onFullData handler");
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
/// Same usage as the onDataV2
|
|
294
|
+
/// except the second parameter to the JS handler is the boolean `isLast`
|
|
295
|
+
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
296
|
+
this->OnDataV2Assignee.callback = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
297
|
+
|
|
298
|
+
/// This a late call
|
|
299
|
+
if(
|
|
300
|
+
this->OnDataV2Assignee.isStopCollecting ||
|
|
301
|
+
this->OnDataV2Assignee.maxRemainingBodyLength == 0
|
|
302
|
+
) {
|
|
303
|
+
this->OnDataV2Assignee.callback->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
304
|
+
[this](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
305
|
+
// auto stringMutableBuffer = facebook::jsi::StringMutableBuffer(&this->OnDataV2Assignee.chunk);
|
|
306
|
+
auto mutableBuffer = CharsMutableBuffer(this->OnDataV2Assignee.buffer.get());
|
|
307
|
+
cb.call(rt,
|
|
308
|
+
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))),
|
|
309
|
+
this->OnDataV2Assignee.maxRemainingBodyLength == 0);
|
|
310
|
+
});
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
return facebook::jsi::Value::undefined();
|
|
314
|
+
}));
|
|
315
|
+
|
|
316
|
+
this->setProperty(rt,
|
|
317
|
+
"onDataV2",
|
|
318
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
319
|
+
facebook::jsi::PropNameID::forUtf8(rt, "onDataV2"),
|
|
320
|
+
1,
|
|
321
|
+
[this, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
322
|
+
const facebook::jsi::Value &thisValue,
|
|
323
|
+
const facebook::jsi::Value *arguments,
|
|
324
|
+
size_t count) -> facebook::jsi::Value {
|
|
325
|
+
if(this->OnDataV2Assignee.callback) {
|
|
326
|
+
throw facebook::jsi::JSError(rt_1, "Cannot reassign onDataV2 or assign it with existing onData and/or onFullData handler");
|
|
327
|
+
}
|
|
328
|
+
|
|
329
|
+
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
330
|
+
this->OnDataV2Assignee.callback = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
331
|
+
|
|
332
|
+
/// This is a late call to the onDataV2 callback
|
|
333
|
+
/// due to the onDataV2 predefined lambda has finished earlier
|
|
334
|
+
/// or isStopCollecting is already marked
|
|
335
|
+
if(
|
|
336
|
+
this->OnDataV2Assignee.buffer &&
|
|
337
|
+
(this->OnDataV2Assignee.isStopCollecting || this->OnDataV2Assignee.maxRemainingBodyLength == 0)
|
|
338
|
+
) {
|
|
339
|
+
this->OnDataV2Assignee.callback
|
|
340
|
+
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
341
|
+
[this](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
342
|
+
// auto stringMutableBuffer = facebook::jsi::StringMutableBuffer(&this->OnDataV2Assignee.chunk);
|
|
343
|
+
auto mutableBuffer = CharsMutableBuffer(this->OnDataV2Assignee.buffer.get());
|
|
344
|
+
cb.call(rt,
|
|
345
|
+
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))),
|
|
346
|
+
facebook::jsi::BigInt::fromUint64(rt, this->OnDataV2Assignee.maxRemainingBodyLength));
|
|
347
|
+
});
|
|
348
|
+
}
|
|
349
|
+
|
|
350
|
+
return facebook::jsi::Value::undefined();
|
|
351
|
+
}));
|
|
352
|
+
|
|
353
|
+
this->setProperty(rt,
|
|
354
|
+
"onFullData",
|
|
355
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
356
|
+
facebook::jsi::PropNameID::forUtf8(rt, "onFullData"),
|
|
357
|
+
1,
|
|
358
|
+
[this, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
359
|
+
const facebook::jsi::Value &thisValue,
|
|
360
|
+
const facebook::jsi::Value *arguments,
|
|
361
|
+
size_t count) -> facebook::jsi::Value {
|
|
362
|
+
if(this->OnDataV2Assignee.callback) {
|
|
363
|
+
throw facebook::jsi::JSError(rt_1, "Cannot reassign onFullData or assign it with existing onData and/or onDataV2 handler");
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
367
|
+
this->OnDataV2Assignee.isCallbackForFullChunk = true;
|
|
368
|
+
this->OnDataV2Assignee.callback = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
369
|
+
|
|
370
|
+
/// This is a late call to the onFullData callback
|
|
371
|
+
/// due to the onDataV2 predefined lambda has finished earlier
|
|
372
|
+
/// or isStopCollecting is already marked
|
|
373
|
+
if(
|
|
374
|
+
this->OnDataV2Assignee.buffer &&
|
|
375
|
+
(this->OnDataV2Assignee.isStopCollecting || this->OnDataV2Assignee.maxRemainingBodyLength == 0)
|
|
376
|
+
) {
|
|
377
|
+
this->OnDataV2Assignee.callback
|
|
378
|
+
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
379
|
+
[this](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
380
|
+
// auto stringMutableBuffer = facebook::jsi::StringMutableBuffer(&this->OnDataV2Assignee.chunk);
|
|
381
|
+
auto mutableBuffer = CharsMutableBuffer(this->OnDataV2Assignee.buffer.get());
|
|
382
|
+
cb.call(rt,
|
|
383
|
+
facebook::jsi::ArrayBuffer(rt, std::make_shared<CharsMutableBuffer>(std::move(mutableBuffer))));
|
|
384
|
+
});
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
return facebook::jsi::Value::undefined();
|
|
388
|
+
}));
|
|
389
|
+
|
|
390
|
+
this->setProperty(rt,
|
|
391
|
+
"onFullDataText",
|
|
392
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
393
|
+
facebook::jsi::PropNameID::forUtf8(rt, "onFullDataText"),
|
|
394
|
+
1,
|
|
395
|
+
[this, &jsInvoker](facebook::jsi::Runtime &rt_1,
|
|
396
|
+
const facebook::jsi::Value &thisValue,
|
|
397
|
+
const facebook::jsi::Value *arguments,
|
|
398
|
+
size_t count) -> facebook::jsi::Value {
|
|
399
|
+
if(this->OnDataV2Assignee.callbackStr) {
|
|
400
|
+
throw facebook::jsi::JSError(rt_1, "Cannot reassign onFullDataText handler");
|
|
401
|
+
}
|
|
402
|
+
|
|
403
|
+
auto callback = arguments[0].asObject(rt_1).asFunction(rt_1);
|
|
404
|
+
this->OnDataV2Assignee.isCallbackForFullChunk = true;
|
|
405
|
+
this->OnDataV2Assignee.callbackStr = std::make_unique<facebook::react::AsyncCallback<facebook::jsi::Value, facebook::jsi::Value>>(rt_1, std::move(callback), jsInvoker);
|
|
406
|
+
|
|
407
|
+
/// This is a late call to the onFullDataText callback
|
|
408
|
+
/// due to the onDataV2 predefined lambda has finished earlier
|
|
409
|
+
/// or isStopCollecting is already marked
|
|
410
|
+
if(
|
|
411
|
+
this->OnDataV2Assignee.buffer &&
|
|
412
|
+
(this->OnDataV2Assignee.isStopCollecting || this->OnDataV2Assignee.maxRemainingBodyLength == 0)
|
|
413
|
+
) {
|
|
414
|
+
this->OnDataV2Assignee.callbackStr
|
|
415
|
+
->callWithPriority(facebook::react::SchedulerPriority::ImmediatePriority,
|
|
416
|
+
[this](facebook::jsi::Runtime &rt, facebook::jsi::Function &cb) {
|
|
417
|
+
cb.call(rt,
|
|
418
|
+
std::string(this->OnDataV2Assignee.buffer->begin(), this->OnDataV2Assignee.buffer->end()));
|
|
419
|
+
});
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
return facebook::jsi::Value::undefined();
|
|
423
|
+
}));
|
|
424
|
+
|
|
425
|
+
this->setProperty(rt,
|
|
426
|
+
"pause",
|
|
427
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
428
|
+
facebook::jsi::PropNameID::forUtf8(rt, "pause"),
|
|
429
|
+
0,
|
|
430
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
431
|
+
const facebook::jsi::Value &thisValue,
|
|
432
|
+
const facebook::jsi::Value *arguments,
|
|
433
|
+
size_t count) -> facebook::jsi::Value {
|
|
434
|
+
res->pause();
|
|
435
|
+
return facebook::jsi::Value::undefined();
|
|
436
|
+
}));
|
|
437
|
+
|
|
438
|
+
this->setProperty(rt,
|
|
439
|
+
"resume",
|
|
440
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
441
|
+
facebook::jsi::PropNameID::forUtf8(rt, "resume"),
|
|
442
|
+
0,
|
|
443
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
444
|
+
const facebook::jsi::Value &thisValue,
|
|
445
|
+
const facebook::jsi::Value *arguments,
|
|
446
|
+
size_t count) -> facebook::jsi::Value {
|
|
447
|
+
res->resume();
|
|
448
|
+
return facebook::jsi::Value::undefined();
|
|
449
|
+
}));
|
|
450
|
+
|
|
451
|
+
this->setProperty(rt,
|
|
452
|
+
"tryEnd",
|
|
453
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
454
|
+
facebook::jsi::PropNameID::forUtf8(rt, "tryEnd"),
|
|
455
|
+
2,
|
|
456
|
+
[this, res](facebook::jsi::Runtime &rt_1,
|
|
457
|
+
const facebook::jsi::Value &thisValue,
|
|
458
|
+
const facebook::jsi::Value *arguments,
|
|
459
|
+
size_t count) -> facebook::jsi::Value {
|
|
460
|
+
/// Due to JS run at different thread
|
|
461
|
+
/// The race condition event is not avoidable under stress test
|
|
462
|
+
/// Our predefined `res->onAborted` call earlier than JS callback
|
|
463
|
+
/// This below makes JS side can call the "res.end" without attaching `onAborted` handler at all.
|
|
464
|
+
/// If we know how to make a JS sync call across the thread, please update this.
|
|
465
|
+
if(this->OnAbortedAssignee.alreadyAborted) {
|
|
466
|
+
return {rt_1, thisValue};
|
|
467
|
+
}
|
|
468
|
+
|
|
469
|
+
auto fullBodyOrChunk = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
470
|
+
auto totalSize = arguments[1].asNumber();
|
|
471
|
+
|
|
472
|
+
auto tryEndResult = res->tryEnd(fullBodyOrChunk, static_cast<uintmax_t>(totalSize));
|
|
473
|
+
|
|
474
|
+
return facebook::jsi::Array::createWithElements(rt_1, {tryEndResult.first, tryEndResult.second});
|
|
475
|
+
}));
|
|
476
|
+
|
|
477
|
+
/// TODO
|
|
478
|
+
/// Implement this method later
|
|
479
|
+
/// It looks like we need to persist/save the us_socket_context_t from the ws.
|
|
480
|
+
// this->setProperty(rt, "upgrade", facebook::jsi::Function::createFromHostFunction(rt,
|
|
481
|
+
// facebook::jsi::PropNameID::forUtf8(rt, "upgrade"),
|
|
482
|
+
// 5,
|
|
483
|
+
// [res](facebook::jsi::Runtime &rt_1,
|
|
484
|
+
// const facebook::jsi::Value &thisValue,
|
|
485
|
+
// const facebook::jsi::Value *arguments,
|
|
486
|
+
// size_t count) -> facebook::jsi::Value {
|
|
487
|
+
// if(!arguments ||
|
|
488
|
+
// count != 5 ||
|
|
489
|
+
// !arguments[0].isString() ||
|
|
490
|
+
// !arguments[1].isString() ||
|
|
491
|
+
// !arguments[2].isString() ||
|
|
492
|
+
// !arguments[3].isString() ||
|
|
493
|
+
// !arguments[4].isNumber()) {
|
|
494
|
+
// return facebook::jsi::Value::undefined();
|
|
495
|
+
// }
|
|
496
|
+
//
|
|
497
|
+
// auto userData = arguments[0].asString(rt_1).utf8(rt_1);
|
|
498
|
+
// auto secWebSocketKey = arguments[1].asString(rt_1).utf8(rt_1);
|
|
499
|
+
// auto secWebSocketProtocol = arguments[2].asString(rt_1).utf8(rt_1);
|
|
500
|
+
// auto secWebSocketExtensions = arguments[3].asString(rt_1).utf8(rt_1);
|
|
501
|
+
// auto context = arguments[4].asNumber();
|
|
502
|
+
//
|
|
503
|
+
// // TODO give user a warning if this method has been called outside of cork handler
|
|
504
|
+
// // assumeCorked()
|
|
505
|
+
//
|
|
506
|
+
// auto *usSocketContext = reinterpret_cast<us_socket_context_t *>(static_cast<u_long>(context));
|
|
507
|
+
//
|
|
508
|
+
// res->upgrade(std::string_view(userData),
|
|
509
|
+
// std::string_view(secWebSocketKey),
|
|
510
|
+
// std::string_view(secWebSocketProtocol),
|
|
511
|
+
// std::string_view(secWebSocketExtensions),
|
|
512
|
+
// usSocketContext);
|
|
513
|
+
//
|
|
514
|
+
// return facebook::jsi::Value::undefined();
|
|
515
|
+
// }));
|
|
516
|
+
|
|
517
|
+
this->setProperty(rt,
|
|
518
|
+
"write",
|
|
519
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
520
|
+
facebook::jsi::PropNameID::forUtf8(rt, "write"),
|
|
521
|
+
2,
|
|
522
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
523
|
+
const facebook::jsi::Value &thisValue,
|
|
524
|
+
const facebook::jsi::Value *arguments,
|
|
525
|
+
size_t count) -> facebook::jsi::Value {
|
|
526
|
+
auto chunk = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
527
|
+
return res->write(std::string_view(chunk));
|
|
528
|
+
}));
|
|
529
|
+
|
|
530
|
+
this->setProperty(rt,
|
|
531
|
+
"writeHeader",
|
|
532
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
533
|
+
facebook::jsi::PropNameID::forUtf8(rt, "writeHeader"),
|
|
534
|
+
2,
|
|
535
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
536
|
+
const facebook::jsi::Value &thisValue,
|
|
537
|
+
const facebook::jsi::Value *arguments,
|
|
538
|
+
size_t count) -> facebook::jsi::Value {
|
|
539
|
+
auto headerKey = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
540
|
+
auto headerVal = RecognizedString(rt_1, arguments[1]).getStringView();
|
|
541
|
+
res->writeHeader(headerKey, headerVal);
|
|
542
|
+
|
|
543
|
+
return {rt_1, thisValue};
|
|
544
|
+
}));
|
|
545
|
+
|
|
546
|
+
this->setProperty(rt,
|
|
547
|
+
"writeStatus",
|
|
548
|
+
facebook::jsi::Function::createFromHostFunction(rt,
|
|
549
|
+
facebook::jsi::PropNameID::forUtf8(rt, "writeStatus"),
|
|
550
|
+
1,
|
|
551
|
+
[res](facebook::jsi::Runtime &rt_1,
|
|
552
|
+
const facebook::jsi::Value &thisValue,
|
|
553
|
+
const facebook::jsi::Value *arguments,
|
|
554
|
+
size_t count) -> facebook::jsi::Value {
|
|
555
|
+
auto status = RecognizedString(rt_1, arguments[0]).getStringView();
|
|
556
|
+
res->writeStatus(status);
|
|
557
|
+
|
|
558
|
+
return {rt_1, thisValue};
|
|
559
|
+
}));
|
|
560
|
+
|
|
561
|
+
/// We have to make JS call asynchronously because the uWebSockets app run at different thread.
|
|
562
|
+
/// See the `uws_react_native::AppRunner`, and `facebook::react::AsyncCallback`.
|
|
563
|
+
/// So this predefined `onAborted` assignment below is to tell that
|
|
564
|
+
/// uWebSockets has to wait until JS call finished with the `res.end() or res.tryEnd()`.
|
|
565
|
+
///
|
|
566
|
+
/// Stated from uWebSockets
|
|
567
|
+
/// `Returning from a request handler without responding or attaching an onAborted handler is ill-use`
|
|
568
|
+
///
|
|
569
|
+
/// I thought `onAborted` is just a callback or event listener.
|
|
570
|
+
res->onAborted([this]() {
|
|
571
|
+
this->OnAbortedAssignee.alreadyAborted = true;
|
|
572
|
+
|
|
573
|
+
if(this->OnAbortedAssignee.callback) {
|
|
574
|
+
this->OnAbortedAssignee.callback->call(facebook::jsi::Value::undefined());
|
|
575
|
+
}
|
|
576
|
+
});
|
|
577
|
+
|
|
578
|
+
/// Sadly, we can't do late assignment to the onDataV2 and onData.
|
|
579
|
+
/// uWebSockets will do nothing to our handler if we assign the lambda so late.
|
|
580
|
+
/// So we have to predefined onDataV2 handler here, and save the chunk.
|
|
581
|
+
if(!options->disableBodyRead) {
|
|
582
|
+
res->onDataV2([this, maxBodySize = options->maxBodySize](auto chunk, auto maxRemainingBodyLength) {
|
|
583
|
+
if(this->OnDataV2Assignee.isStopCollecting) {
|
|
584
|
+
return;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
if(maxBodySize > 0) {
|
|
588
|
+
auto chunkSize = chunk.size();
|
|
589
|
+
auto currentChunkSize = this->OnDataV2Assignee.buffer ? this->OnDataV2Assignee.buffer->size() : 0;
|
|
590
|
+
|
|
591
|
+
/// First and possibly only chunk
|
|
592
|
+
if(currentChunkSize == 0 && chunkSize > maxBodySize) {
|
|
593
|
+
this->OnDataV2Assignee.isStopCollecting = true;
|
|
594
|
+
/// set the first chunk
|
|
595
|
+
this->setChunk(chunk, maxRemainingBodyLength);
|
|
596
|
+
this->invokeOnDataHandler();
|
|
597
|
+
return;
|
|
598
|
+
}
|
|
599
|
+
|
|
600
|
+
/// subsequent chunks overflow
|
|
601
|
+
if(currentChunkSize > 0 && chunkSize > maxBodySize - currentChunkSize) {
|
|
602
|
+
/// tell to JS that we already stop collecting chunk
|
|
603
|
+
/// and invoke the JSI onData / onDataText / onDataV2 / onFullData / onFullDataText handler immediately
|
|
604
|
+
this->OnDataV2Assignee.isStopCollecting = true;
|
|
605
|
+
this->invokeOnDataHandler();
|
|
606
|
+
return;
|
|
607
|
+
}
|
|
608
|
+
}
|
|
609
|
+
|
|
610
|
+
this->setChunk(chunk, maxRemainingBodyLength);
|
|
611
|
+
this->invokeOnDataHandler();
|
|
612
|
+
|
|
613
|
+
/// About the invokeOnDataHandler,
|
|
614
|
+
/// JS call may late
|
|
615
|
+
/// it will invokes the handler once when user pass the handler.
|
|
616
|
+
});
|
|
617
|
+
}
|
|
618
|
+
|
|
619
|
+
} // HttpResponseObject
|
|
620
|
+
|
|
621
|
+
};
|
|
622
|
+
|
|
623
|
+
}
|