@fails-components/webtransport 0.1.0-macarmbuild.6 → 0.1.2
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/CMakeLists.txt +19 -39
- package/dist/lib/server.d.ts +16 -3
- package/dist/lib/server.d.ts.map +1 -1
- package/dist/lib/session.d.ts +4 -0
- package/dist/lib/session.d.ts.map +1 -1
- package/dist/lib/types.d.ts +7 -0
- package/dist/lib/types.d.ts.map +1 -1
- package/lib/server.js +42 -3
- package/lib/session.js +3 -0
- package/lib/types.ts +8 -0
- package/package.json +1 -1
- package/platform/icufix/fakedata.cpp +8 -0
- package/src/http3eventloop.cc +124 -32
- package/src/http3eventloop.h +30 -17
- package/src/http3server.cc +111 -0
- package/src/http3server.h +14 -6
- package/src/http3serverbackend.cc +31 -18
- package/src/http3serverbackend.h +38 -3
- package/src/http3serverstream.cc +19 -6
- package/src/http3serverstream.h +2 -0
- package/src/http3wtstreamvisitor.cc +3 -0
- package/src/http3wtstreamvisitor.h +3 -1
- package/test/unidirectional-streams.spec.js +52 -0
package/CMakeLists.txt
CHANGED
|
@@ -19,25 +19,6 @@ set(BUILD_TESTING OFF)
|
|
|
19
19
|
set(protobuf_BUILD_PROTOC_BINARIES ON)
|
|
20
20
|
|
|
21
21
|
|
|
22
|
-
IF( NOT WIN32)
|
|
23
|
-
IF(APPLE)
|
|
24
|
-
IF(DEFINED ENV{LOCALHOMEWBREWICU})
|
|
25
|
-
MESSAGE(STATUS "Local homebrew icu detected")
|
|
26
|
-
MESSAGE(STATUS $ENV{LOCALHOMEWBREWICU})
|
|
27
|
-
SET(ICU_ROOT $ENV{LOCALHOMEWBREWICU})
|
|
28
|
-
ELSE()
|
|
29
|
-
IF(CMAKE_OSX_ARCHITECTURES MATCHES "x86_64")
|
|
30
|
-
MESSAGE(STATUS "set icu root local")
|
|
31
|
-
SET(ICU_ROOT "/usr/local/opt/icu4c")
|
|
32
|
-
ELSE()
|
|
33
|
-
MESSAGE(STATUS "set icu root homebrew")
|
|
34
|
-
SET(ICU_ROOT "/opt/homebrew/icu4c")
|
|
35
|
-
ENDIF()
|
|
36
|
-
ENDIF()
|
|
37
|
-
set(CMAKE_FIND_LIBRARY_SUFFIXES ".a")
|
|
38
|
-
ENDIF(APPLE)
|
|
39
|
-
find_package(ICU COMPONENTS uc i18n REQUIRED)
|
|
40
|
-
ENDIF(NOT WIN32)
|
|
41
22
|
|
|
42
23
|
IF (WIN32)
|
|
43
24
|
add_compile_definitions(NOMINMAX)
|
|
@@ -93,8 +74,6 @@ endif(COMMAND cmake_policy)
|
|
|
93
74
|
add_compile_definitions(QUICHE_ENABLE_LIBEVENT)
|
|
94
75
|
|
|
95
76
|
|
|
96
|
-
IF (WIN32)
|
|
97
|
-
|
|
98
77
|
add_library(icu STATIC
|
|
99
78
|
#icu
|
|
100
79
|
third_party/icu/icu4c/source/common/appendable.cpp
|
|
@@ -160,10 +139,11 @@ add_library(icu STATIC
|
|
|
160
139
|
third_party/icu/icu4c/source/common/utypes.cpp
|
|
161
140
|
third_party/icu/icu4c/source/common/uvector.cpp
|
|
162
141
|
third_party/icu/icu4c/source/common/putil.cpp
|
|
163
|
-
|
|
164
|
-
|
|
142
|
+
)
|
|
143
|
+
target_include_directories(icu
|
|
165
144
|
PUBLIC third_party/icu/icu4c/source/common
|
|
166
|
-
|
|
145
|
+
)
|
|
146
|
+
if (WIN32)
|
|
167
147
|
target_sources(icu PRIVATE
|
|
168
148
|
third_party/icu/icu4c/source/common/wintz.cpp
|
|
169
149
|
)
|
|
@@ -171,14 +151,18 @@ add_library(icu STATIC
|
|
|
171
151
|
#hack since this function is not currently used
|
|
172
152
|
ICU_DATA_DIR_WINDOWS=""
|
|
173
153
|
)
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
PRIVATE
|
|
177
|
-
|
|
178
|
-
U_COMMON_IMPLEMENTATION
|
|
154
|
+
else()
|
|
155
|
+
# fix data problem
|
|
156
|
+
target_sources(icu PRIVATE
|
|
157
|
+
platform/icufix/fakedata.cpp
|
|
179
158
|
)
|
|
159
|
+
endif()
|
|
180
160
|
|
|
181
|
-
|
|
161
|
+
target_compile_definitions(icu
|
|
162
|
+
PRIVATE U_DEFINE_FALSE_AND_TRUE=1
|
|
163
|
+
U_STATIC_IMPLEMENTATION
|
|
164
|
+
U_COMMON_IMPLEMENTATION
|
|
165
|
+
)
|
|
182
166
|
|
|
183
167
|
add_library(gquiche STATIC
|
|
184
168
|
#plattform impl
|
|
@@ -989,12 +973,8 @@ PUBLIC ${CMAKE_CURRENT_BINARY_DIR}
|
|
|
989
973
|
PUBLIC ${CMAKE_JS_INC}
|
|
990
974
|
)
|
|
991
975
|
|
|
992
|
-
|
|
993
|
-
|
|
994
|
-
ELSE(WIN32)
|
|
995
|
-
include_directories(gquiche PUBLIC ${ICU_INCLUDE_DIRS})
|
|
996
|
-
target_link_libraries(gquiche ICU::uc ICU::i18n)
|
|
997
|
-
ENDIF(WIN32)
|
|
976
|
+
|
|
977
|
+
target_include_directories(gquiche PUBLIC third_party/icu/icu4c/source/common)
|
|
998
978
|
|
|
999
979
|
target_link_libraries(gquiche
|
|
1000
980
|
absl::base
|
|
@@ -1023,9 +1003,9 @@ if(MSVC AND CMAKE_JS_NODELIB_DEF AND CMAKE_JS_NODELIB_TARGET)
|
|
|
1023
1003
|
execute_process(COMMAND ${CMAKE_AR} /def:${CMAKE_JS_NODELIB_DEF} /out:${CMAKE_JS_NODELIB_TARGET} ${CMAKE_STATIC_LINKER_FLAGS})
|
|
1024
1004
|
endif()
|
|
1025
1005
|
|
|
1026
|
-
|
|
1027
|
-
|
|
1028
|
-
|
|
1006
|
+
|
|
1007
|
+
target_link_libraries(gquiche icu)
|
|
1008
|
+
|
|
1029
1009
|
|
|
1030
1010
|
if(APPLE)
|
|
1031
1011
|
target_compile_definitions (gquiche PRIVATE __APPLE_USE_RFC_3542)
|
package/dist/lib/server.d.ts
CHANGED
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* @typedef {import('./types').Http3ServerEventHandler} Http3ServerEventHandler
|
|
6
6
|
* @typedef {import('./types').Http3WTServerSessionVisitorEvent} Http3WTServerSessionVisitorEvent
|
|
7
7
|
* @typedef {import('./types').ServerStatusEvent} ServerStatusEvent
|
|
8
|
+
* @typedef {import('./types').ServerSessionRequestEvent} ServerSessionRequestEvent
|
|
8
9
|
* @typedef {import('./types').Http3ServerInit} Http3ServerInit
|
|
9
10
|
*/
|
|
10
11
|
/**
|
|
@@ -22,6 +23,8 @@ export class Http3Server extends Http3WebTransport implements Http3ServerEventHa
|
|
|
22
23
|
sessionController: Record<string, ReadableStreamController<any>>;
|
|
23
24
|
port: number | null;
|
|
24
25
|
host: string | null;
|
|
26
|
+
/** @type {any} */
|
|
27
|
+
requestHandler: any;
|
|
25
28
|
_ready: import("./types").Deferred<unknown>;
|
|
26
29
|
ready: Promise<unknown>;
|
|
27
30
|
_closed: import("./types").Deferred<unknown>;
|
|
@@ -37,11 +40,20 @@ export class Http3Server extends Http3WebTransport implements Http3ServerEventHa
|
|
|
37
40
|
host: string;
|
|
38
41
|
family: 'IPv4' | 'IPv6';
|
|
39
42
|
} | null;
|
|
43
|
+
/**
|
|
44
|
+
* @param {any} callback
|
|
45
|
+
*/
|
|
46
|
+
setRequestCallback(callback: any): void;
|
|
40
47
|
/**
|
|
41
48
|
* @param {string} path
|
|
49
|
+
* @param {any | undefined} [args=undefined]
|
|
42
50
|
* @returns {ReadableStream<WebTransportSession>}
|
|
43
51
|
*/
|
|
44
|
-
sessionStream(path: string): ReadableStream<WebTransportSession>;
|
|
52
|
+
sessionStream(path: string, args?: any | undefined): ReadableStream<WebTransportSession>;
|
|
53
|
+
/**
|
|
54
|
+
* @param {ServerSessionRequestEvent} args
|
|
55
|
+
*/
|
|
56
|
+
onSessionRequest(args: ServerSessionRequestEvent): void;
|
|
45
57
|
/**
|
|
46
58
|
* @param {Http3WTServerSessionVisitorEvent} args
|
|
47
59
|
*/
|
|
@@ -60,15 +72,16 @@ export class Http3Server extends Http3WebTransport implements Http3ServerEventHa
|
|
|
60
72
|
*/
|
|
61
73
|
onServerStatus(evt: ServerStatusEvent): void;
|
|
62
74
|
/**
|
|
63
|
-
* @param {Http3WTServerSessionVisitorEvent | ServerStatusEvent} args
|
|
75
|
+
* @param {Http3WTServerSessionVisitorEvent | ServerStatusEvent | ServerSessionRequestEvent} args
|
|
64
76
|
*/
|
|
65
|
-
customCallback(args: Http3WTServerSessionVisitorEvent | ServerStatusEvent): void;
|
|
77
|
+
customCallback(args: Http3WTServerSessionVisitorEvent | ServerStatusEvent | ServerSessionRequestEvent): void;
|
|
66
78
|
}
|
|
67
79
|
export type WebTransportSession = import('./types').WebTransportSession;
|
|
68
80
|
export type NativeHttp3WTSession = import('./types').NativeHttp3WTSession;
|
|
69
81
|
export type Http3ServerEventHandler = import('./types').Http3ServerEventHandler;
|
|
70
82
|
export type Http3WTServerSessionVisitorEvent = import('./types').Http3WTServerSessionVisitorEvent;
|
|
71
83
|
export type ServerStatusEvent = import('./types').ServerStatusEvent;
|
|
84
|
+
export type ServerSessionRequestEvent = import('./types').ServerSessionRequestEvent;
|
|
72
85
|
export type Http3ServerInit = import('./types').Http3ServerInit;
|
|
73
86
|
import { Http3WebTransport } from "./transport.js";
|
|
74
87
|
import { ReadableStream } from "stream/web";
|
package/dist/lib/server.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../lib/server.js"],"names":[],"mappings":";AAOA
|
|
1
|
+
{"version":3,"file":"server.d.ts","sourceRoot":"","sources":["../../lib/server.js"],"names":[],"mappings":";AAOA;;;;;;;;GAQG;AAEH;;GAEG;AACH;IACE;;;OAGG;IACH,kBAFW,eAAe,EAuBzB;IAlBC,6CAA6C;IAC7C,gBADW,OAAO,MAAM,EAAE,cAAc,CAAC,CACjB;IAExB,4DAA4D;IAC5D,mBADW,OAAO,MAAM,EAAE,yBAAyB,GAAG,CAAC,CAAC,CAC7B;IAE3B,oBAAgB;IAChB,oBAAgB;IAGhB,kBAAkB;IAClB,gBADW,GAAG,CACY;IAE1B,4CAAqB;IACrB,wBAAgC;IAEhC,6CAAsB;IACtB,yBAAkC;IAGpC,oBAEC;IAED,mBAOC;IADC,6BAAmB;IAGrB;;OAEG;IACH,WAFa;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAAA;KAAE,GAAG,IAAI,CAa1E;IAED;;OAEG;IACH,6BAFW,GAAG,QAMb;IAED;;;;OAIG;IACH,oBAJW,MAAM,SACN,GAAG,GAAG,SAAS,GACb,eAAe,mBAAmB,CAAC,CAa/C;IAED;;OAEG;IACH,uBAFW,yBAAyB,QAiBnC;IAED;;OAEG;IACH,8BAFW,gCAAgC,QAa1C;IAED;OACG;IACH,sBAEC;IAED;OACG;IACH,0BAEC;IAED;OACG;IACH,sBAEC;IAED;;OAEG;IACH,oBAFW,iBAAiB,QAoB3B;IAED;;OAEG;IACH,qBAFW,gCAAgC,GAAG,iBAAiB,GAAG,yBAAyB,QAoB1F;CACF;kCAnMY,OAAO,SAAS,EAAE,mBAAmB;mCACrC,OAAO,SAAS,EAAE,oBAAoB;sCACtC,OAAO,SAAS,EAAE,uBAAuB;+CACzC,OAAO,SAAS,EAAE,gCAAgC;gCAClD,OAAO,SAAS,EAAE,iBAAiB;wCACnC,OAAO,SAAS,EAAE,yBAAyB;8BAC3C,OAAO,SAAS,EAAE,eAAe"}
|
package/dist/lib/session.d.ts
CHANGED
|
@@ -36,10 +36,12 @@ export class Http3WTSession implements WebTransportSessionEventHandler, WebTrans
|
|
|
36
36
|
* @param {object} args
|
|
37
37
|
* @param {import('./types').NativeHttp3WTSession} [args.object]
|
|
38
38
|
* @param {Http3Server | Http3Client} args.parentobj
|
|
39
|
+
* @param {any | undefined} [args.header= undefined]
|
|
39
40
|
*/
|
|
40
41
|
constructor(args: {
|
|
41
42
|
object?: import("./types").NativeHttp3WTSession | undefined;
|
|
42
43
|
parentobj: Http3Server | Http3Client;
|
|
44
|
+
header?: any | undefined;
|
|
43
45
|
});
|
|
44
46
|
objint: import("./types").NativeHttp3WTSession | undefined;
|
|
45
47
|
parentobj: import("./server").Http3Server | import("./client").Http3Client;
|
|
@@ -49,6 +51,8 @@ export class Http3WTSession implements WebTransportSessionEventHandler, WebTrans
|
|
|
49
51
|
readyResolve: ((value?: any) => void) | null | undefined;
|
|
50
52
|
/** @type {(() => void) | null | undefined} */
|
|
51
53
|
closeHook: (() => void) | null | undefined;
|
|
54
|
+
/** @type {(any | null | undefined)} */
|
|
55
|
+
header: (any | null | undefined);
|
|
52
56
|
/** @type {Promise<void>} */
|
|
53
57
|
ready: Promise<void>;
|
|
54
58
|
readyReject: (reason?: any) => void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../lib/session.js"],"names":[],"mappings":";AAGA;;;;;;;;;;;;;;;;;;;;;;;GAuBG;AAEH;;;GAGG;AACH;
|
|
1
|
+
{"version":3,"file":"session.d.ts","sourceRoot":"","sources":["../../lib/session.js"],"names":[],"mappings":"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"}
|
package/dist/lib/types.d.ts
CHANGED
|
@@ -112,6 +112,13 @@ export interface Http3ClientEventHandler {
|
|
|
112
112
|
export interface Http3WTServerSessionVisitorEvent extends Http3WTSessionVisitorEvent {
|
|
113
113
|
path: string;
|
|
114
114
|
object: any;
|
|
115
|
+
header?: any;
|
|
116
|
+
}
|
|
117
|
+
export interface ServerSessionRequestEvent {
|
|
118
|
+
purpose: 'SessionRequest';
|
|
119
|
+
header: Object;
|
|
120
|
+
promise: any;
|
|
121
|
+
session: any;
|
|
115
122
|
}
|
|
116
123
|
/**
|
|
117
124
|
* The Http3 server is listening on the specified port
|
package/dist/lib/types.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../lib/types.ts"],"names":[],"mappings":"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"}
|
package/lib/server.js
CHANGED
|
@@ -11,6 +11,7 @@ import { defer } from './utils.js'
|
|
|
11
11
|
* @typedef {import('./types').Http3ServerEventHandler} Http3ServerEventHandler
|
|
12
12
|
* @typedef {import('./types').Http3WTServerSessionVisitorEvent} Http3WTServerSessionVisitorEvent
|
|
13
13
|
* @typedef {import('./types').ServerStatusEvent} ServerStatusEvent
|
|
14
|
+
* @typedef {import('./types').ServerSessionRequestEvent} ServerSessionRequestEvent
|
|
14
15
|
* @typedef {import('./types').Http3ServerInit} Http3ServerInit
|
|
15
16
|
*/
|
|
16
17
|
|
|
@@ -34,6 +35,10 @@ export class Http3Server extends Http3WebTransport {
|
|
|
34
35
|
this.port = null
|
|
35
36
|
this.host = null
|
|
36
37
|
|
|
38
|
+
// FIX ME TYPE
|
|
39
|
+
/** @type {any} */
|
|
40
|
+
this.requestHandler = null
|
|
41
|
+
|
|
37
42
|
this._ready = defer()
|
|
38
43
|
this.ready = this._ready.promise
|
|
39
44
|
|
|
@@ -70,11 +75,21 @@ export class Http3Server extends Http3WebTransport {
|
|
|
70
75
|
}
|
|
71
76
|
}
|
|
72
77
|
|
|
78
|
+
/**
|
|
79
|
+
* @param {any} callback
|
|
80
|
+
*/
|
|
81
|
+
setRequestCallback(callback) {
|
|
82
|
+
this.requestHandler = callback
|
|
83
|
+
|
|
84
|
+
this.transportInt.setJSRequestHandler(!!callback)
|
|
85
|
+
}
|
|
86
|
+
|
|
73
87
|
/**
|
|
74
88
|
* @param {string} path
|
|
89
|
+
* @param {any | undefined} [args=undefined]
|
|
75
90
|
* @returns {ReadableStream<WebTransportSession>}
|
|
76
91
|
*/
|
|
77
|
-
sessionStream(path) {
|
|
92
|
+
sessionStream(path, args) {
|
|
78
93
|
if (path in this.sessionStreams) {
|
|
79
94
|
return this.sessionStreams[path]
|
|
80
95
|
}
|
|
@@ -83,10 +98,30 @@ export class Http3Server extends Http3WebTransport {
|
|
|
83
98
|
this.sessionController[path] = controller
|
|
84
99
|
}
|
|
85
100
|
})
|
|
86
|
-
this.transportInt.addPath(path)
|
|
101
|
+
if (!args || !args.noAutoPaths) this.transportInt.addPath(path)
|
|
87
102
|
return this.sessionStreams[path]
|
|
88
103
|
}
|
|
89
104
|
|
|
105
|
+
/**
|
|
106
|
+
* @param {ServerSessionRequestEvent} args
|
|
107
|
+
*/
|
|
108
|
+
onSessionRequest(args) {
|
|
109
|
+
if (args.promise && args.header) {
|
|
110
|
+
if (!this.requestHandler) throw new Error('Request handler not set')
|
|
111
|
+
this.requestHandler({ header: args.header }).then(
|
|
112
|
+
(/** @type {any} */ result) => {
|
|
113
|
+
console.log('oSR', result)
|
|
114
|
+
this.transportInt.finishSessionRequest({
|
|
115
|
+
promise: args.promise,
|
|
116
|
+
header: args.header,
|
|
117
|
+
session: args.session,
|
|
118
|
+
...result
|
|
119
|
+
})
|
|
120
|
+
}
|
|
121
|
+
)
|
|
122
|
+
} else throw new Error('onSessionRequest')
|
|
123
|
+
}
|
|
124
|
+
|
|
90
125
|
/**
|
|
91
126
|
* @param {Http3WTServerSessionVisitorEvent} args
|
|
92
127
|
*/
|
|
@@ -95,6 +130,7 @@ export class Http3Server extends Http3WebTransport {
|
|
|
95
130
|
if (args.object) {
|
|
96
131
|
const sesobj = new Http3WTSession({
|
|
97
132
|
object: args.session,
|
|
133
|
+
header: args.header,
|
|
98
134
|
parentobj: this
|
|
99
135
|
})
|
|
100
136
|
if (this.sessionController[args.path])
|
|
@@ -144,12 +180,15 @@ export class Http3Server extends Http3WebTransport {
|
|
|
144
180
|
}
|
|
145
181
|
|
|
146
182
|
/**
|
|
147
|
-
* @param {Http3WTServerSessionVisitorEvent | ServerStatusEvent} args
|
|
183
|
+
* @param {Http3WTServerSessionVisitorEvent | ServerStatusEvent | ServerSessionRequestEvent} args
|
|
148
184
|
*/
|
|
149
185
|
customCallback(args) {
|
|
150
186
|
// console.log('incoming callback server', args)
|
|
151
187
|
if (args.purpose) {
|
|
152
188
|
switch (args.purpose) {
|
|
189
|
+
case 'SessionRequest':
|
|
190
|
+
this.onSessionRequest(args)
|
|
191
|
+
break
|
|
153
192
|
case 'Http3WTSessionVisitor':
|
|
154
193
|
this.onHttp3WTSessionVisitor(args)
|
|
155
194
|
break
|
package/lib/session.js
CHANGED
|
@@ -35,6 +35,7 @@ export class Http3WTSession {
|
|
|
35
35
|
* @param {object} args
|
|
36
36
|
* @param {import('./types').NativeHttp3WTSession} [args.object]
|
|
37
37
|
* @param {Http3Server | Http3Client} args.parentobj
|
|
38
|
+
* @param {any | undefined} [args.header= undefined]
|
|
38
39
|
*/
|
|
39
40
|
constructor(args) {
|
|
40
41
|
if (args.object) {
|
|
@@ -49,6 +50,8 @@ export class Http3WTSession {
|
|
|
49
50
|
this.readyResolve = null
|
|
50
51
|
/** @type {(() => void) | null | undefined} */
|
|
51
52
|
this.closeHook = null
|
|
53
|
+
/** @type {(any | null | undefined)} */
|
|
54
|
+
this.header = args.header
|
|
52
55
|
|
|
53
56
|
/** @type {Promise<void>} */
|
|
54
57
|
this.ready = new Promise((resolve, reject) => {
|
package/lib/types.ts
CHANGED
|
@@ -129,6 +129,14 @@ export interface Http3ClientEventHandler {
|
|
|
129
129
|
export interface Http3WTServerSessionVisitorEvent extends Http3WTSessionVisitorEvent {
|
|
130
130
|
path: string
|
|
131
131
|
object: any
|
|
132
|
+
header?: any
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
export interface ServerSessionRequestEvent {
|
|
136
|
+
purpose: 'SessionRequest'
|
|
137
|
+
header: Object
|
|
138
|
+
promise: any
|
|
139
|
+
session: any
|
|
132
140
|
}
|
|
133
141
|
|
|
134
142
|
/**
|
package/package.json
CHANGED
package/src/http3eventloop.cc
CHANGED
|
@@ -253,12 +253,25 @@ namespace quic
|
|
|
253
253
|
progress_->Send(&report, 1);
|
|
254
254
|
}
|
|
255
255
|
|
|
256
|
-
void Http3EventLoop::
|
|
256
|
+
void Http3EventLoop::informAboutNewSessionRequest(Http3Server *server, WebTransportSession *session, spdy::Http2HeaderBlock *reqheadcopy, WebTransportRespPromisePtr promise)
|
|
257
|
+
{
|
|
258
|
+
struct Http3ProgressReport report;
|
|
259
|
+
report.type = Http3ProgressReport::NewSessionRequest;
|
|
260
|
+
report.webtsession = session;
|
|
261
|
+
report.serverobj = server;
|
|
262
|
+
report.headerblock = reqheadcopy;
|
|
263
|
+
report.promise = new WebTransportRespPromisePtr(promise);
|
|
264
|
+
if (progress_)
|
|
265
|
+
progress_->Send(&report, 1);
|
|
266
|
+
}
|
|
267
|
+
|
|
268
|
+
void Http3EventLoop::informAboutNewSession(Http3Server *server, Http3WTSession *session, absl::string_view path, Napi::Reference<Napi::Value> *header)
|
|
257
269
|
{
|
|
258
270
|
struct Http3ProgressReport report;
|
|
259
271
|
report.type = Http3ProgressReport::NewSession;
|
|
260
272
|
report.serverobj = server;
|
|
261
273
|
report.session = session;
|
|
274
|
+
report.header = header;
|
|
262
275
|
report.para = new std::string(path);
|
|
263
276
|
if (progress_)
|
|
264
277
|
progress_->Send(&report, 1);
|
|
@@ -295,7 +308,7 @@ namespace quic
|
|
|
295
308
|
progress_->Send(&report, 1);
|
|
296
309
|
}
|
|
297
310
|
|
|
298
|
-
void Http3EventLoop::informServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails*
|
|
311
|
+
void Http3EventLoop::informServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails *details)
|
|
299
312
|
{
|
|
300
313
|
struct Http3ProgressReport report;
|
|
301
314
|
report.type = Http3ProgressReport::ServerStatus;
|
|
@@ -314,7 +327,8 @@ namespace quic
|
|
|
314
327
|
|
|
315
328
|
void Http3EventLoop::processClientConnected(Http3Client *clientobj, bool success)
|
|
316
329
|
{
|
|
317
|
-
if (!checkQw())
|
|
330
|
+
if (!checkQw())
|
|
331
|
+
return;
|
|
318
332
|
HandleScope scope(qw_->Env());
|
|
319
333
|
auto client = clientobj->getJS();
|
|
320
334
|
|
|
@@ -330,7 +344,8 @@ namespace quic
|
|
|
330
344
|
|
|
331
345
|
void Http3EventLoop::processClientWebtransportSupport(Http3Client *clientobj)
|
|
332
346
|
{
|
|
333
|
-
if (!checkQw())
|
|
347
|
+
if (!checkQw())
|
|
348
|
+
return;
|
|
334
349
|
HandleScope scope(qw_->Env());
|
|
335
350
|
|
|
336
351
|
auto client = clientobj->getJS();
|
|
@@ -345,7 +360,8 @@ namespace quic
|
|
|
345
360
|
|
|
346
361
|
void Http3EventLoop::processStream(bool incom, bool bidi, Http3WTSession *sessionobj, Http3WTStream *stream)
|
|
347
362
|
{
|
|
348
|
-
if (!checkQw())
|
|
363
|
+
if (!checkQw())
|
|
364
|
+
return;
|
|
349
365
|
HandleScope scope(qw_->Env());
|
|
350
366
|
|
|
351
367
|
Http3Constructors *constr = qw_->Env().GetInstanceData<Http3Constructors>();
|
|
@@ -369,7 +385,8 @@ namespace quic
|
|
|
369
385
|
|
|
370
386
|
void Http3EventLoop::processStreamRecvSignal(Http3WTStream *streamobj, WebTransportStreamError error_code, NetworkTask task)
|
|
371
387
|
{
|
|
372
|
-
if (!checkQw())
|
|
388
|
+
if (!checkQw())
|
|
389
|
+
return;
|
|
373
390
|
HandleScope scope(qw_->Env());
|
|
374
391
|
auto stream = streamobj->getJS();
|
|
375
392
|
if (!stream)
|
|
@@ -409,7 +426,8 @@ namespace quic
|
|
|
409
426
|
|
|
410
427
|
void Http3EventLoop::processStreamRead(Http3WTStream *streamobj, std::string *data, bool fin)
|
|
411
428
|
{
|
|
412
|
-
if (!checkQw())
|
|
429
|
+
if (!checkQw())
|
|
430
|
+
return;
|
|
413
431
|
HandleScope scope(qw_->Env());
|
|
414
432
|
|
|
415
433
|
Napi::Object dataVal =
|
|
@@ -435,7 +453,8 @@ namespace quic
|
|
|
435
453
|
|
|
436
454
|
void Http3EventLoop::processStreamWrite(Http3WTStream *streamobj, Napi::ObjectReference *bufferhandle, bool success)
|
|
437
455
|
{
|
|
438
|
-
if (!checkQw())
|
|
456
|
+
if (!checkQw())
|
|
457
|
+
return;
|
|
439
458
|
HandleScope scope(qw_->Env());
|
|
440
459
|
|
|
441
460
|
auto stream = streamobj->getJS();
|
|
@@ -456,7 +475,8 @@ namespace quic
|
|
|
456
475
|
|
|
457
476
|
void Http3EventLoop::processStreamReset(Http3WTStream *streamobj)
|
|
458
477
|
{
|
|
459
|
-
if (!checkQw())
|
|
478
|
+
if (!checkQw())
|
|
479
|
+
return;
|
|
460
480
|
HandleScope scope(qw_->Env());
|
|
461
481
|
|
|
462
482
|
auto stream = streamobj->getJS();
|
|
@@ -474,7 +494,8 @@ namespace quic
|
|
|
474
494
|
|
|
475
495
|
void Http3EventLoop::processStreamNetworkFinish(Http3WTStream *streamobj, NetworkTask task)
|
|
476
496
|
{
|
|
477
|
-
if (!checkQw())
|
|
497
|
+
if (!checkQw())
|
|
498
|
+
return;
|
|
478
499
|
HandleScope scope(qw_->Env());
|
|
479
500
|
|
|
480
501
|
auto stream = streamobj->getJS();
|
|
@@ -520,7 +541,8 @@ namespace quic
|
|
|
520
541
|
|
|
521
542
|
void Http3EventLoop::processDatagramReceived(Http3WTSession *sessionobj, std::string *datagram)
|
|
522
543
|
{
|
|
523
|
-
if (!checkQw())
|
|
544
|
+
if (!checkQw())
|
|
545
|
+
return;
|
|
524
546
|
HandleScope scope(qw_->Env());
|
|
525
547
|
Napi::Object datagramVal =
|
|
526
548
|
Napi::Uint8Array::New(qw_->Env(),
|
|
@@ -544,7 +566,8 @@ namespace quic
|
|
|
544
566
|
|
|
545
567
|
void Http3EventLoop::processDatagramSend(Http3WTSession *sessionobj)
|
|
546
568
|
{
|
|
547
|
-
if (!checkQw())
|
|
569
|
+
if (!checkQw())
|
|
570
|
+
return;
|
|
548
571
|
HandleScope scope(qw_->Env());
|
|
549
572
|
auto session = sessionobj->getJS();
|
|
550
573
|
if (!session)
|
|
@@ -558,9 +581,55 @@ namespace quic
|
|
|
558
581
|
cbsession_.Call({retObj});
|
|
559
582
|
}
|
|
560
583
|
|
|
561
|
-
void Http3EventLoop::
|
|
584
|
+
void Http3EventLoop::processNewSessionRequest(Http3Server *serverobj, WebTransportSession *session, spdy::Http2HeaderBlock *reqheadcopy, WebTransportRespPromisePtr *promise)
|
|
562
585
|
{
|
|
563
|
-
if (!checkQw())
|
|
586
|
+
if (!checkQw())
|
|
587
|
+
return;
|
|
588
|
+
HandleScope scope(qw_->Env());
|
|
589
|
+
|
|
590
|
+
Napi::Object objVal = serverobj->getJS()->Value();
|
|
591
|
+
|
|
592
|
+
Napi::Object retObj = Napi::Object::New(qw_->Env());
|
|
593
|
+
|
|
594
|
+
retObj.Set("purpose", "SessionRequest");
|
|
595
|
+
// header
|
|
596
|
+
|
|
597
|
+
Napi::Object headObj = Napi::Object::New(qw_->Env());
|
|
598
|
+
for (auto pair : *reqheadcopy)
|
|
599
|
+
{
|
|
600
|
+
// we iterate over all header fields
|
|
601
|
+
headObj.Set(std::string(pair.first), std::string(pair.second));
|
|
602
|
+
}
|
|
603
|
+
retObj.Set("header", headObj);
|
|
604
|
+
delete reqheadcopy; // we own it and must free it!
|
|
605
|
+
|
|
606
|
+
// promise
|
|
607
|
+
Napi::External<WebTransportRespPromisePtr> promObj =
|
|
608
|
+
Napi::External<WebTransportRespPromisePtr>::New(qw_->Env(), promise,
|
|
609
|
+
[](Napi::Env /*env*/, WebTransportRespPromisePtr *ref)
|
|
610
|
+
{
|
|
611
|
+
delete ref; // we own it and must delete it
|
|
612
|
+
});
|
|
613
|
+
retObj.Set("promise", promObj);
|
|
614
|
+
|
|
615
|
+
Napi::External<WebTransportSession> wtsObj =
|
|
616
|
+
Napi::External<WebTransportSession>::New(qw_->Env(), session,
|
|
617
|
+
[](Napi::Env /*env*/, WebTransportSession *ref)
|
|
618
|
+
{
|
|
619
|
+
// we do not own it! And do not delete it.
|
|
620
|
+
// does it outlife everything?
|
|
621
|
+
});
|
|
622
|
+
retObj.Set("session", wtsObj);
|
|
623
|
+
|
|
624
|
+
retObj.Set("object", objVal);
|
|
625
|
+
|
|
626
|
+
cbtransport_.Call({retObj});
|
|
627
|
+
}
|
|
628
|
+
|
|
629
|
+
void Http3EventLoop::processNewSession(Http3Server *serverobj, Http3WTSession *session, const std::string &path, Napi::Reference<Napi::Value> *header)
|
|
630
|
+
{
|
|
631
|
+
if (!checkQw())
|
|
632
|
+
return;
|
|
564
633
|
HandleScope scope(qw_->Env());
|
|
565
634
|
|
|
566
635
|
Http3Constructors *constr = qw_->Env().GetInstanceData<Http3Constructors>();
|
|
@@ -577,13 +646,20 @@ namespace quic
|
|
|
577
646
|
retObj.Set("session", sessionobj);
|
|
578
647
|
retObj.Set("path", path);
|
|
579
648
|
retObj.Set("object", objVal);
|
|
649
|
+
if (header)
|
|
650
|
+
{
|
|
651
|
+
retObj.Set("header", header->Value());
|
|
652
|
+
header->Unref();
|
|
653
|
+
delete header;
|
|
654
|
+
}
|
|
580
655
|
|
|
581
656
|
cbtransport_.Call({retObj});
|
|
582
657
|
}
|
|
583
658
|
|
|
584
659
|
void Http3EventLoop::processNewClientSession(Http3Client *clientobj, Http3WTSession *session)
|
|
585
660
|
{
|
|
586
|
-
if (!checkQw())
|
|
661
|
+
if (!checkQw())
|
|
662
|
+
return;
|
|
587
663
|
HandleScope scope(qw_->Env());
|
|
588
664
|
|
|
589
665
|
Napi::Object retObj = Napi::Object::New(qw_->Env());
|
|
@@ -607,7 +683,8 @@ namespace quic
|
|
|
607
683
|
|
|
608
684
|
void Http3EventLoop::processSessionReady(Http3WTSession *sessionobj)
|
|
609
685
|
{
|
|
610
|
-
if (!checkQw())
|
|
686
|
+
if (!checkQw())
|
|
687
|
+
return;
|
|
611
688
|
HandleScope scope(qw_->Env());
|
|
612
689
|
auto session = sessionobj->getJS();
|
|
613
690
|
if (!session)
|
|
@@ -623,7 +700,8 @@ namespace quic
|
|
|
623
700
|
|
|
624
701
|
void Http3EventLoop::processSessionClose(Http3WTSession *sessionobj, uint32_t errorcode, const std::string &error)
|
|
625
702
|
{
|
|
626
|
-
if (!checkQw())
|
|
703
|
+
if (!checkQw())
|
|
704
|
+
return;
|
|
627
705
|
HandleScope scope(qw_->Env());
|
|
628
706
|
|
|
629
707
|
auto session = sessionobj->getJS();
|
|
@@ -642,9 +720,10 @@ namespace quic
|
|
|
642
720
|
cbsession_.Call({retObj});
|
|
643
721
|
}
|
|
644
722
|
|
|
645
|
-
void Http3EventLoop::processServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails *
|
|
723
|
+
void Http3EventLoop::processServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails *details)
|
|
646
724
|
{
|
|
647
|
-
if (!checkQw())
|
|
725
|
+
if (!checkQw())
|
|
726
|
+
return;
|
|
648
727
|
HandleScope scope(qw_->Env());
|
|
649
728
|
|
|
650
729
|
Napi::Object objVal = serverobj->getJS()->Value();
|
|
@@ -660,19 +739,27 @@ namespace quic
|
|
|
660
739
|
delete details; // we own it and must throw it away
|
|
661
740
|
switch (status)
|
|
662
741
|
{
|
|
663
|
-
|
|
742
|
+
case NetError:
|
|
743
|
+
{
|
|
664
744
|
retObj.Set("status", "error");
|
|
665
|
-
|
|
666
|
-
|
|
745
|
+
}
|
|
746
|
+
break;
|
|
747
|
+
case NetListening:
|
|
748
|
+
{
|
|
667
749
|
retObj.Set("status", "listening");
|
|
668
|
-
|
|
669
|
-
|
|
750
|
+
}
|
|
751
|
+
break;
|
|
752
|
+
case NetClose:
|
|
753
|
+
{
|
|
670
754
|
retObj.Set("status", "close");
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
|
|
675
|
-
|
|
755
|
+
}
|
|
756
|
+
break;
|
|
757
|
+
default:
|
|
758
|
+
{
|
|
759
|
+
Napi::Error::New(Env(), "Unknown status from server").ThrowAsJavaScriptException();
|
|
760
|
+
return;
|
|
761
|
+
}
|
|
762
|
+
break;
|
|
676
763
|
};
|
|
677
764
|
cbtransport_.Call({retObj});
|
|
678
765
|
}
|
|
@@ -699,9 +786,14 @@ namespace quic
|
|
|
699
786
|
processNewClientSession(cur.clientobj, cur.session);
|
|
700
787
|
}
|
|
701
788
|
break;
|
|
789
|
+
case Http3ProgressReport::NewSessionRequest:
|
|
790
|
+
{
|
|
791
|
+
processNewSessionRequest(cur.serverobj, cur.webtsession, cur.headerblock, cur.promise);
|
|
792
|
+
}
|
|
793
|
+
break;
|
|
702
794
|
case Http3ProgressReport::NewSession:
|
|
703
795
|
{
|
|
704
|
-
processNewSession(cur.serverobj, cur.session, *cur.para);
|
|
796
|
+
processNewSession(cur.serverobj, cur.session, *cur.para, cur.header);
|
|
705
797
|
}
|
|
706
798
|
break;
|
|
707
799
|
case Http3ProgressReport::SessionReady:
|
|
@@ -791,7 +883,6 @@ namespace quic
|
|
|
791
883
|
if (cur.para)
|
|
792
884
|
delete cur.para;
|
|
793
885
|
}
|
|
794
|
-
|
|
795
886
|
}
|
|
796
887
|
|
|
797
888
|
Http3EventLoop::Http3EventLoop(const Napi::CallbackInfo &info)
|
|
@@ -866,7 +957,8 @@ namespace quic
|
|
|
866
957
|
// got the object we can now start the server
|
|
867
958
|
Ref(); // do not garbage collect
|
|
868
959
|
// epoll_server_.set_timeout_in_us(-1); // negative values would mean wait forever
|
|
869
|
-
if (!checkQw())
|
|
960
|
+
if (!checkQw())
|
|
961
|
+
return;
|
|
870
962
|
qw_->Queue(); // from asyncprogressqueue worker
|
|
871
963
|
}
|
|
872
964
|
|
package/src/http3eventloop.h
CHANGED
|
@@ -33,6 +33,7 @@ namespace quic
|
|
|
33
33
|
class Http3WTSession;
|
|
34
34
|
class Http3WTStream;
|
|
35
35
|
class Http3EventLoop;
|
|
36
|
+
class WebTransportRespPromise;
|
|
36
37
|
|
|
37
38
|
class LifetimeHelper
|
|
38
39
|
{
|
|
@@ -58,10 +59,10 @@ namespace quic
|
|
|
58
59
|
{
|
|
59
60
|
Napi::FunctionReference stream;
|
|
60
61
|
Napi::FunctionReference session;
|
|
61
|
-
|
|
62
62
|
};
|
|
63
63
|
|
|
64
|
-
struct ServerStatusDetails
|
|
64
|
+
struct ServerStatusDetails
|
|
65
|
+
{
|
|
65
66
|
std::string host;
|
|
66
67
|
int port;
|
|
67
68
|
};
|
|
@@ -69,12 +70,15 @@ namespace quic
|
|
|
69
70
|
class Http3ProgressReport // actually struct would be a better fit but make napi happy
|
|
70
71
|
{
|
|
71
72
|
public:
|
|
73
|
+
using WebTransportRespPromise = JSlikePromise<Http3ServerBackend::WebTransportResponse>;
|
|
74
|
+
using WebTransportRespPromisePtr = std::shared_ptr<Http3ServerBackend::WebTransportRespPromise>;
|
|
72
75
|
enum
|
|
73
76
|
{
|
|
74
77
|
ClientConnected,
|
|
75
78
|
ClientWebTransportSupport,
|
|
76
79
|
NewClientSession,
|
|
77
80
|
NewSession,
|
|
81
|
+
NewSessionRequest,
|
|
78
82
|
SessionReady,
|
|
79
83
|
SessionClosed,
|
|
80
84
|
IncomBiDiStream,
|
|
@@ -105,23 +109,27 @@ namespace quic
|
|
|
105
109
|
WebTransportSessionError wtecode;
|
|
106
110
|
NetworkTask nettask;
|
|
107
111
|
NetworkStatus status;
|
|
112
|
+
WebTransportSession *webtsession;
|
|
108
113
|
};
|
|
109
114
|
union
|
|
110
115
|
{
|
|
111
116
|
Http3WTStream *stream; // unowned
|
|
112
117
|
Http3WTSession *session; // unowned
|
|
118
|
+
spdy::Http2HeaderBlock *headerblock; // we own it and must delete it after return from js
|
|
113
119
|
Napi::ObjectReference *bufferhandle; // we own it and must delete it if present
|
|
114
120
|
bool fin;
|
|
115
121
|
WebTransportStreamError wtscode;
|
|
116
122
|
};
|
|
117
123
|
union
|
|
118
124
|
{
|
|
119
|
-
bool success;
|
|
120
|
-
};
|
|
121
|
-
union {
|
|
122
|
-
|
|
123
125
|
std::string *para = nullptr; // for session and others, we own it, and must delete it
|
|
124
|
-
ServerStatusDetails *
|
|
126
|
+
ServerStatusDetails *details;
|
|
127
|
+
};
|
|
128
|
+
union
|
|
129
|
+
{
|
|
130
|
+
bool success;
|
|
131
|
+
WebTransportRespPromisePtr *promise;
|
|
132
|
+
Napi::Reference<Napi::Value> *header;
|
|
125
133
|
};
|
|
126
134
|
};
|
|
127
135
|
|
|
@@ -162,8 +170,6 @@ namespace quic
|
|
|
162
170
|
eventloop_->Destroy();
|
|
163
171
|
}
|
|
164
172
|
|
|
165
|
-
|
|
166
|
-
|
|
167
173
|
protected:
|
|
168
174
|
Http3EventLoop *eventloop_;
|
|
169
175
|
};
|
|
@@ -192,11 +198,15 @@ namespace quic
|
|
|
192
198
|
void informClientWebtransportSupport(Http3Client *client);
|
|
193
199
|
void informNewClientSession(Http3Client *client, Http3WTSession *session);
|
|
194
200
|
|
|
195
|
-
|
|
201
|
+
using WebTransportRespPromise = JSlikePromise<Http3ServerBackend::WebTransportResponse>;
|
|
202
|
+
using WebTransportRespPromisePtr = std::shared_ptr<Http3ServerBackend::WebTransportRespPromise>;
|
|
203
|
+
|
|
204
|
+
void informAboutNewSessionRequest(Http3Server *server, WebTransportSession *session, spdy::Http2HeaderBlock *reqheadcopy, WebTransportRespPromisePtr promise);
|
|
205
|
+
void informAboutNewSession(Http3Server *server, Http3WTSession *session, absl::string_view path, Napi::Reference<Napi::Value> *header);
|
|
196
206
|
void informSessionClosed(Http3WTSession *sessionobj, WebTransportSessionError error_code, absl::string_view error_message);
|
|
197
207
|
void informSessionReady(Http3WTSession *sessionobj);
|
|
198
208
|
|
|
199
|
-
void informServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails*
|
|
209
|
+
void informServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails *details);
|
|
200
210
|
|
|
201
211
|
void informAboutStream(bool incom, bool bidir, Http3WTSession *sessionobj, Http3WTStream *stream);
|
|
202
212
|
void informStreamRecvSignal(Http3WTStream *streamobj, WebTransportStreamError error_code, NetworkTask task);
|
|
@@ -219,15 +229,18 @@ namespace quic
|
|
|
219
229
|
private:
|
|
220
230
|
QueueWorker *qw_;
|
|
221
231
|
|
|
222
|
-
bool checkQw()
|
|
223
|
-
|
|
232
|
+
bool checkQw()
|
|
233
|
+
{
|
|
234
|
+
if (!qw_)
|
|
235
|
+
{
|
|
224
236
|
Napi::Error::New(Env(), "Queueworker gone").ThrowAsJavaScriptException();
|
|
225
237
|
return false;
|
|
226
238
|
}
|
|
227
239
|
return true;
|
|
228
240
|
}
|
|
229
241
|
|
|
230
|
-
void removeQw()
|
|
242
|
+
void removeQw()
|
|
243
|
+
{
|
|
231
244
|
qw_ = nullptr;
|
|
232
245
|
}
|
|
233
246
|
|
|
@@ -254,11 +267,12 @@ namespace quic
|
|
|
254
267
|
void processClientWebtransportSupport(Http3Client *client);
|
|
255
268
|
void processNewClientSession(Http3Client *client, Http3WTSession *session);
|
|
256
269
|
|
|
257
|
-
void
|
|
270
|
+
void processNewSessionRequest(Http3Server *server, WebTransportSession *session, spdy::Http2HeaderBlock *reqheadcopy, WebTransportRespPromisePtr *promise);
|
|
271
|
+
void processNewSession(Http3Server *serverobj, Http3WTSession *session, const std::string &path, Napi::Reference<Napi::Value> *header);
|
|
258
272
|
void processSessionClose(Http3WTSession *sessionobj, uint32_t errorcode, const std::string &path);
|
|
259
273
|
void processSessionReady(Http3WTSession *sessionobj);
|
|
260
274
|
|
|
261
|
-
void processServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails *
|
|
275
|
+
void processServerStatus(Http3Server *serverobj, NetworkStatus status, ServerStatusDetails *details);
|
|
262
276
|
|
|
263
277
|
void processStream(bool incom, bool bidi, Http3WTSession *sessionobj, Http3WTStream *stream);
|
|
264
278
|
void processStreamRecvSignal(Http3WTStream *streamobj, WebTransportStreamError error_code, NetworkTask task);
|
|
@@ -279,7 +293,6 @@ namespace quic
|
|
|
279
293
|
Napi::FunctionReference cbsession_;
|
|
280
294
|
Napi::FunctionReference cbtransport_;
|
|
281
295
|
|
|
282
|
-
|
|
283
296
|
bool loop_running_;
|
|
284
297
|
};
|
|
285
298
|
}
|
package/src/http3server.cc
CHANGED
|
@@ -400,5 +400,116 @@ namespace quic
|
|
|
400
400
|
};
|
|
401
401
|
obj->eventloop_->Schedule(task);
|
|
402
402
|
}
|
|
403
|
+
else
|
|
404
|
+
return Napi::Error::New(Env(), "No path set for addPath").ThrowAsJavaScriptException();
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
void Http3ServerJS::finishSessionRequest(const Napi::CallbackInfo &info)
|
|
408
|
+
{
|
|
409
|
+
Http3Server *obj = getObj();
|
|
410
|
+
|
|
411
|
+
if (!info[0].IsUndefined())
|
|
412
|
+
{
|
|
413
|
+
// needs two properties
|
|
414
|
+
int status = -1;
|
|
415
|
+
std::string path = "";
|
|
416
|
+
Napi::Object lobj = info[0].ToObject();
|
|
417
|
+
if (!lobj.IsEmpty())
|
|
418
|
+
{
|
|
419
|
+
if (lobj.Has("status") && !(lobj).Get("status").IsEmpty())
|
|
420
|
+
{
|
|
421
|
+
Napi::Value statusValue = (lobj).Get("status");
|
|
422
|
+
status = statusValue.As<Napi::Number>().Int32Value();
|
|
423
|
+
}
|
|
424
|
+
else
|
|
425
|
+
return Napi::Error::New(Env(), "No status code passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
426
|
+
|
|
427
|
+
if (lobj.Has("path") && !(lobj).Get("path").IsEmpty())
|
|
428
|
+
{
|
|
429
|
+
Napi::Value pathValue = (lobj).Get("path");
|
|
430
|
+
path = pathValue.ToString().Utf8Value();
|
|
431
|
+
}
|
|
432
|
+
else
|
|
433
|
+
return Napi::Error::New(Env(), "No status code passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
434
|
+
WebTransportSession *session = nullptr;
|
|
435
|
+
if (lobj.Has("session") && !(lobj).Get("session").IsEmpty())
|
|
436
|
+
{
|
|
437
|
+
Napi::Value sessionVal = (lobj).Get("session");
|
|
438
|
+
if (!sessionVal.IsExternal())
|
|
439
|
+
return Napi::Error::New(Env(), "Session is not external for finishSessionRequest").ThrowAsJavaScriptException();
|
|
440
|
+
Napi::External<WebTransportSession> sessionExt = sessionVal.As<Napi::External<WebTransportSession>>();
|
|
441
|
+
session = sessionExt.Data();
|
|
442
|
+
}
|
|
443
|
+
else
|
|
444
|
+
return Napi::Error::New(Env(), "No session passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
445
|
+
|
|
446
|
+
if (lobj.Has("promise") && !(lobj).Get("promise").IsEmpty())
|
|
447
|
+
{
|
|
448
|
+
Napi::Value promiseVal = (lobj).Get("promise");
|
|
449
|
+
if (!promiseVal.IsExternal())
|
|
450
|
+
return Napi::Error::New(Env(), "Promise is not external for finishSessionRequest").ThrowAsJavaScriptException();
|
|
451
|
+
Napi::External<Http3ServerBackend::WebTransportRespPromisePtr> promise = promiseVal.As<Napi::External<Http3ServerBackend::WebTransportRespPromisePtr>>();
|
|
452
|
+
|
|
453
|
+
Http3ServerBackend::WebTransportRespPromisePtr *prom = promise.Data();
|
|
454
|
+
Napi::Reference<Napi::Value> *headerValue = nullptr;
|
|
455
|
+
if (status == 200)
|
|
456
|
+
{
|
|
457
|
+
|
|
458
|
+
if (lobj.Has("header") && !(lobj).Get("header").IsEmpty())
|
|
459
|
+
{
|
|
460
|
+
napi_ref ref;
|
|
461
|
+
napi_status status = napi_create_reference(Env(), lobj.Get("header"), 1, &ref);
|
|
462
|
+
NAPI_THROW_IF_FAILED(Env(), status, Reference<Napi::Value>());
|
|
463
|
+
headerValue = new Napi::Reference<Napi::Value>(Env(), ref);
|
|
464
|
+
}
|
|
465
|
+
else
|
|
466
|
+
return Napi::Error::New(Env(), "No status code passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
467
|
+
}
|
|
468
|
+
std::function<void()> task = [status, prom, path, headerValue, session, obj, this]()
|
|
469
|
+
{
|
|
470
|
+
if (status != 200)
|
|
471
|
+
{
|
|
472
|
+
std::unique_ptr<Http3ServerBackend::WebTransportResponse> response = std::make_unique<Http3ServerBackend::WebTransportResponse>();
|
|
473
|
+
response->response_headers[":status"] = std::to_string(status);
|
|
474
|
+
(*prom)->resolve(std::move(response));
|
|
475
|
+
}
|
|
476
|
+
else
|
|
477
|
+
{
|
|
478
|
+
std::unique_ptr<Http3ServerBackend::WebTransportResponse> response = std::make_unique<Http3ServerBackend::WebTransportResponse>();
|
|
479
|
+
response->response_headers[":status"] = std::to_string(status);
|
|
480
|
+
Http3WTSession *wtsession = new Http3WTSession();
|
|
481
|
+
wtsession->init(session, obj->eventloop_);
|
|
482
|
+
response->visitor =
|
|
483
|
+
std::make_unique<Http3WTSession::Visitor>(wtsession);
|
|
484
|
+
obj->eventloop_->informAboutNewSession(obj, static_cast<Http3WTSession *>(wtsession), path, headerValue);
|
|
485
|
+
(*prom)->resolve(std::move(response));
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
obj->eventloop_->Schedule(task);
|
|
489
|
+
}
|
|
490
|
+
else
|
|
491
|
+
return Napi::Error::New(Env(), "No promise passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
492
|
+
}
|
|
493
|
+
else
|
|
494
|
+
return Napi::Error::New(Env(), "No object passed for finishSessionRequest").ThrowAsJavaScriptException();
|
|
495
|
+
}
|
|
496
|
+
}
|
|
497
|
+
|
|
498
|
+
void Http3ServerJS::setJSRequestHandler(const Napi::CallbackInfo &info)
|
|
499
|
+
{
|
|
500
|
+
Http3Server *obj = getObj();
|
|
501
|
+
|
|
502
|
+
if (!info[0].IsUndefined())
|
|
503
|
+
{
|
|
504
|
+
|
|
505
|
+
bool hashandler = info[0].ToBoolean();
|
|
506
|
+
std::function<void()> task = [obj, hashandler]()
|
|
507
|
+
{
|
|
508
|
+
obj->http3_server_backend_.setJSHandler(hashandler);
|
|
509
|
+
};
|
|
510
|
+
obj->eventloop_->Schedule(task);
|
|
511
|
+
}
|
|
512
|
+
else
|
|
513
|
+
return Napi::Error::New(Env(), "No bool set for setJSRequestHandler").ThrowAsJavaScriptException();
|
|
403
514
|
}
|
|
404
515
|
}
|
package/src/http3server.h
CHANGED
|
@@ -50,6 +50,9 @@ namespace quic
|
|
|
50
50
|
|
|
51
51
|
void addPath(const Napi::CallbackInfo &info);
|
|
52
52
|
|
|
53
|
+
void finishSessionRequest(const Napi::CallbackInfo &info);
|
|
54
|
+
|
|
55
|
+
void setJSRequestHandler(const Napi::CallbackInfo &info);
|
|
53
56
|
|
|
54
57
|
static void InitExports(Napi::Env env, Napi::Object exports)
|
|
55
58
|
{
|
|
@@ -59,7 +62,11 @@ namespace quic
|
|
|
59
62
|
InstanceMethod<&Http3ServerJS::stopServer>("stopServer",
|
|
60
63
|
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
61
64
|
InstanceMethod<&Http3ServerJS::addPath>("addPath",
|
|
62
|
-
static_cast<napi_property_attributes>(napi_writable | napi_configurable))
|
|
65
|
+
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
66
|
+
InstanceMethod<&Http3ServerJS::finishSessionRequest>("finishSessionRequest",
|
|
67
|
+
static_cast<napi_property_attributes>(napi_writable | napi_configurable)),
|
|
68
|
+
InstanceMethod<&Http3ServerJS::setJSRequestHandler>("setJSRequestHandler",
|
|
69
|
+
static_cast<napi_property_attributes>(napi_writable | napi_configurable))});
|
|
63
70
|
exports.Set("Http3WebTransportServer", tplsrv);
|
|
64
71
|
}
|
|
65
72
|
|
|
@@ -95,11 +102,12 @@ namespace quic
|
|
|
95
102
|
|
|
96
103
|
Http3ServerJS *getJS() { return js_; };
|
|
97
104
|
|
|
98
|
-
ServerStatusDetails *getStatusDetails()
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
105
|
+
ServerStatusDetails *getStatusDetails()
|
|
106
|
+
{
|
|
107
|
+
ServerStatusDetails *details = new ServerStatusDetails();
|
|
108
|
+
details->host = host_;
|
|
109
|
+
details->port = port_;
|
|
110
|
+
return details;
|
|
103
111
|
}
|
|
104
112
|
|
|
105
113
|
private:
|
|
@@ -26,7 +26,6 @@
|
|
|
26
26
|
#include "quiche/common/platform/api/quiche_file_utils.h"
|
|
27
27
|
#include "quiche/common/quiche_text_utils.h"
|
|
28
28
|
|
|
29
|
-
|
|
30
29
|
using spdy::Http2HeaderBlock;
|
|
31
30
|
|
|
32
31
|
namespace quic
|
|
@@ -45,42 +44,56 @@ namespace quic
|
|
|
45
44
|
}
|
|
46
45
|
*/
|
|
47
46
|
|
|
48
|
-
Http3ServerBackend::
|
|
47
|
+
Http3ServerBackend::WebTransportRespPromisePtr
|
|
49
48
|
Http3ServerBackend::ProcessWebTransportRequest(
|
|
50
49
|
const spdy::Http2HeaderBlock &request_headers,
|
|
51
50
|
WebTransportSession *session)
|
|
52
51
|
{
|
|
52
|
+
WebTransportRespPromisePtr promise = std::make_shared<WebTransportRespPromise>();
|
|
53
53
|
if (!SupportsWebTransport())
|
|
54
54
|
{
|
|
55
|
-
WebTransportResponse response;
|
|
56
|
-
response
|
|
57
|
-
|
|
55
|
+
std::unique_ptr<WebTransportResponse> response = std::make_unique<WebTransportResponse>();
|
|
56
|
+
response->response_headers[":status"] = "400";
|
|
57
|
+
promise->resolve(std::move(response));
|
|
58
|
+
return promise;
|
|
58
59
|
}
|
|
59
60
|
|
|
60
61
|
auto path_it = request_headers.find(":path");
|
|
61
62
|
if (path_it == request_headers.end())
|
|
62
63
|
{
|
|
63
|
-
WebTransportResponse response;
|
|
64
|
-
response
|
|
65
|
-
|
|
64
|
+
std::unique_ptr<WebTransportResponse> response = std::make_unique<WebTransportResponse>();
|
|
65
|
+
response->response_headers[":status"] = "400";
|
|
66
|
+
promise->resolve(std::move(response));
|
|
67
|
+
return promise;
|
|
66
68
|
}
|
|
67
69
|
std::string path(path_it->second);
|
|
68
70
|
|
|
69
71
|
if (paths_.find(path) != paths_.end())
|
|
70
72
|
{ // to do handle our web transport paths
|
|
71
|
-
WebTransportResponse response;
|
|
72
|
-
Http3WTSession *
|
|
73
|
+
std::unique_ptr<WebTransportResponse> response = std::make_unique<WebTransportResponse>();
|
|
74
|
+
Http3WTSession *wtsession = new Http3WTSession();
|
|
73
75
|
wtsession->init(session, eventloop_);
|
|
74
|
-
response
|
|
75
|
-
response
|
|
76
|
-
std::make_unique<Http3WTSession::Visitor>(wtsession);
|
|
77
|
-
eventloop_->informAboutNewSession(server_, static_cast<Http3WTSession *>(wtsession), path);
|
|
78
|
-
|
|
76
|
+
response->response_headers[":status"] = "200";
|
|
77
|
+
response->visitor =
|
|
78
|
+
std::make_unique<Http3WTSession::Visitor>(wtsession);
|
|
79
|
+
eventloop_->informAboutNewSession(server_, static_cast<Http3WTSession *>(wtsession), path, nullptr);
|
|
80
|
+
promise->resolve(std::move(response));
|
|
81
|
+
return promise;
|
|
82
|
+
}
|
|
83
|
+
else if (jshandlerequesthandler_)
|
|
84
|
+
{
|
|
85
|
+
// first step pass header block along, due to thread safety, we need to copy
|
|
86
|
+
spdy::Http2HeaderBlock *reqheadcopy = new Http2HeaderBlock(request_headers.Clone());
|
|
87
|
+
|
|
88
|
+
// second step inform the js side
|
|
89
|
+
eventloop_->informAboutNewSessionRequest(server_, session, reqheadcopy, promise);
|
|
90
|
+
return promise;
|
|
79
91
|
}
|
|
80
92
|
|
|
81
|
-
WebTransportResponse response;
|
|
82
|
-
response
|
|
83
|
-
|
|
93
|
+
std::unique_ptr<WebTransportResponse> response = std::make_unique<WebTransportResponse>();
|
|
94
|
+
response->response_headers[":status"] = "404";
|
|
95
|
+
promise->resolve(std::move(response));
|
|
96
|
+
return promise;
|
|
84
97
|
}
|
|
85
98
|
|
|
86
99
|
Http3ServerBackend::~Http3ServerBackend()
|
package/src/http3serverbackend.h
CHANGED
|
@@ -23,6 +23,36 @@ namespace quic
|
|
|
23
23
|
class Http3Server;
|
|
24
24
|
class Http3EventLoop;
|
|
25
25
|
|
|
26
|
+
template <typename T>
|
|
27
|
+
class JSlikePromise
|
|
28
|
+
{
|
|
29
|
+
public:
|
|
30
|
+
void finally(std::function<void(T *)> func)
|
|
31
|
+
{
|
|
32
|
+
T *res = result.get();
|
|
33
|
+
if (res != nullptr)
|
|
34
|
+
func(res);
|
|
35
|
+
else
|
|
36
|
+
finallys.push_back(func);
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
void resolve(std::unique_ptr<T> res)
|
|
40
|
+
{
|
|
41
|
+
if (result.get() != nullptr)
|
|
42
|
+
return; // throw std::runtime_error("Promise already settled");
|
|
43
|
+
result = std::move(res);
|
|
44
|
+
for (auto finally : finallys)
|
|
45
|
+
{
|
|
46
|
+
finally(result.get());
|
|
47
|
+
}
|
|
48
|
+
finallys.clear();
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
protected:
|
|
52
|
+
std::unique_ptr<T> result;
|
|
53
|
+
std::list<std::function<void(T *)>> finallys;
|
|
54
|
+
};
|
|
55
|
+
|
|
26
56
|
// This interface implements the functionality to fetch a response
|
|
27
57
|
// from the backend (such as cache, http-proxy etc) to serve
|
|
28
58
|
// requests received by a Quic Server
|
|
@@ -36,14 +66,18 @@ namespace quic
|
|
|
36
66
|
std::unique_ptr<WebTransportVisitor> visitor;
|
|
37
67
|
};
|
|
38
68
|
|
|
69
|
+
using WebTransportRespPromise = JSlikePromise<WebTransportResponse>;
|
|
70
|
+
using WebTransportRespPromisePtr = std::shared_ptr<WebTransportRespPromise>;
|
|
71
|
+
|
|
39
72
|
Http3ServerBackend(Http3EventLoop *eventloop) : eventloop_(eventloop),
|
|
40
|
-
|
|
73
|
+
server_(nullptr), jshandlerequesthandler_(false) {}
|
|
41
74
|
|
|
42
75
|
~Http3ServerBackend();
|
|
43
76
|
|
|
44
77
|
void setServer(Http3Server *server) { server_ = server; }
|
|
78
|
+
void setJSHandler(bool on) { jshandlerequesthandler_ = on; }
|
|
45
79
|
|
|
46
|
-
|
|
80
|
+
WebTransportRespPromisePtr ProcessWebTransportRequest(
|
|
47
81
|
const spdy::Http2HeaderBlock & /*request_headers*/,
|
|
48
82
|
WebTransportSession * /*session*/);
|
|
49
83
|
bool SupportsWebTransport() { return true; }
|
|
@@ -53,8 +87,9 @@ namespace quic
|
|
|
53
87
|
void addPath(std::string path) { paths_.insert(path); }
|
|
54
88
|
|
|
55
89
|
protected:
|
|
56
|
-
Http3Server *server_;
|
|
90
|
+
Http3Server *server_; // unowned
|
|
57
91
|
Http3EventLoop *eventloop_; // unowned
|
|
92
|
+
bool jshandlerequesthandler_;
|
|
58
93
|
std::set<std::string> paths_;
|
|
59
94
|
};
|
|
60
95
|
|
package/src/http3serverstream.cc
CHANGED
|
@@ -59,6 +59,13 @@ namespace quic
|
|
|
59
59
|
Http3ServerStream::~Http3ServerStream()
|
|
60
60
|
{
|
|
61
61
|
// http3_server_backend_->CloseBackendResponseStream(this);
|
|
62
|
+
for (auto prom : pending_proms_)
|
|
63
|
+
{
|
|
64
|
+
std::unique_ptr<Http3ServerBackend::WebTransportResponse> response =
|
|
65
|
+
std::make_unique<Http3ServerBackend::WebTransportResponse>();
|
|
66
|
+
response->response_headers[":status"] = "500"; // internal server error, probably implementation on js side
|
|
67
|
+
prom->resolve(std::move(response));
|
|
68
|
+
}
|
|
62
69
|
}
|
|
63
70
|
|
|
64
71
|
void Http3ServerStream::OnInitialHeadersComplete(
|
|
@@ -211,22 +218,28 @@ namespace quic
|
|
|
211
218
|
|
|
212
219
|
if (web_transport() != nullptr)
|
|
213
220
|
{
|
|
214
|
-
|
|
221
|
+
// to do synchronize lifetime of object, so maybe store promises
|
|
222
|
+
Http3ServerBackend::WebTransportRespPromisePtr response =
|
|
215
223
|
http3_server_backend_->ProcessWebTransportRequest(
|
|
216
224
|
request_headers_, web_transport());
|
|
217
|
-
|
|
225
|
+
pending_proms_.insert(response);
|
|
226
|
+
response->finally([this, response](Http3ServerBackend::WebTransportResponse *resp)
|
|
227
|
+
{
|
|
228
|
+
pending_proms_.erase(response);
|
|
229
|
+
if (resp->response_headers[":status"] == "200")
|
|
218
230
|
{
|
|
219
|
-
WriteHeaders(std::move(
|
|
220
|
-
if (
|
|
231
|
+
WriteHeaders(std::move(resp->response_headers), false, nullptr);
|
|
232
|
+
if (resp->visitor != nullptr)
|
|
221
233
|
{
|
|
222
|
-
web_transport()->SetVisitor(std::move(
|
|
234
|
+
web_transport()->SetVisitor(std::move(resp->visitor));
|
|
223
235
|
}
|
|
224
236
|
web_transport()->HeadersReceived(request_headers_);
|
|
225
237
|
}
|
|
226
238
|
else
|
|
227
239
|
{
|
|
228
|
-
WriteHeaders(std::move(
|
|
240
|
+
WriteHeaders(std::move(resp->response_headers), true, nullptr);
|
|
229
241
|
}
|
|
242
|
+
return; });
|
|
230
243
|
return;
|
|
231
244
|
}
|
|
232
245
|
|
package/src/http3serverstream.h
CHANGED
|
@@ -103,6 +103,8 @@ namespace quic
|
|
|
103
103
|
spdy::Http2HeaderBlock request_headers_;
|
|
104
104
|
int64_t content_length_;
|
|
105
105
|
std::string body_;
|
|
106
|
+
// promises not fullfilled from js side or c++ side
|
|
107
|
+
std::set<Http3ServerBackend::WebTransportRespPromisePtr> pending_proms_;
|
|
106
108
|
|
|
107
109
|
private:
|
|
108
110
|
uint64_t generate_bytes_length_;
|
|
@@ -69,7 +69,10 @@ namespace quic
|
|
|
69
69
|
void Http3WTStream::doCanRead()
|
|
70
70
|
{
|
|
71
71
|
if (pause_reading_)
|
|
72
|
+
{
|
|
73
|
+
can_read_pending_ = true;
|
|
72
74
|
return; // back pressure folks!
|
|
75
|
+
}
|
|
73
76
|
// first figure out if we have readable data
|
|
74
77
|
size_t readable = stream_->ReadableBytes();
|
|
75
78
|
// ok create a string obj to hold the data
|
|
@@ -93,8 +93,9 @@ namespace quic
|
|
|
93
93
|
void tryRead()
|
|
94
94
|
{
|
|
95
95
|
pause_reading_ = false;
|
|
96
|
-
if (stream_ && stream_->ReadableBytes() > 0)
|
|
96
|
+
if (stream_ && ((stream_->ReadableBytes() > 0) || can_read_pending_))
|
|
97
97
|
{
|
|
98
|
+
can_read_pending_ = false;
|
|
98
99
|
doCanRead();
|
|
99
100
|
}
|
|
100
101
|
}
|
|
@@ -209,6 +210,7 @@ namespace quic
|
|
|
209
210
|
bool fin_was_sent_ = false;
|
|
210
211
|
bool stop_sending_received_ = false;
|
|
211
212
|
bool pause_reading_ = false;
|
|
213
|
+
bool can_read_pending_ = false;
|
|
212
214
|
std::deque<WChunks> chunks_;
|
|
213
215
|
};
|
|
214
216
|
|
|
@@ -125,4 +125,56 @@ describe('unidirectional streams', function () {
|
|
|
125
125
|
'Did not receive the same bytes we sent'
|
|
126
126
|
)
|
|
127
127
|
})
|
|
128
|
+
|
|
129
|
+
it('handles fin when paused due to backpressure', async function () {
|
|
130
|
+
this.timeout(10000)
|
|
131
|
+
|
|
132
|
+
/** @type {Deferred<ReadableStream>} */
|
|
133
|
+
const serverStream = defer()
|
|
134
|
+
|
|
135
|
+
Promise.resolve().then(async () => {
|
|
136
|
+
const session = await getReaderValue(server.sessionStream(SERVER_PATH))
|
|
137
|
+
const stream = await getReaderValue(session.incomingUnidirectionalStreams)
|
|
138
|
+
|
|
139
|
+
serverStream.resolve(stream)
|
|
140
|
+
})
|
|
141
|
+
|
|
142
|
+
client = new WebTransport(`${url}${SERVER_PATH}`, {
|
|
143
|
+
serverCertificateHashes: [
|
|
144
|
+
{
|
|
145
|
+
algorithm: 'sha-256',
|
|
146
|
+
value: certificate.hash
|
|
147
|
+
}
|
|
148
|
+
]
|
|
149
|
+
})
|
|
150
|
+
await client.ready
|
|
151
|
+
|
|
152
|
+
const clientStream = await client.createUnidirectionalStream()
|
|
153
|
+
|
|
154
|
+
const input = [
|
|
155
|
+
Uint8Array.from([0, 1, 2, 3, 4]),
|
|
156
|
+
Uint8Array.from([5, 6, 7, 8, 9]),
|
|
157
|
+
Uint8Array.from([10, 11, 12, 13, 14]),
|
|
158
|
+
Uint8Array.from([15, 16, 17, 18, 19]),
|
|
159
|
+
Uint8Array.from([20, 21, 22, 23, 24])
|
|
160
|
+
]
|
|
161
|
+
|
|
162
|
+
const writer = clientStream.getWriter()
|
|
163
|
+
|
|
164
|
+
for (const buf of input) {
|
|
165
|
+
await writer.write(buf)
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
169
|
+
|
|
170
|
+
await writer.close()
|
|
171
|
+
|
|
172
|
+
await new Promise((resolve) => setTimeout(resolve, 1000))
|
|
173
|
+
|
|
174
|
+
const received = await readStream(await serverStream.promise)
|
|
175
|
+
expect(received).to.deep.equal(
|
|
176
|
+
input,
|
|
177
|
+
'Did not receive the same bytes we sent'
|
|
178
|
+
)
|
|
179
|
+
})
|
|
128
180
|
})
|