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.
Files changed (315) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +84 -0
  3. package/UwsReactNative.podspec +71 -0
  4. package/android/build.gradle.kts +138 -0
  5. package/android/src/main/AndroidManifest.xml +2 -0
  6. package/android/src/main/java/id/sufeni/oss/uwsreactnative/UwsReactNativePackage.kt +18 -0
  7. package/apple/OnLoad.mm +17 -0
  8. package/cpp/CMakeLists.txt +154 -0
  9. package/cpp/UwsReactNativeModule.cpp +191 -0
  10. package/cpp/UwsReactNativeModule.h +30 -0
  11. package/cpp/app/AppHost.h +37 -0
  12. package/cpp/app/AppRunner.h +88 -0
  13. package/cpp/app/CMakeLists.txt +39 -0
  14. package/cpp/app/HttpRequestObject.h +173 -0
  15. package/cpp/app/HttpResponseObject.h +623 -0
  16. package/cpp/app/RecognizedString.h +71 -0
  17. package/cpp/app/TemplatedAppObject.h +472 -0
  18. package/cpp/bridging/ArrayBuffer.h +150 -0
  19. package/cpp/bridging/CMakeLists.txt +34 -0
  20. package/cpp/jsi/Buffer.h +91 -0
  21. package/cpp/jsi/CMakeLists.txt +34 -0
  22. package/cpp/uSockets/bsd.c +767 -0
  23. package/cpp/uSockets/context.c +524 -0
  24. package/cpp/uSockets/crypto/openssl.c +858 -0
  25. package/cpp/uSockets/crypto/sni_tree.cpp +218 -0
  26. package/cpp/uSockets/eventing/asio.cpp +475 -0
  27. package/cpp/uSockets/eventing/epoll_kqueue.c +458 -0
  28. package/cpp/uSockets/eventing/gcd.c +278 -0
  29. package/cpp/uSockets/eventing/libuv.c +305 -0
  30. package/cpp/uSockets/internal/eventing/asio.h +45 -0
  31. package/cpp/uSockets/internal/eventing/epoll_kqueue.h +67 -0
  32. package/cpp/uSockets/internal/eventing/gcd.h +40 -0
  33. package/cpp/uSockets/internal/eventing/libuv.h +45 -0
  34. package/cpp/uSockets/internal/internal.h +224 -0
  35. package/cpp/uSockets/internal/loop_data.h +38 -0
  36. package/cpp/uSockets/internal/networking/bsd.h +109 -0
  37. package/cpp/uSockets/io_uring/internal.h +98 -0
  38. package/cpp/uSockets/io_uring/io_context.c +302 -0
  39. package/cpp/uSockets/io_uring/io_loop.c +422 -0
  40. package/cpp/uSockets/io_uring/io_socket.c +139 -0
  41. package/cpp/uSockets/libusockets.h +350 -0
  42. package/cpp/uSockets/loop.c +396 -0
  43. package/cpp/uSockets/quic.c +1071 -0
  44. package/cpp/uSockets/quic.h +68 -0
  45. package/cpp/uSockets/socket.c +231 -0
  46. package/cpp/uSockets/udp.c +151 -0
  47. package/cpp/uWebSockets/uWebSockets/App.h +676 -0
  48. package/cpp/uWebSockets/uWebSockets/AsyncSocket.h +376 -0
  49. package/cpp/uWebSockets/uWebSockets/AsyncSocketData.h +94 -0
  50. package/cpp/uWebSockets/uWebSockets/BloomFilter.h +83 -0
  51. package/cpp/uWebSockets/uWebSockets/CachingApp.h +115 -0
  52. package/cpp/uWebSockets/uWebSockets/ChunkedEncoding.h +237 -0
  53. package/cpp/uWebSockets/uWebSockets/ClientApp.h +36 -0
  54. package/cpp/uWebSockets/uWebSockets/Http3App.h +140 -0
  55. package/cpp/uWebSockets/uWebSockets/Http3Context.h +157 -0
  56. package/cpp/uWebSockets/uWebSockets/Http3ContextData.h +21 -0
  57. package/cpp/uWebSockets/uWebSockets/Http3Request.h +22 -0
  58. package/cpp/uWebSockets/uWebSockets/Http3Response.h +120 -0
  59. package/cpp/uWebSockets/uWebSockets/Http3ResponseData.h +25 -0
  60. package/cpp/uWebSockets/uWebSockets/HttpContext.h +521 -0
  61. package/cpp/uWebSockets/uWebSockets/HttpContextData.h +60 -0
  62. package/cpp/uWebSockets/uWebSockets/HttpErrors.h +53 -0
  63. package/cpp/uWebSockets/uWebSockets/HttpParser.h +747 -0
  64. package/cpp/uWebSockets/uWebSockets/HttpResponse.h +605 -0
  65. package/cpp/uWebSockets/uWebSockets/HttpResponseData.h +123 -0
  66. package/cpp/uWebSockets/uWebSockets/HttpRouter.h +384 -0
  67. package/cpp/uWebSockets/uWebSockets/LocalCluster.h +64 -0
  68. package/cpp/uWebSockets/uWebSockets/Loop.h +238 -0
  69. package/cpp/uWebSockets/uWebSockets/LoopData.h +113 -0
  70. package/cpp/uWebSockets/uWebSockets/MessageParser.h +64 -0
  71. package/cpp/uWebSockets/uWebSockets/MoveOnlyFunction.h +389 -0
  72. package/cpp/uWebSockets/uWebSockets/Multipart.h +231 -0
  73. package/cpp/uWebSockets/uWebSockets/PerMessageDeflate.h +303 -0
  74. package/cpp/uWebSockets/uWebSockets/ProxyParser.h +187 -0
  75. package/cpp/uWebSockets/uWebSockets/QueryParser.h +120 -0
  76. package/cpp/uWebSockets/uWebSockets/TopicTree.h +364 -0
  77. package/cpp/uWebSockets/uWebSockets/Utilities.h +66 -0
  78. package/cpp/uWebSockets/uWebSockets/WebSocket.h +407 -0
  79. package/cpp/uWebSockets/uWebSockets/WebSocketContext.h +436 -0
  80. package/cpp/uWebSockets/uWebSockets/WebSocketContextData.h +109 -0
  81. package/cpp/uWebSockets/uWebSockets/WebSocketData.h +86 -0
  82. package/cpp/uWebSockets/uWebSockets/WebSocketExtensions.h +256 -0
  83. package/cpp/uWebSockets/uWebSockets/WebSocketHandshake.h +145 -0
  84. package/cpp/uWebSockets/uWebSockets/WebSocketProtocol.h +525 -0
  85. package/lib/commonjs/_internal/native-modules/NativeReactNativeUws.js +12 -0
  86. package/lib/commonjs/_internal/native-modules/NativeReactNativeUws.js.map +1 -0
  87. package/lib/commonjs/index.js +28 -0
  88. package/lib/commonjs/index.js.map +1 -0
  89. package/lib/commonjs/modules/App.js +17 -0
  90. package/lib/commonjs/modules/App.js.map +1 -0
  91. package/lib/commonjs/modules/CompressOptions.js +103 -0
  92. package/lib/commonjs/modules/CompressOptions.js.map +1 -0
  93. package/lib/commonjs/modules/EnvironmentVariables.js +17 -0
  94. package/lib/commonjs/modules/EnvironmentVariables.js.map +1 -0
  95. package/lib/commonjs/modules/ListenOptions.js +12 -0
  96. package/lib/commonjs/modules/ListenOptions.js.map +1 -0
  97. package/lib/commonjs/modules/SSLApp.js +15 -0
  98. package/lib/commonjs/modules/SSLApp.js.map +1 -0
  99. package/lib/commonjs/modules/getParts.js +28 -0
  100. package/lib/commonjs/modules/getParts.js.map +1 -0
  101. package/lib/commonjs/modules/index.js +61 -0
  102. package/lib/commonjs/modules/index.js.map +1 -0
  103. package/lib/commonjs/modules/us_listen_socket_close.js +21 -0
  104. package/lib/commonjs/modules/us_listen_socket_close.js.map +1 -0
  105. package/lib/commonjs/modules/us_socket_local_port.js +22 -0
  106. package/lib/commonjs/modules/us_socket_local_port.js.map +1 -0
  107. package/lib/commonjs/package.json +1 -0
  108. package/lib/commonjs/types/AppDescriptor.js +2 -0
  109. package/lib/commonjs/types/AppDescriptor.js.map +1 -0
  110. package/lib/commonjs/types/AppOptions.js +2 -0
  111. package/lib/commonjs/types/AppOptions.js.map +1 -0
  112. package/lib/commonjs/types/HttpRequest.js +6 -0
  113. package/lib/commonjs/types/HttpRequest.js.map +1 -0
  114. package/lib/commonjs/types/HttpResponse.js +6 -0
  115. package/lib/commonjs/types/HttpResponse.js.map +1 -0
  116. package/lib/commonjs/types/HttpRouterOptions.js +2 -0
  117. package/lib/commonjs/types/HttpRouterOptions.js.map +1 -0
  118. package/lib/commonjs/types/MultipartField.js +2 -0
  119. package/lib/commonjs/types/MultipartField.js.map +1 -0
  120. package/lib/commonjs/types/RecognizedString.js +2 -0
  121. package/lib/commonjs/types/RecognizedString.js.map +1 -0
  122. package/lib/commonjs/types/TemplatedApp.js +6 -0
  123. package/lib/commonjs/types/TemplatedApp.js.map +1 -0
  124. package/lib/commonjs/types/WebSocket.js +6 -0
  125. package/lib/commonjs/types/WebSocket.js.map +1 -0
  126. package/lib/commonjs/types/WebSocketBehaviour.js +139 -0
  127. package/lib/commonjs/types/WebSocketBehaviour.js.map +1 -0
  128. package/lib/commonjs/types/index.js +2 -0
  129. package/lib/commonjs/types/index.js.map +1 -0
  130. package/lib/commonjs/types/us_listen_socket.js +2 -0
  131. package/lib/commonjs/types/us_listen_socket.js.map +1 -0
  132. package/lib/commonjs/types/us_socket.js +2 -0
  133. package/lib/commonjs/types/us_socket.js.map +1 -0
  134. package/lib/commonjs/types/us_socket_context_t.js +2 -0
  135. package/lib/commonjs/types/us_socket_context_t.js.map +1 -0
  136. package/lib/module/_internal/native-modules/NativeReactNativeUws.js +10 -0
  137. package/lib/module/_internal/native-modules/NativeReactNativeUws.js.map +1 -0
  138. package/lib/module/index.js +5 -0
  139. package/lib/module/index.js.map +1 -0
  140. package/lib/module/modules/App.js +12 -0
  141. package/lib/module/modules/App.js.map +1 -0
  142. package/lib/module/modules/CompressOptions.js +103 -0
  143. package/lib/module/modules/CompressOptions.js.map +1 -0
  144. package/lib/module/modules/EnvironmentVariables.js +13 -0
  145. package/lib/module/modules/EnvironmentVariables.js.map +1 -0
  146. package/lib/module/modules/ListenOptions.js +8 -0
  147. package/lib/module/modules/ListenOptions.js.map +1 -0
  148. package/lib/module/modules/SSLApp.js +15 -0
  149. package/lib/module/modules/SSLApp.js.map +1 -0
  150. package/lib/module/modules/getParts.js +23 -0
  151. package/lib/module/modules/getParts.js.map +1 -0
  152. package/lib/module/modules/index.js +11 -0
  153. package/lib/module/modules/index.js.map +1 -0
  154. package/lib/module/modules/us_listen_socket_close.js +17 -0
  155. package/lib/module/modules/us_listen_socket_close.js.map +1 -0
  156. package/lib/module/modules/us_socket_local_port.js +18 -0
  157. package/lib/module/modules/us_socket_local_port.js.map +1 -0
  158. package/lib/module/package.json +1 -0
  159. package/lib/module/types/AppDescriptor.js +2 -0
  160. package/lib/module/types/AppDescriptor.js.map +1 -0
  161. package/lib/module/types/AppOptions.js +2 -0
  162. package/lib/module/types/AppOptions.js.map +1 -0
  163. package/lib/module/types/HttpRequest.js +4 -0
  164. package/lib/module/types/HttpRequest.js.map +1 -0
  165. package/lib/module/types/HttpResponse.js +4 -0
  166. package/lib/module/types/HttpResponse.js.map +1 -0
  167. package/lib/module/types/HttpRouterOptions.js +2 -0
  168. package/lib/module/types/HttpRouterOptions.js.map +1 -0
  169. package/lib/module/types/MultipartField.js +2 -0
  170. package/lib/module/types/MultipartField.js.map +1 -0
  171. package/lib/module/types/RecognizedString.js +2 -0
  172. package/lib/module/types/RecognizedString.js.map +1 -0
  173. package/lib/module/types/TemplatedApp.js +4 -0
  174. package/lib/module/types/TemplatedApp.js.map +1 -0
  175. package/lib/module/types/WebSocket.js +4 -0
  176. package/lib/module/types/WebSocket.js.map +1 -0
  177. package/lib/module/types/WebSocketBehaviour.js +139 -0
  178. package/lib/module/types/WebSocketBehaviour.js.map +1 -0
  179. package/lib/module/types/index.js +2 -0
  180. package/lib/module/types/index.js.map +1 -0
  181. package/lib/module/types/us_listen_socket.js +2 -0
  182. package/lib/module/types/us_listen_socket.js.map +1 -0
  183. package/lib/module/types/us_socket.js +2 -0
  184. package/lib/module/types/us_socket.js.map +1 -0
  185. package/lib/module/types/us_socket_context_t.js +2 -0
  186. package/lib/module/types/us_socket_context_t.js.map +1 -0
  187. package/lib/typescript/commonjs/_internal/native-modules/NativeReactNativeUws.d.ts +22 -0
  188. package/lib/typescript/commonjs/_internal/native-modules/NativeReactNativeUws.d.ts.map +1 -0
  189. package/lib/typescript/commonjs/index.d.ts +3 -0
  190. package/lib/typescript/commonjs/index.d.ts.map +1 -0
  191. package/lib/typescript/commonjs/modules/App.d.ts +7 -0
  192. package/lib/typescript/commonjs/modules/App.d.ts.map +1 -0
  193. package/lib/typescript/commonjs/modules/CompressOptions.d.ts +1 -0
  194. package/lib/typescript/commonjs/modules/CompressOptions.d.ts.map +1 -0
  195. package/lib/typescript/commonjs/modules/EnvironmentVariables.d.ts +16 -0
  196. package/lib/typescript/commonjs/modules/EnvironmentVariables.d.ts.map +1 -0
  197. package/lib/typescript/commonjs/modules/ListenOptions.d.ts +5 -0
  198. package/lib/typescript/commonjs/modules/ListenOptions.d.ts.map +1 -0
  199. package/lib/typescript/commonjs/modules/SSLApp.d.ts +1 -0
  200. package/lib/typescript/commonjs/modules/SSLApp.d.ts.map +1 -0
  201. package/lib/typescript/commonjs/modules/getParts.d.ts +6 -0
  202. package/lib/typescript/commonjs/modules/getParts.d.ts.map +1 -0
  203. package/lib/typescript/commonjs/modules/index.d.ts +6 -0
  204. package/lib/typescript/commonjs/modules/index.d.ts.map +1 -0
  205. package/lib/typescript/commonjs/modules/us_listen_socket_close.d.ts +5 -0
  206. package/lib/typescript/commonjs/modules/us_listen_socket_close.d.ts.map +1 -0
  207. package/lib/typescript/commonjs/modules/us_socket_local_port.d.ts +5 -0
  208. package/lib/typescript/commonjs/modules/us_socket_local_port.d.ts.map +1 -0
  209. package/lib/typescript/commonjs/package.json +1 -0
  210. package/lib/typescript/commonjs/types/AppDescriptor.d.ts +8 -0
  211. package/lib/typescript/commonjs/types/AppDescriptor.d.ts.map +1 -0
  212. package/lib/typescript/commonjs/types/AppOptions.d.ts +17 -0
  213. package/lib/typescript/commonjs/types/AppOptions.d.ts.map +1 -0
  214. package/lib/typescript/commonjs/types/HttpRequest.d.ts +54 -0
  215. package/lib/typescript/commonjs/types/HttpRequest.d.ts.map +1 -0
  216. package/lib/typescript/commonjs/types/HttpResponse.d.ts +169 -0
  217. package/lib/typescript/commonjs/types/HttpResponse.d.ts.map +1 -0
  218. package/lib/typescript/commonjs/types/HttpRouterOptions.d.ts +24 -0
  219. package/lib/typescript/commonjs/types/HttpRouterOptions.d.ts.map +1 -0
  220. package/lib/typescript/commonjs/types/MultipartField.d.ts +7 -0
  221. package/lib/typescript/commonjs/types/MultipartField.d.ts.map +1 -0
  222. package/lib/typescript/commonjs/types/RecognizedString.d.ts +10 -0
  223. package/lib/typescript/commonjs/types/RecognizedString.d.ts.map +1 -0
  224. package/lib/typescript/commonjs/types/TemplatedApp.d.ts +108 -0
  225. package/lib/typescript/commonjs/types/TemplatedApp.d.ts.map +1 -0
  226. package/lib/typescript/commonjs/types/WebSocket.d.ts +96 -0
  227. package/lib/typescript/commonjs/types/WebSocket.d.ts.map +1 -0
  228. package/lib/typescript/commonjs/types/WebSocketBehaviour.d.ts +1 -0
  229. package/lib/typescript/commonjs/types/WebSocketBehaviour.d.ts.map +1 -0
  230. package/lib/typescript/commonjs/types/index.d.ts +6 -0
  231. package/lib/typescript/commonjs/types/index.d.ts.map +1 -0
  232. package/lib/typescript/commonjs/types/us_listen_socket.d.ts +7 -0
  233. package/lib/typescript/commonjs/types/us_listen_socket.d.ts.map +1 -0
  234. package/lib/typescript/commonjs/types/us_socket.d.ts +7 -0
  235. package/lib/typescript/commonjs/types/us_socket.d.ts.map +1 -0
  236. package/lib/typescript/commonjs/types/us_socket_context_t.d.ts +7 -0
  237. package/lib/typescript/commonjs/types/us_socket_context_t.d.ts.map +1 -0
  238. package/lib/typescript/module/_internal/native-modules/NativeReactNativeUws.d.ts +22 -0
  239. package/lib/typescript/module/_internal/native-modules/NativeReactNativeUws.d.ts.map +1 -0
  240. package/lib/typescript/module/index.d.ts +3 -0
  241. package/lib/typescript/module/index.d.ts.map +1 -0
  242. package/lib/typescript/module/modules/App.d.ts +7 -0
  243. package/lib/typescript/module/modules/App.d.ts.map +1 -0
  244. package/lib/typescript/module/modules/CompressOptions.d.ts +1 -0
  245. package/lib/typescript/module/modules/CompressOptions.d.ts.map +1 -0
  246. package/lib/typescript/module/modules/EnvironmentVariables.d.ts +16 -0
  247. package/lib/typescript/module/modules/EnvironmentVariables.d.ts.map +1 -0
  248. package/lib/typescript/module/modules/ListenOptions.d.ts +5 -0
  249. package/lib/typescript/module/modules/ListenOptions.d.ts.map +1 -0
  250. package/lib/typescript/module/modules/SSLApp.d.ts +1 -0
  251. package/lib/typescript/module/modules/SSLApp.d.ts.map +1 -0
  252. package/lib/typescript/module/modules/getParts.d.ts +6 -0
  253. package/lib/typescript/module/modules/getParts.d.ts.map +1 -0
  254. package/lib/typescript/module/modules/index.d.ts +6 -0
  255. package/lib/typescript/module/modules/index.d.ts.map +1 -0
  256. package/lib/typescript/module/modules/us_listen_socket_close.d.ts +5 -0
  257. package/lib/typescript/module/modules/us_listen_socket_close.d.ts.map +1 -0
  258. package/lib/typescript/module/modules/us_socket_local_port.d.ts +5 -0
  259. package/lib/typescript/module/modules/us_socket_local_port.d.ts.map +1 -0
  260. package/lib/typescript/module/package.json +1 -0
  261. package/lib/typescript/module/types/AppDescriptor.d.ts +8 -0
  262. package/lib/typescript/module/types/AppDescriptor.d.ts.map +1 -0
  263. package/lib/typescript/module/types/AppOptions.d.ts +17 -0
  264. package/lib/typescript/module/types/AppOptions.d.ts.map +1 -0
  265. package/lib/typescript/module/types/HttpRequest.d.ts +54 -0
  266. package/lib/typescript/module/types/HttpRequest.d.ts.map +1 -0
  267. package/lib/typescript/module/types/HttpResponse.d.ts +169 -0
  268. package/lib/typescript/module/types/HttpResponse.d.ts.map +1 -0
  269. package/lib/typescript/module/types/HttpRouterOptions.d.ts +24 -0
  270. package/lib/typescript/module/types/HttpRouterOptions.d.ts.map +1 -0
  271. package/lib/typescript/module/types/MultipartField.d.ts +7 -0
  272. package/lib/typescript/module/types/MultipartField.d.ts.map +1 -0
  273. package/lib/typescript/module/types/RecognizedString.d.ts +10 -0
  274. package/lib/typescript/module/types/RecognizedString.d.ts.map +1 -0
  275. package/lib/typescript/module/types/TemplatedApp.d.ts +108 -0
  276. package/lib/typescript/module/types/TemplatedApp.d.ts.map +1 -0
  277. package/lib/typescript/module/types/WebSocket.d.ts +96 -0
  278. package/lib/typescript/module/types/WebSocket.d.ts.map +1 -0
  279. package/lib/typescript/module/types/WebSocketBehaviour.d.ts +1 -0
  280. package/lib/typescript/module/types/WebSocketBehaviour.d.ts.map +1 -0
  281. package/lib/typescript/module/types/index.d.ts +6 -0
  282. package/lib/typescript/module/types/index.d.ts.map +1 -0
  283. package/lib/typescript/module/types/us_listen_socket.d.ts +7 -0
  284. package/lib/typescript/module/types/us_listen_socket.d.ts.map +1 -0
  285. package/lib/typescript/module/types/us_socket.d.ts +7 -0
  286. package/lib/typescript/module/types/us_socket.d.ts.map +1 -0
  287. package/lib/typescript/module/types/us_socket_context_t.d.ts +7 -0
  288. package/lib/typescript/module/types/us_socket_context_t.d.ts.map +1 -0
  289. package/lib/typescript/tsconfig.tsbuildinfo +1 -0
  290. package/package.json +62 -0
  291. package/src/_internal/native-modules/NativeUwsReactNative.ts +40 -0
  292. package/src/index.ts +2 -0
  293. package/src/modules/App.ts +14 -0
  294. package/src/modules/CompressOptions.ts +101 -0
  295. package/src/modules/EnvironmentVariables.ts +16 -0
  296. package/src/modules/ListenOptions.ts +4 -0
  297. package/src/modules/SSLApp.ts +13 -0
  298. package/src/modules/getParts.ts +29 -0
  299. package/src/modules/index.ts +8 -0
  300. package/src/modules/us_listen_socket_close.ts +15 -0
  301. package/src/modules/us_socket_local_port.ts +16 -0
  302. package/src/types/AppDescriptor.ts +7 -0
  303. package/src/types/AppOptions.ts +22 -0
  304. package/src/types/HttpRequest.ts +74 -0
  305. package/src/types/HttpResponse.ts +309 -0
  306. package/src/types/HttpRouterOptions.ts +24 -0
  307. package/src/types/MultipartField.ts +6 -0
  308. package/src/types/RecognizedString.ts +11 -0
  309. package/src/types/TemplatedApp.ts +285 -0
  310. package/src/types/WebSocket.ts +147 -0
  311. package/src/types/WebSocketBehaviour.ts +137 -0
  312. package/src/types/index.ts +12 -0
  313. package/src/types/us_listen_socket.ts +6 -0
  314. package/src/types/us_socket.ts +6 -0
  315. package/src/types/us_socket_context_t.ts +6 -0
@@ -0,0 +1,376 @@
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
+ #ifndef UWS_ASYNCSOCKET_H
19
+ #define UWS_ASYNCSOCKET_H
20
+
21
+ /* This class implements async socket memory management strategies */
22
+
23
+ /* NOTE: Many unsigned/signed conversion warnings could be solved by moving from int length
24
+ * to unsigned length for everything to/from uSockets - this would however remove the opportunity
25
+ * to signal error with -1 (which is how the entire UNIX syscalling is built). */
26
+
27
+ #include <cstring>
28
+ #include <iostream>
29
+
30
+ #include "libusockets.h"
31
+
32
+ #include "LoopData.h"
33
+ #include "AsyncSocketData.h"
34
+
35
+ namespace uWS {
36
+
37
+ enum SendBufferAttribute {
38
+ NEEDS_NOTHING,
39
+ NEEDS_DRAIN,
40
+ NEEDS_UNCORK
41
+ };
42
+
43
+ template <bool, bool, typename> struct WebSocketContext;
44
+
45
+ template <bool SSL>
46
+ struct AsyncSocket {
47
+ /* This guy is promiscuous */
48
+ template <bool> friend struct HttpContext;
49
+ template <bool, bool, typename> friend struct WebSocketContext;
50
+ template <bool> friend struct TemplatedApp;
51
+ template <bool, typename> friend struct WebSocketContextData;
52
+ template <typename, typename> friend struct TopicTree;
53
+ template <bool> friend struct HttpResponse;
54
+
55
+ private:
56
+ /* Helper, do not use directly (todo: move to uSockets or de-crazify) */
57
+ void throttle_helper(int toggle) {
58
+ /* These should be exposed by uSockets */
59
+ static thread_local int us_events[2] = {0, 0};
60
+
61
+ struct us_poll_t *p = (struct us_poll_t *) this;
62
+ struct us_loop_t *loop = us_socket_context_loop(SSL, us_socket_context(SSL, (us_socket_t *) this));
63
+
64
+ if (toggle) {
65
+ /* Pause */
66
+ int events = us_poll_events(p);
67
+ if (events) {
68
+ us_events[getBufferedAmount() ? 1 : 0] = events;
69
+ }
70
+ us_poll_change(p, loop, 0);
71
+ } else {
72
+ /* Resume */
73
+ int events = us_events[getBufferedAmount() ? 1 : 0];
74
+ us_poll_change(p, loop, events);
75
+ }
76
+ }
77
+
78
+ protected:
79
+ /* Returns SSL pointer or FD as pointer */
80
+ void *getNativeHandle() {
81
+ return us_socket_get_native_handle(SSL, (us_socket_t *) this);
82
+ }
83
+
84
+ /* Get loop data for socket */
85
+ LoopData *getLoopData() {
86
+ return (LoopData *) us_loop_ext(us_socket_context_loop(SSL, us_socket_context(SSL, (us_socket_t *) this)));
87
+ }
88
+
89
+ /* Get socket extension */
90
+ AsyncSocketData<SSL> *getAsyncSocketData() {
91
+ return (AsyncSocketData<SSL> *) us_socket_ext(SSL, (us_socket_t *) this);
92
+ }
93
+
94
+ /* Socket timeout */
95
+ void timeout(unsigned int seconds) {
96
+ us_socket_timeout(SSL, (us_socket_t *) this, seconds);
97
+ }
98
+
99
+ /* Shutdown socket without any automatic drainage */
100
+ void shutdown() {
101
+ us_socket_shutdown(SSL, (us_socket_t *) this);
102
+ }
103
+
104
+ /* Experimental pause */
105
+ us_socket_t *pause() {
106
+ throttle_helper(1);
107
+ return (us_socket_t *) this;
108
+ }
109
+
110
+ /* Experimental resume */
111
+ us_socket_t *resume() {
112
+ throttle_helper(0);
113
+ return (us_socket_t *) this;
114
+ }
115
+
116
+ /* Immediately close socket */
117
+ us_socket_t *close() {
118
+ return us_socket_close(SSL, (us_socket_t *) this, 0, nullptr);
119
+ }
120
+
121
+ void corkUnchecked() {
122
+ /* What if another socket is corked? */
123
+ getLoopData()->corkedSocket = this;
124
+ }
125
+
126
+ void uncorkWithoutSending() {
127
+ if (isCorked()) {
128
+ getLoopData()->corkedSocket = nullptr;
129
+ }
130
+ }
131
+
132
+ /* Cork this socket. Only one socket may ever be corked per-loop at any given time */
133
+ void cork() {
134
+ /* Extra check for invalid corking of others */
135
+ if (getLoopData()->corkOffset && getLoopData()->corkedSocket != this) {
136
+ std::cerr << "Error: Cork buffer must not be acquired without checking canCork!" << std::endl;
137
+ std::terminate();
138
+ }
139
+
140
+ /* What if another socket is corked? */
141
+ getLoopData()->corkedSocket = this;
142
+ }
143
+
144
+ /* Returns whether we are corked or not */
145
+ bool isCorked() {
146
+ return getLoopData()->corkedSocket == this;
147
+ }
148
+
149
+ /* Returns whether we could cork (it is free) */
150
+ bool canCork() {
151
+ return getLoopData()->corkedSocket == nullptr;
152
+ }
153
+
154
+ /* Returns a suitable buffer for temporary assemblation of send data */
155
+ std::pair<char *, SendBufferAttribute> getSendBuffer(size_t size) {
156
+ /* First step is to determine if we already have backpressure or not */
157
+ LoopData *loopData = getLoopData();
158
+ BackPressure &backPressure = getAsyncSocketData()->buffer;
159
+ size_t existingBackpressure = backPressure.length();
160
+ if ((!existingBackpressure) && (isCorked() || canCork()) && (loopData->corkOffset + size < LoopData::CORK_BUFFER_SIZE)) {
161
+ /* Cork automatically if we can */
162
+ if (isCorked()) {
163
+ char *sendBuffer = loopData->corkBuffer + loopData->corkOffset;
164
+ loopData->corkOffset += (unsigned int) size;
165
+ return {sendBuffer, SendBufferAttribute::NEEDS_NOTHING};
166
+ } else {
167
+ cork();
168
+ char *sendBuffer = loopData->corkBuffer + loopData->corkOffset;
169
+ loopData->corkOffset += (unsigned int) size;
170
+ return {sendBuffer, SendBufferAttribute::NEEDS_UNCORK};
171
+ }
172
+ } else {
173
+
174
+ /* If we are corked and there is already data in the cork buffer,
175
+ mark how much is ours and reset it */
176
+ unsigned int ourCorkOffset = 0;
177
+ if (isCorked() && loopData->corkOffset) {
178
+ ourCorkOffset = loopData->corkOffset;
179
+ loopData->corkOffset = 0;
180
+ }
181
+
182
+ /* Fallback is to use the backpressure as buffer */
183
+ backPressure.resize(ourCorkOffset + existingBackpressure + size);
184
+
185
+ /* And copy corkbuffer in front */
186
+ memcpy((char *) backPressure.data() + existingBackpressure, loopData->corkBuffer, ourCorkOffset);
187
+
188
+ return {(char *) backPressure.data() + ourCorkOffset + existingBackpressure, SendBufferAttribute::NEEDS_DRAIN};
189
+ }
190
+ }
191
+
192
+ /* Returns the user space backpressure. */
193
+ unsigned int getBufferedAmount() {
194
+ /* We return the actual amount of bytes in backbuffer, including pendingRemoval */
195
+ return (unsigned int) getAsyncSocketData()->buffer.totalLength();
196
+ }
197
+
198
+ /* Returns the text representation of an IPv4 or IPv6 address */
199
+ std::string_view addressAsText(std::string_view binary) {
200
+ static thread_local char buf[64];
201
+ int ipLength = 0;
202
+
203
+ if (!binary.length()) {
204
+ return {};
205
+ }
206
+
207
+ unsigned char *b = (unsigned char *) binary.data();
208
+
209
+ if (binary.length() == 4) {
210
+ ipLength = snprintf(buf, 64, "%u.%u.%u.%u", b[0], b[1], b[2], b[3]);
211
+ } else {
212
+ ipLength = snprintf(buf, 64, "%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x:%02x%02x",
213
+ b[0], b[1], b[2], b[3], b[4], b[5], b[6], b[7], b[8], b[9], b[10], b[11],
214
+ b[12], b[13], b[14], b[15]);
215
+ }
216
+
217
+ return {buf, (unsigned int) ipLength};
218
+ }
219
+
220
+ /* Returns the remote IP address or empty string on failure */
221
+ std::string_view getRemoteAddress() {
222
+ #ifdef UWS_REMOTE_ADDRESS_USERSPACE
223
+ AsyncSocketData<SSL> *data = getAsyncSocketData();
224
+ return std::string_view(data->remoteAddress, (unsigned int) data->remoteAddressLength);
225
+ #else
226
+ static thread_local char buf[16];
227
+ int ipLength = 16;
228
+ us_socket_remote_address(SSL, (us_socket_t *) this, buf, &ipLength);
229
+ return std::string_view(buf, (unsigned int) ipLength);
230
+ #endif
231
+ }
232
+
233
+ /* Returns the text representation of IP */
234
+ std::string_view getRemoteAddressAsText() {
235
+ return addressAsText(getRemoteAddress());
236
+ }
237
+
238
+ /* Returns the remote port number or -1 on failure */
239
+ unsigned int getRemotePort() {
240
+ int port = us_socket_remote_port(SSL, (us_socket_t *) this);
241
+ return (unsigned int) port;
242
+ }
243
+
244
+ /* Write in three levels of prioritization: cork-buffer, syscall, socket-buffer. Always drain if possible.
245
+ * Returns pair of bytes written (anywhere) and whether or not this call resulted in the polling for
246
+ * writable (or we are in a state that implies polling for writable). */
247
+ std::pair<int, bool> write(const char *src, int length, bool optionally = false, int nextLength = 0) {
248
+ /* Fake success if closed, simple fix to allow uncork of closed socket to succeed */
249
+ if (us_socket_is_closed(SSL, (us_socket_t *) this)) {
250
+ return {length, false};
251
+ }
252
+
253
+ LoopData *loopData = getLoopData();
254
+ AsyncSocketData<SSL> *asyncSocketData = getAsyncSocketData();
255
+
256
+ /* We are limited if we have a per-socket buffer */
257
+ if (asyncSocketData->buffer.length()) {
258
+ /* Write off as much as we can */
259
+ int written = us_socket_write(SSL, (us_socket_t *) this, asyncSocketData->buffer.data(), (int) asyncSocketData->buffer.length(), /*nextLength != 0 | */length);
260
+
261
+ /* On failure return, otherwise continue down the function */
262
+ if ((unsigned int) written < asyncSocketData->buffer.length()) {
263
+
264
+ /* Update buffering (todo: we can do better here if we keep track of what happens to this guy later on) */
265
+ asyncSocketData->buffer.erase((unsigned int) written);
266
+
267
+ if (optionally) {
268
+ /* Thankfully we can exit early here */
269
+ return {0, true};
270
+ } else {
271
+ /* This path is horrible and points towards erroneous usage */
272
+ asyncSocketData->buffer.append(src, (unsigned int) length);
273
+
274
+ return {length, true};
275
+ }
276
+ }
277
+
278
+ /* At this point we simply have no buffer and can continue as normal */
279
+ asyncSocketData->buffer.clear();
280
+ }
281
+
282
+ if (length) {
283
+ if (loopData->corkedSocket == this) {
284
+ /* We are corked */
285
+ if (LoopData::CORK_BUFFER_SIZE - loopData->corkOffset >= (unsigned int) length) {
286
+ /* If the entire chunk fits in cork buffer */
287
+ memcpy(loopData->corkBuffer + loopData->corkOffset, src, (unsigned int) length);
288
+ loopData->corkOffset += (unsigned int) length;
289
+ /* Fall through to default return */
290
+ } else {
291
+ /* Strategy differences between SSL and non-SSL regarding syscall minimizing */
292
+ if constexpr (false) {
293
+ /* Cork up as much as we can */
294
+ unsigned int stripped = LoopData::CORK_BUFFER_SIZE - loopData->corkOffset;
295
+ memcpy(loopData->corkBuffer + loopData->corkOffset, src, stripped);
296
+ loopData->corkOffset = LoopData::CORK_BUFFER_SIZE;
297
+
298
+ auto [written, failed] = uncork(src + stripped, length - (int) stripped, optionally);
299
+ return {written + (int) stripped, failed};
300
+ }
301
+
302
+ /* For non-SSL we take the penalty of two syscalls */
303
+ return uncork(src, length, optionally);
304
+ }
305
+ } else {
306
+ /* We are not corked */
307
+ int written = us_socket_write(SSL, (us_socket_t *) this, src, length, nextLength != 0);
308
+
309
+ /* Did we fail? */
310
+ if (written < length) {
311
+ /* If the write was optional then just bail out */
312
+ if (optionally) {
313
+ return {written, true};
314
+ }
315
+
316
+ /* Fall back to worst possible case (should be very rare for HTTP) */
317
+ /* At least we can reserve room for next chunk if we know it up front */
318
+ if (nextLength) {
319
+ asyncSocketData->buffer.reserve(asyncSocketData->buffer.length() + (size_t) (length - written + nextLength));
320
+ }
321
+
322
+ /* Buffer this chunk */
323
+ asyncSocketData->buffer.append(src + written, (size_t) (length - written));
324
+
325
+ /* Return the failure */
326
+ return {length, true};
327
+ }
328
+ /* Fall through to default return */
329
+ }
330
+ }
331
+
332
+ /* Default fall through return */
333
+ return {length, false};
334
+ }
335
+
336
+ /* Uncork this socket and flush or buffer any corked and/or passed data. It is essential to remember doing this. */
337
+ /* It does NOT count bytes written from cork buffer (they are already accounted for in the write call responsible for its corking)! */
338
+ std::pair<int, bool> uncork(const char *src = nullptr, int length = 0, bool optionally = false) {
339
+ LoopData *loopData = getLoopData();
340
+
341
+ if (loopData->corkedSocket == this) {
342
+ loopData->corkedSocket = nullptr;
343
+
344
+ if (loopData->corkOffset) {
345
+ /* Corked data is already accounted for via its write call */
346
+ auto [written, failed] = write(loopData->corkBuffer, (int) loopData->corkOffset, false, length);
347
+ loopData->corkOffset = 0;
348
+
349
+ if (failed) {
350
+ /* If corked data fails to flush, and we have more data to write, immediately buffer it here
351
+ * since the above call to write excludes src */
352
+ if (!optionally && src && length) {
353
+ AsyncSocketData<SSL> *asyncSocketData = getAsyncSocketData();
354
+ asyncSocketData->buffer.append(src, (size_t) length);
355
+
356
+ /* We wrote to per socket buffer, so report success */
357
+ return {length, true};
358
+ }
359
+
360
+ /* We do not need to care for buffering (of the corked data) here, write did that */
361
+ return {0, true};
362
+ }
363
+ }
364
+
365
+ /* We should only return with new writes, not things written to cork already */
366
+ return write(src, length, optionally, 0);
367
+ } else {
368
+ /* We are not even corked! */
369
+ return {0, false};
370
+ }
371
+ }
372
+ };
373
+
374
+ }
375
+
376
+ #endif // UWS_ASYNCSOCKET_H
@@ -0,0 +1,94 @@
1
+ /*
2
+ * Authored by Alex Hultman, 2018-2025.
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
+ #ifndef UWS_ASYNCSOCKETDATA_H
19
+ #define UWS_ASYNCSOCKETDATA_H
20
+
21
+ #include <string>
22
+
23
+ namespace uWS {
24
+
25
+ struct BackPressure {
26
+ std::string buffer;
27
+ unsigned int pendingRemoval = 0;
28
+ BackPressure(BackPressure &&other) {
29
+ buffer = std::move(other.buffer);
30
+ pendingRemoval = other.pendingRemoval;
31
+ }
32
+ BackPressure() = default;
33
+ void append(const char *data, size_t length) {
34
+ buffer.append(data, length);
35
+ }
36
+ void erase(unsigned int length) {
37
+ pendingRemoval += length;
38
+ /* Always erase a minimum of 1/32th the current backpressure */
39
+ if (pendingRemoval > (buffer.length() >> 5)) {
40
+ std::string(buffer.begin() + pendingRemoval, buffer.end()).swap(buffer);
41
+ pendingRemoval = 0;
42
+ }
43
+ }
44
+ size_t length() {
45
+ return buffer.length() - pendingRemoval;
46
+ }
47
+ /* Only used in AsyncSocket::write - what about replacing it with the other functions like erase(length())? */
48
+ void clear() {
49
+ pendingRemoval = 0;
50
+ buffer.clear();
51
+ buffer.shrink_to_fit();
52
+ }
53
+ /* Only used by AsyncSocket::write (optionally) before append */
54
+ void reserve(size_t length) {
55
+ buffer.reserve(length + pendingRemoval);
56
+ }
57
+ /* Only used by getSendBuffer as last resort */
58
+ void resize(size_t length) {
59
+ buffer.resize(length + pendingRemoval);
60
+ }
61
+ const char *data() {
62
+ return buffer.data() + pendingRemoval;
63
+ }
64
+ /* The total length, incuding pending removal */
65
+ size_t totalLength() {
66
+ return buffer.length();
67
+ }
68
+ };
69
+
70
+ /* Depending on how we want AsyncSocket to function, this will need to change */
71
+
72
+ template <bool SSL>
73
+ struct AsyncSocketData {
74
+ /* This will do for now */
75
+ BackPressure buffer;
76
+
77
+ #ifdef UWS_REMOTE_ADDRESS_USERSPACE
78
+ /* Cache for remote address, populated on socket open */
79
+ char remoteAddress[16];
80
+ int remoteAddressLength = 0;
81
+ #endif
82
+
83
+ /* Allow move constructing us */
84
+ AsyncSocketData(BackPressure &&backpressure) : buffer(std::move(backpressure)) {
85
+
86
+ }
87
+
88
+ /* Or emppty */
89
+ AsyncSocketData() = default;
90
+ };
91
+
92
+ }
93
+
94
+ #endif // UWS_ASYNCSOCKETDATA_H
@@ -0,0 +1,83 @@
1
+ /*
2
+ * Authored by Alex Hultman, 2018-2022.
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
+ #ifndef UWS_BLOOMFILTER_H
19
+ #define UWS_BLOOMFILTER_H
20
+
21
+ /* This filter has no false positives or collisions for the standard
22
+ * and non-standard common request headers */
23
+
24
+ #include <cstdint>
25
+ #include <string_view>
26
+ #include <bitset>
27
+
28
+ namespace uWS {
29
+
30
+ struct BloomFilter {
31
+ private:
32
+ std::bitset<256> filter;
33
+ static inline uint32_t perfectHash(uint32_t features) {
34
+ return features * 1843993368;
35
+ }
36
+
37
+ union ScrambleArea {
38
+ unsigned char p[4];
39
+ uint32_t val;
40
+ };
41
+
42
+ ScrambleArea getFeatures(std::string_view key) {
43
+ ScrambleArea s;
44
+ s.p[0] = reinterpret_cast<const unsigned char&>(key[0]);
45
+ s.p[1] = reinterpret_cast<const unsigned char&>(key[key.length() - 1]);
46
+ s.p[2] = reinterpret_cast<const unsigned char&>(key[key.length() - 2]);
47
+ s.p[3] = reinterpret_cast<const unsigned char&>(key[key.length() >> 1]);
48
+ return s;
49
+ }
50
+
51
+ public:
52
+ bool mightHave(std::string_view key) {
53
+ if (key.length() < 2) {
54
+ return true;
55
+ }
56
+
57
+ ScrambleArea s = getFeatures(key);
58
+ s.val = perfectHash(s.val);
59
+ return filter[s.p[0]] &&
60
+ filter[s.p[1]] &&
61
+ filter[s.p[2]] &&
62
+ filter[s.p[3]];
63
+ }
64
+
65
+ void add(std::string_view key) {
66
+ if (key.length() >= 2) {
67
+ ScrambleArea s = getFeatures(key);
68
+ s.val = perfectHash(s.val);
69
+ filter[s.p[0]] = 1;
70
+ filter[s.p[1]] = 1;
71
+ filter[s.p[2]] = 1;
72
+ filter[s.p[3]] = 1;
73
+ }
74
+ }
75
+
76
+ void reset() {
77
+ filter.reset();
78
+ }
79
+ };
80
+
81
+ }
82
+
83
+ #endif // UWS_BLOOMFILTER_H
@@ -0,0 +1,115 @@
1
+ #ifndef UWS_CACHINGAPP_H
2
+ #define UWS_CACHINGAPP_H
3
+
4
+ #include "App.h"
5
+ #include <unordered_map>
6
+ #include <string>
7
+ #include <functional>
8
+ #include <string_view>
9
+
10
+ namespace uWS {
11
+
12
+ struct StringViewHash {
13
+ size_t operator()(std::string_view sv) const {
14
+ return std::hash<std::string_view>{}(sv);
15
+ }
16
+ };
17
+
18
+ struct StringViewEqual {
19
+ bool operator()(std::string_view sv1, std::string_view sv2) const {
20
+ return sv1 == sv2;
21
+ }
22
+ };
23
+
24
+
25
+
26
+ class CachingHttpResponse {
27
+ public:
28
+ CachingHttpResponse(uWS::HttpResponse<false> *res)
29
+ : res(res) {}
30
+
31
+ void write(std::string_view data) {
32
+ buffer.append(data);
33
+ }
34
+
35
+ void end(std::string_view data = "", bool closeConnection = false) {
36
+ buffer.append(data);
37
+
38
+ // end for all queued up sockets also
39
+ res->end(buffer);
40
+
41
+ created = time(0);
42
+
43
+ std::ignore = closeConnection;
44
+ }
45
+
46
+ public:
47
+ uWS::HttpResponse<false>* res; // should be a vector of waiting sockets
48
+
49
+
50
+ std::string buffer; // body
51
+ time_t created;
52
+ };
53
+
54
+ typedef std::unordered_map<std::string_view, CachingHttpResponse *,
55
+ StringViewHash,
56
+ StringViewEqual> CacheType;
57
+
58
+ // we can also derive from H3app later on
59
+ template <bool SSL>
60
+ struct CachingApp : public uWS::TemplatedAppBase<SSL, CachingApp<SSL>> {
61
+ public:
62
+ CachingApp(SocketContextOptions options = {}) : uWS::TemplatedAppBase<SSL, CachingApp<SSL>>(options) {}
63
+
64
+ using uWS::TemplatedAppBase<SSL, CachingApp<SSL>>::get;
65
+
66
+ CachingApp(const CachingApp &other) = delete;
67
+ CachingApp(CachingApp<SSL> &&other) : uWS::TemplatedAppBase<SSL, CachingApp<SSL>>(std::move(other)) {
68
+ // also move the cache
69
+ }
70
+
71
+ ~CachingApp() {
72
+
73
+ }
74
+
75
+ // variant 1: only taking URL into account
76
+ CachingApp &&get(const std::string& url, uWS::MoveOnlyFunction<void(CachingHttpResponse*, uWS::HttpRequest*)> &&handler, unsigned int secondsToExpiry) {
77
+ ((uWS::TemplatedAppBase<SSL, CachingApp<SSL>> *)this)->get(url, [this, handler = std::move(handler), secondsToExpiry](auto* res, auto* req) mutable {
78
+ /* We need to know the cache key and the time of now */
79
+ std::string_view cache_key = req->getFullUrl();
80
+ time_t now = static_cast<LoopData *>(us_loop_ext((us_loop_t *)uWS::Loop::get()))->cacheTimepoint;
81
+
82
+ auto it = cache.find(cache_key);
83
+ if (it != cache.end()) {
84
+
85
+ if (it->second->created + secondsToExpiry > now) {
86
+ res->end(it->second->buffer); // tryEnd!
87
+ return;
88
+ }
89
+
90
+ /* We are no longer valid, delete old cache and fall through to create a new entry */
91
+ delete it->second;
92
+
93
+ // is the cache completed? if not, add yourself to the waiting list of sockets to that cache
94
+
95
+ // if the cache completed? ok, is it still valid? use it
96
+ }
97
+
98
+ // immediately take the place in the cache
99
+ CachingHttpResponse *cachingRes;
100
+ cache[cache_key] = (cachingRes = new CachingHttpResponse(res));
101
+
102
+ handler(cachingRes, req);
103
+ });
104
+ return std::move(*this);
105
+ }
106
+
107
+ // variant 2: taking URL and a list of headers into account
108
+ // todo
109
+
110
+ private:
111
+ CacheType cache;
112
+ };
113
+
114
+ }
115
+ #endif