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,389 @@
|
|
|
1
|
+
/*
|
|
2
|
+
MIT License
|
|
3
|
+
|
|
4
|
+
Copyright (c) 2020 Oleg Fatkhiev
|
|
5
|
+
|
|
6
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
7
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
8
|
+
in the Software without restriction, including without limitation the rights
|
|
9
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
10
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
11
|
+
furnished to do so, subject to the following conditions:
|
|
12
|
+
|
|
13
|
+
The above copyright notice and this permission notice shall be included in all
|
|
14
|
+
copies or substantial portions of the Software.
|
|
15
|
+
|
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
17
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
18
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
19
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
20
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
21
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
22
|
+
SOFTWARE.
|
|
23
|
+
*/
|
|
24
|
+
|
|
25
|
+
/* Sources fetched from https://github.com/ofats/any_invocable on 2021-02-19. */
|
|
26
|
+
|
|
27
|
+
#ifndef _ANY_INVOKABLE_H_
|
|
28
|
+
#define _ANY_INVOKABLE_H_
|
|
29
|
+
|
|
30
|
+
#include <functional>
|
|
31
|
+
|
|
32
|
+
#if !defined(__cpp_lib_move_only_function) || __cpp_lib_move_only_function < 202110L
|
|
33
|
+
|
|
34
|
+
#include <memory>
|
|
35
|
+
#include <type_traits>
|
|
36
|
+
|
|
37
|
+
// clang-format off
|
|
38
|
+
/*
|
|
39
|
+
namespace std {
|
|
40
|
+
template<class Sig> class any_invocable; // never defined
|
|
41
|
+
|
|
42
|
+
template<class R, class... ArgTypes>
|
|
43
|
+
class any_invocable<R(ArgTypes...) cv ref noexcept(noex)> {
|
|
44
|
+
public:
|
|
45
|
+
using result_type = R;
|
|
46
|
+
|
|
47
|
+
// SECTION.3, construct/copy/destroy
|
|
48
|
+
any_invocable() noexcept;
|
|
49
|
+
any_invocable(nullptr_t) noexcept;
|
|
50
|
+
any_invocable(any_invocable&&) noexcept;
|
|
51
|
+
template<class F> any_invocable(F&&);
|
|
52
|
+
|
|
53
|
+
template<class T, class... Args>
|
|
54
|
+
explicit any_invocable(in_place_type_t<T>, Args&&...);
|
|
55
|
+
template<class T, class U, class... Args>
|
|
56
|
+
explicit any_invocable(in_place_type_t<T>, initializer_list<U>, Args&&...);
|
|
57
|
+
|
|
58
|
+
any_invocable& operator=(any_invocable&&) noexcept;
|
|
59
|
+
any_invocable& operator=(nullptr_t) noexcept;
|
|
60
|
+
template<class F> any_invocable& operator=(F&&);
|
|
61
|
+
template<class F> any_invocable& operator=(reference_wrapper<F>) noexcept;
|
|
62
|
+
|
|
63
|
+
~any_invocable();
|
|
64
|
+
|
|
65
|
+
// SECTION.4, any_invocable modifiers
|
|
66
|
+
void swap(any_invocable&) noexcept;
|
|
67
|
+
|
|
68
|
+
// SECTION.5, any_invocable capacity
|
|
69
|
+
explicit operator bool() const noexcept;
|
|
70
|
+
|
|
71
|
+
// SECTION.6, any_invocable invocation
|
|
72
|
+
R operator()(ArgTypes...) cv ref noexcept(noex);
|
|
73
|
+
|
|
74
|
+
// SECTION.7, null pointer comparisons
|
|
75
|
+
friend bool operator==(const any_invocable&, nullptr_t) noexcept;
|
|
76
|
+
|
|
77
|
+
// SECTION.8, specialized algorithms
|
|
78
|
+
friend void swap(any_invocable&, any_invocable&) noexcept;
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
*/
|
|
82
|
+
// clang-format on
|
|
83
|
+
|
|
84
|
+
namespace ofats {
|
|
85
|
+
|
|
86
|
+
namespace any_detail {
|
|
87
|
+
|
|
88
|
+
using buffer = std::aligned_storage_t<sizeof(void*) * 2, alignof(void*)>;
|
|
89
|
+
|
|
90
|
+
template <class T>
|
|
91
|
+
inline constexpr bool is_small_object_v =
|
|
92
|
+
sizeof(T) <= sizeof(buffer) && alignof(buffer) % alignof(T) == 0 &&
|
|
93
|
+
std::is_nothrow_move_constructible_v<T>;
|
|
94
|
+
|
|
95
|
+
union storage {
|
|
96
|
+
void* ptr_ = nullptr;
|
|
97
|
+
buffer buf_;
|
|
98
|
+
};
|
|
99
|
+
|
|
100
|
+
enum class action { destroy, move };
|
|
101
|
+
|
|
102
|
+
template <class R, class... ArgTypes>
|
|
103
|
+
struct handler_traits {
|
|
104
|
+
template <class Derived>
|
|
105
|
+
struct handler_base {
|
|
106
|
+
static void handle(action act, storage* current, storage* other = nullptr) {
|
|
107
|
+
switch (act) {
|
|
108
|
+
case (action::destroy):
|
|
109
|
+
Derived::destroy(*current);
|
|
110
|
+
break;
|
|
111
|
+
case (action::move):
|
|
112
|
+
Derived::move(*current, *other);
|
|
113
|
+
break;
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
};
|
|
117
|
+
|
|
118
|
+
template <class T>
|
|
119
|
+
struct small_handler : handler_base<small_handler<T>> {
|
|
120
|
+
template <class... Args>
|
|
121
|
+
static void create(storage& s, Args&&... args) {
|
|
122
|
+
new (static_cast<void*>(&s.buf_)) T(std::forward<Args>(args)...);
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
static void destroy(storage& s) noexcept {
|
|
126
|
+
T& value = *static_cast<T*>(static_cast<void*>(&s.buf_));
|
|
127
|
+
value.~T();
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
static void move(storage& dst, storage& src) noexcept {
|
|
131
|
+
create(dst, std::move(*static_cast<T*>(static_cast<void*>(&src.buf_))));
|
|
132
|
+
destroy(src);
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
static R call(storage& s, ArgTypes... args) {
|
|
136
|
+
return std::invoke(*static_cast<T*>(static_cast<void*>(&s.buf_)),
|
|
137
|
+
std::forward<ArgTypes>(args)...);
|
|
138
|
+
}
|
|
139
|
+
};
|
|
140
|
+
|
|
141
|
+
template <class T>
|
|
142
|
+
struct large_handler : handler_base<large_handler<T>> {
|
|
143
|
+
template <class... Args>
|
|
144
|
+
static void create(storage& s, Args&&... args) {
|
|
145
|
+
s.ptr_ = new T(std::forward<Args>(args)...);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
static void destroy(storage& s) noexcept { delete static_cast<T*>(s.ptr_); }
|
|
149
|
+
|
|
150
|
+
static void move(storage& dst, storage& src) noexcept {
|
|
151
|
+
dst.ptr_ = src.ptr_;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
static R call(storage& s, ArgTypes... args) {
|
|
155
|
+
return std::invoke(*static_cast<T*>(s.ptr_),
|
|
156
|
+
std::forward<ArgTypes>(args)...);
|
|
157
|
+
}
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
template <class T>
|
|
161
|
+
using handler = std::conditional_t<is_small_object_v<T>, small_handler<T>,
|
|
162
|
+
large_handler<T>>;
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
template <class T>
|
|
166
|
+
struct is_in_place_type : std::false_type {};
|
|
167
|
+
|
|
168
|
+
template <class T>
|
|
169
|
+
struct is_in_place_type<std::in_place_type_t<T>> : std::true_type {};
|
|
170
|
+
|
|
171
|
+
template <class T>
|
|
172
|
+
inline constexpr auto is_in_place_type_v = is_in_place_type<T>::value;
|
|
173
|
+
|
|
174
|
+
template <class R, bool is_noexcept, class... ArgTypes>
|
|
175
|
+
class any_invocable_impl {
|
|
176
|
+
template <class T>
|
|
177
|
+
using handler =
|
|
178
|
+
typename any_detail::handler_traits<R, ArgTypes...>::template handler<T>;
|
|
179
|
+
|
|
180
|
+
using storage = any_detail::storage;
|
|
181
|
+
using action = any_detail::action;
|
|
182
|
+
using handle_func = void (*)(any_detail::action, any_detail::storage*,
|
|
183
|
+
any_detail::storage*);
|
|
184
|
+
using call_func = R (*)(any_detail::storage&, ArgTypes...);
|
|
185
|
+
|
|
186
|
+
public:
|
|
187
|
+
using result_type = R;
|
|
188
|
+
|
|
189
|
+
any_invocable_impl() noexcept = default;
|
|
190
|
+
any_invocable_impl(std::nullptr_t) noexcept {}
|
|
191
|
+
any_invocable_impl(any_invocable_impl&& rhs) noexcept {
|
|
192
|
+
if (rhs.handle_) {
|
|
193
|
+
handle_ = rhs.handle_;
|
|
194
|
+
handle_(action::move, &storage_, &rhs.storage_);
|
|
195
|
+
call_ = rhs.call_;
|
|
196
|
+
rhs.handle_ = nullptr;
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
|
|
200
|
+
any_invocable_impl& operator=(any_invocable_impl&& rhs) noexcept {
|
|
201
|
+
any_invocable_impl{std::move(rhs)}.swap(*this);
|
|
202
|
+
return *this;
|
|
203
|
+
}
|
|
204
|
+
any_invocable_impl& operator=(std::nullptr_t) noexcept {
|
|
205
|
+
destroy();
|
|
206
|
+
return *this;
|
|
207
|
+
}
|
|
208
|
+
|
|
209
|
+
~any_invocable_impl() { destroy(); }
|
|
210
|
+
|
|
211
|
+
void swap(any_invocable_impl& rhs) noexcept {
|
|
212
|
+
if (handle_) {
|
|
213
|
+
if (rhs.handle_) {
|
|
214
|
+
storage tmp;
|
|
215
|
+
handle_(action::move, &tmp, &storage_);
|
|
216
|
+
rhs.handle_(action::move, &storage_, &rhs.storage_);
|
|
217
|
+
handle_(action::move, &rhs.storage_, &tmp);
|
|
218
|
+
std::swap(handle_, rhs.handle_);
|
|
219
|
+
std::swap(call_, rhs.call_);
|
|
220
|
+
} else {
|
|
221
|
+
rhs.swap(*this);
|
|
222
|
+
}
|
|
223
|
+
} else if (rhs.handle_) {
|
|
224
|
+
rhs.handle_(action::move, &storage_, &rhs.storage_);
|
|
225
|
+
handle_ = rhs.handle_;
|
|
226
|
+
call_ = rhs.call_;
|
|
227
|
+
rhs.handle_ = nullptr;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
explicit operator bool() const noexcept { return handle_ != nullptr; }
|
|
232
|
+
|
|
233
|
+
protected:
|
|
234
|
+
template <class F, class... Args>
|
|
235
|
+
void create(Args&&... args) {
|
|
236
|
+
using hdl = handler<F>;
|
|
237
|
+
hdl::create(storage_, std::forward<Args>(args)...);
|
|
238
|
+
handle_ = &hdl::handle;
|
|
239
|
+
call_ = &hdl::call;
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
void destroy() noexcept {
|
|
243
|
+
if (handle_) {
|
|
244
|
+
handle_(action::destroy, &storage_, nullptr);
|
|
245
|
+
handle_ = nullptr;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
R call(ArgTypes... args) noexcept(is_noexcept) {
|
|
250
|
+
return call_(storage_, std::forward<ArgTypes>(args)...);
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
friend bool operator==(const any_invocable_impl& f, std::nullptr_t) noexcept {
|
|
254
|
+
return !f;
|
|
255
|
+
}
|
|
256
|
+
friend bool operator==(std::nullptr_t, const any_invocable_impl& f) noexcept {
|
|
257
|
+
return !f;
|
|
258
|
+
}
|
|
259
|
+
friend bool operator!=(const any_invocable_impl& f, std::nullptr_t) noexcept {
|
|
260
|
+
return static_cast<bool>(f);
|
|
261
|
+
}
|
|
262
|
+
friend bool operator!=(std::nullptr_t, const any_invocable_impl& f) noexcept {
|
|
263
|
+
return static_cast<bool>(f);
|
|
264
|
+
}
|
|
265
|
+
|
|
266
|
+
friend void swap(any_invocable_impl& lhs, any_invocable_impl& rhs) noexcept {
|
|
267
|
+
lhs.swap(rhs);
|
|
268
|
+
}
|
|
269
|
+
|
|
270
|
+
private:
|
|
271
|
+
storage storage_;
|
|
272
|
+
handle_func handle_ = nullptr;
|
|
273
|
+
call_func call_;
|
|
274
|
+
};
|
|
275
|
+
|
|
276
|
+
template <class T>
|
|
277
|
+
using remove_cvref_t = std::remove_cv_t<std::remove_reference_t<T>>;
|
|
278
|
+
|
|
279
|
+
template <class AI, class F, bool noex, class R, class FCall, class... ArgTypes>
|
|
280
|
+
using can_convert = std::conjunction<
|
|
281
|
+
std::negation<std::is_same<remove_cvref_t<F>, AI>>,
|
|
282
|
+
std::negation<any_detail::is_in_place_type<remove_cvref_t<F>>>,
|
|
283
|
+
std::is_invocable_r<R, FCall, ArgTypes...>,
|
|
284
|
+
std::bool_constant<(!noex ||
|
|
285
|
+
std::is_nothrow_invocable_r_v<R, FCall, ArgTypes...>)>,
|
|
286
|
+
std::is_constructible<std::decay_t<F>, F>>;
|
|
287
|
+
|
|
288
|
+
} // namespace any_detail
|
|
289
|
+
|
|
290
|
+
template <class Signature>
|
|
291
|
+
class any_invocable;
|
|
292
|
+
|
|
293
|
+
#define __OFATS_ANY_INVOCABLE(cv, ref, noex, inv_quals) \
|
|
294
|
+
template <class R, class... ArgTypes> \
|
|
295
|
+
class any_invocable<R(ArgTypes...) cv ref noexcept(noex)> \
|
|
296
|
+
: public any_detail::any_invocable_impl<R, noex, ArgTypes...> { \
|
|
297
|
+
using base_type = any_detail::any_invocable_impl<R, noex, ArgTypes...>; \
|
|
298
|
+
\
|
|
299
|
+
public: \
|
|
300
|
+
using base_type::base_type; \
|
|
301
|
+
\
|
|
302
|
+
template < \
|
|
303
|
+
class F, \
|
|
304
|
+
class = std::enable_if_t<any_detail::can_convert< \
|
|
305
|
+
any_invocable, F, noex, R, F inv_quals, ArgTypes...>::value>> \
|
|
306
|
+
any_invocable(F&& f) { \
|
|
307
|
+
base_type::template create<std::decay_t<F>>(std::forward<F>(f)); \
|
|
308
|
+
} \
|
|
309
|
+
\
|
|
310
|
+
template <class T, class... Args, class VT = std::decay_t<T>, \
|
|
311
|
+
class = std::enable_if_t< \
|
|
312
|
+
std::is_move_constructible_v<VT> && \
|
|
313
|
+
std::is_constructible_v<VT, Args...> && \
|
|
314
|
+
std::is_invocable_r_v<R, VT inv_quals, ArgTypes...> && \
|
|
315
|
+
(!noex || std::is_nothrow_invocable_r_v<R, VT inv_quals, \
|
|
316
|
+
ArgTypes...>)>> \
|
|
317
|
+
explicit any_invocable(std::in_place_type_t<T>, Args&&... args) { \
|
|
318
|
+
base_type::template create<VT>(std::forward<Args>(args)...); \
|
|
319
|
+
} \
|
|
320
|
+
\
|
|
321
|
+
template < \
|
|
322
|
+
class T, class U, class... Args, class VT = std::decay_t<T>, \
|
|
323
|
+
class = std::enable_if_t< \
|
|
324
|
+
std::is_move_constructible_v<VT> && \
|
|
325
|
+
std::is_constructible_v<VT, std::initializer_list<U>&, Args...> && \
|
|
326
|
+
std::is_invocable_r_v<R, VT inv_quals, ArgTypes...> && \
|
|
327
|
+
(!noex || \
|
|
328
|
+
std::is_nothrow_invocable_r_v<R, VT inv_quals, ArgTypes...>)>> \
|
|
329
|
+
explicit any_invocable(std::in_place_type_t<T>, \
|
|
330
|
+
std::initializer_list<U> il, Args&&... args) { \
|
|
331
|
+
base_type::template create<VT>(il, std::forward<Args>(args)...); \
|
|
332
|
+
} \
|
|
333
|
+
\
|
|
334
|
+
template <class F, class FDec = std::decay_t<F>> \
|
|
335
|
+
std::enable_if_t<!std::is_same_v<FDec, any_invocable> && \
|
|
336
|
+
std::is_move_constructible_v<FDec>, \
|
|
337
|
+
any_invocable&> \
|
|
338
|
+
operator=(F&& f) { \
|
|
339
|
+
any_invocable{std::forward<F>(f)}.swap(*this); \
|
|
340
|
+
return *this; \
|
|
341
|
+
} \
|
|
342
|
+
template <class F> \
|
|
343
|
+
any_invocable& operator=(std::reference_wrapper<F> f) { \
|
|
344
|
+
any_invocable{f}.swap(*this); \
|
|
345
|
+
return *this; \
|
|
346
|
+
} \
|
|
347
|
+
\
|
|
348
|
+
R operator()(ArgTypes... args) cv ref noexcept(noex) { \
|
|
349
|
+
return base_type::call(std::forward<ArgTypes>(args)...); \
|
|
350
|
+
} \
|
|
351
|
+
};
|
|
352
|
+
|
|
353
|
+
// cv -> {`empty`, const}
|
|
354
|
+
// ref -> {`empty`, &, &&}
|
|
355
|
+
// noex -> {true, false}
|
|
356
|
+
// inv_quals -> (is_empty(ref) ? & : ref)
|
|
357
|
+
__OFATS_ANY_INVOCABLE(, , false, &) // 000
|
|
358
|
+
__OFATS_ANY_INVOCABLE(, , true, &) // 001
|
|
359
|
+
__OFATS_ANY_INVOCABLE(, &, false, &) // 010
|
|
360
|
+
__OFATS_ANY_INVOCABLE(, &, true, &) // 011
|
|
361
|
+
__OFATS_ANY_INVOCABLE(, &&, false, &&) // 020
|
|
362
|
+
__OFATS_ANY_INVOCABLE(, &&, true, &&) // 021
|
|
363
|
+
__OFATS_ANY_INVOCABLE(const, , false, const&) // 100
|
|
364
|
+
__OFATS_ANY_INVOCABLE(const, , true, const&) // 101
|
|
365
|
+
__OFATS_ANY_INVOCABLE(const, &, false, const&) // 110
|
|
366
|
+
__OFATS_ANY_INVOCABLE(const, &, true, const&) // 111
|
|
367
|
+
__OFATS_ANY_INVOCABLE(const, &&, false, const&&) // 120
|
|
368
|
+
__OFATS_ANY_INVOCABLE(const, &&, true, const&&) // 121
|
|
369
|
+
|
|
370
|
+
#undef __OFATS_ANY_INVOCABLE
|
|
371
|
+
|
|
372
|
+
} // namespace ofats
|
|
373
|
+
|
|
374
|
+
/* We, uWebSockets define our own type */
|
|
375
|
+
namespace uWS {
|
|
376
|
+
template <class T>
|
|
377
|
+
using MoveOnlyFunction = ofats::any_invocable<T>;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
#else // !defined(__cpp_lib_move_only_function) || __cpp_lib_move_only_function < 202110L
|
|
381
|
+
|
|
382
|
+
namespace uWS {
|
|
383
|
+
template <class T>
|
|
384
|
+
using MoveOnlyFunction = std::move_only_function<T>;
|
|
385
|
+
}
|
|
386
|
+
|
|
387
|
+
#endif
|
|
388
|
+
|
|
389
|
+
#endif // _ANY_INVOKABLE_H_
|
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
/*
|
|
2
|
+
* Authored by Alex Hultman, 2018-2020.
|
|
3
|
+
* Intellectual property of third-party.
|
|
4
|
+
|
|
5
|
+
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
6
|
+
* you may not use this file except in compliance with the License.
|
|
7
|
+
* You may obtain a copy of the License at
|
|
8
|
+
|
|
9
|
+
* http://www.apache.org/licenses/LICENSE-2.0
|
|
10
|
+
|
|
11
|
+
* Unless required by applicable law or agreed to in writing, software
|
|
12
|
+
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
13
|
+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
14
|
+
* See the License for the specific language governing permissions and
|
|
15
|
+
* limitations under the License.
|
|
16
|
+
*/
|
|
17
|
+
|
|
18
|
+
/* Implements the multipart protocol. Builds atop parts of our common http parser (not yet refactored that way). */
|
|
19
|
+
/* https://www.w3.org/Protocols/rfc1341/7_2_Multipart.html */
|
|
20
|
+
|
|
21
|
+
#ifndef UWS_MULTIPART_H
|
|
22
|
+
#define UWS_MULTIPART_H
|
|
23
|
+
|
|
24
|
+
#include "MessageParser.h"
|
|
25
|
+
|
|
26
|
+
#include <string_view>
|
|
27
|
+
#include <optional>
|
|
28
|
+
#include <cstring>
|
|
29
|
+
#include <utility>
|
|
30
|
+
#include <cctype>
|
|
31
|
+
|
|
32
|
+
namespace uWS {
|
|
33
|
+
|
|
34
|
+
/* This one could possibly be shared with ExtensionsParser to some degree */
|
|
35
|
+
struct ParameterParser {
|
|
36
|
+
|
|
37
|
+
/* Takes the line, commonly given as content-disposition header in the multipart */
|
|
38
|
+
ParameterParser(std::string_view line) {
|
|
39
|
+
remainingLine = line;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
/* Returns next key/value where value can simply be empty.
|
|
43
|
+
* If key (first) is empty then we are at the end */
|
|
44
|
+
std::pair<std::string_view, std::string_view> getKeyValue() {
|
|
45
|
+
auto key = getToken();
|
|
46
|
+
auto op = getToken();
|
|
47
|
+
|
|
48
|
+
if (!op.length()) {
|
|
49
|
+
return {key, ""};
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
if (op[0] != ';') {
|
|
53
|
+
auto value = getToken();
|
|
54
|
+
/* Strip ; or if at end, nothing */
|
|
55
|
+
getToken();
|
|
56
|
+
return {key, value};
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
return {key, ""};
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
private:
|
|
63
|
+
std::string_view remainingLine;
|
|
64
|
+
|
|
65
|
+
/* Consumes a token from the line. Will "unquote" strings */
|
|
66
|
+
std::string_view getToken() {
|
|
67
|
+
/* Strip whitespace */
|
|
68
|
+
while (remainingLine.length() && isspace(remainingLine[0])) {
|
|
69
|
+
remainingLine.remove_prefix(1);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
if (!remainingLine.length()) {
|
|
73
|
+
/* All we had was space */
|
|
74
|
+
return {};
|
|
75
|
+
} else {
|
|
76
|
+
/* Are we at an operator? */
|
|
77
|
+
if (remainingLine[0] == ';' || remainingLine[0] == '=') {
|
|
78
|
+
auto op = remainingLine.substr(0, 1);
|
|
79
|
+
remainingLine.remove_prefix(1);
|
|
80
|
+
return op;
|
|
81
|
+
} else {
|
|
82
|
+
/* Are we at a quoted string? */
|
|
83
|
+
if (remainingLine[0] == '\"') {
|
|
84
|
+
/* Remove first quote and start counting */
|
|
85
|
+
remainingLine.remove_prefix(1);
|
|
86
|
+
auto quote = remainingLine;
|
|
87
|
+
int quoteLength = 0;
|
|
88
|
+
|
|
89
|
+
/* Read anything until other double quote appears */
|
|
90
|
+
while (remainingLine.length() && remainingLine[0] != '\"') {
|
|
91
|
+
remainingLine.remove_prefix(1);
|
|
92
|
+
quoteLength++;
|
|
93
|
+
}
|
|
94
|
+
|
|
95
|
+
/* We can't remove_prefix if we have nothing to remove */
|
|
96
|
+
if (!remainingLine.length()) {
|
|
97
|
+
return {};
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
remainingLine.remove_prefix(1);
|
|
101
|
+
return quote.substr(0, quoteLength);
|
|
102
|
+
} else {
|
|
103
|
+
/* Read anything until ; = space or end */
|
|
104
|
+
std::string_view token = remainingLine;
|
|
105
|
+
|
|
106
|
+
int tokenLength = 0;
|
|
107
|
+
while (remainingLine.length() && remainingLine[0] != ';' && remainingLine[0] != '=' && !isspace(remainingLine[0])) {
|
|
108
|
+
remainingLine.remove_prefix(1);
|
|
109
|
+
tokenLength++;
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
return token.substr(0, tokenLength);
|
|
113
|
+
}
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
/* Nothing */
|
|
118
|
+
return "";
|
|
119
|
+
}
|
|
120
|
+
};
|
|
121
|
+
|
|
122
|
+
struct MultipartParser {
|
|
123
|
+
|
|
124
|
+
/* 2 chars of hyphen + 1 - 70 chars of boundary */
|
|
125
|
+
char prependedBoundaryBuffer[72];
|
|
126
|
+
std::string_view prependedBoundary;
|
|
127
|
+
std::string_view remainingBody;
|
|
128
|
+
bool first = true;
|
|
129
|
+
|
|
130
|
+
/* I think it is more than sane to limit this to 10 per part */
|
|
131
|
+
//static const int MAX_HEADERS = 10;
|
|
132
|
+
|
|
133
|
+
/* Construct the parser based on contentType (reads boundary) */
|
|
134
|
+
MultipartParser(std::string_view contentType) {
|
|
135
|
+
|
|
136
|
+
/* We expect the form "multipart/something;somethingboundary=something" */
|
|
137
|
+
if (contentType.length() < 10 || contentType.substr(0, 10) != "multipart/") {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
/* For now we simply guess boundary will lie between = and end. This is not entirely
|
|
142
|
+
* standards compliant as boundary may be expressed with or without " and spaces */
|
|
143
|
+
auto equalToken = contentType.find('=', 10);
|
|
144
|
+
if (equalToken != std::string_view::npos) {
|
|
145
|
+
|
|
146
|
+
/* Boundary must be less than or equal to 70 chars yet 1 char or longer */
|
|
147
|
+
std::string_view boundary = contentType.substr(equalToken + 1);
|
|
148
|
+
if (!boundary.length() || boundary.length() > 70) {
|
|
149
|
+
/* Invalid size */
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/* Prepend it with two hyphens */
|
|
154
|
+
prependedBoundaryBuffer[0] = prependedBoundaryBuffer[1] = '-';
|
|
155
|
+
memcpy(&prependedBoundaryBuffer[2], boundary.data(), boundary.length());
|
|
156
|
+
|
|
157
|
+
prependedBoundary = {prependedBoundaryBuffer, boundary.length() + 2};
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
/* Is this even a valid multipart request? */
|
|
162
|
+
bool isValid() {
|
|
163
|
+
return prependedBoundary.length() != 0;
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
/* Set the body once, before getting any parts */
|
|
167
|
+
void setBody(std::string_view body) {
|
|
168
|
+
remainingBody = body;
|
|
169
|
+
}
|
|
170
|
+
|
|
171
|
+
/* Parse out the next part's data, filling the headers. Returns nullopt on end or error. */
|
|
172
|
+
std::optional<std::string_view> getNextPart(std::pair<std::string_view, std::string_view> *headers) {
|
|
173
|
+
|
|
174
|
+
/* The remaining two hyphens should be shorter than the boundary */
|
|
175
|
+
if (remainingBody.length() < prependedBoundary.length()) {
|
|
176
|
+
/* We are done now */
|
|
177
|
+
return std::nullopt;
|
|
178
|
+
}
|
|
179
|
+
|
|
180
|
+
if (first) {
|
|
181
|
+
auto nextBoundary = remainingBody.find(prependedBoundary);
|
|
182
|
+
if (nextBoundary == std::string_view::npos) {
|
|
183
|
+
/* Cannot parse */
|
|
184
|
+
return std::nullopt;
|
|
185
|
+
}
|
|
186
|
+
|
|
187
|
+
/* Toss away boundary and anything before it */
|
|
188
|
+
remainingBody.remove_prefix(nextBoundary + prependedBoundary.length());
|
|
189
|
+
first = false;
|
|
190
|
+
}
|
|
191
|
+
|
|
192
|
+
auto nextEndBoundary = remainingBody.find(prependedBoundary);
|
|
193
|
+
if (nextEndBoundary == std::string_view::npos) {
|
|
194
|
+
/* Cannot parse (or simply done) */
|
|
195
|
+
return std::nullopt;
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
std::string_view part = remainingBody.substr(0, nextEndBoundary);
|
|
199
|
+
remainingBody.remove_prefix(nextEndBoundary + prependedBoundary.length());
|
|
200
|
+
|
|
201
|
+
/* Also strip rn before and rn after the part */
|
|
202
|
+
if (part.length() < 4) {
|
|
203
|
+
/* Cannot strip */
|
|
204
|
+
return std::nullopt;
|
|
205
|
+
}
|
|
206
|
+
part.remove_prefix(2);
|
|
207
|
+
part.remove_suffix(2);
|
|
208
|
+
|
|
209
|
+
/* We are allowed to post pad like this because we know the boundary is at least 2 bytes */
|
|
210
|
+
/* This makes parsing a second pass invalid, so you can only iterate over parts once */
|
|
211
|
+
memset((char *) part.data() + part.length(), '\r', 1);
|
|
212
|
+
|
|
213
|
+
/* For this to be a valid part, we need to consume at least 4 bytes (\r\n\r\n) */
|
|
214
|
+
int consumed = getHeaders((char *) part.data(), (char *) part.data() + part.length(), headers);
|
|
215
|
+
|
|
216
|
+
if (!consumed) {
|
|
217
|
+
/* This is an invalid part */
|
|
218
|
+
return std::nullopt;
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
/* Strip away the headers from the part body data */
|
|
222
|
+
part.remove_prefix(consumed);
|
|
223
|
+
|
|
224
|
+
/* Now pass whatever is remaining of the part */
|
|
225
|
+
return part;
|
|
226
|
+
}
|
|
227
|
+
};
|
|
228
|
+
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
#endif
|