@@ -2,7 +2,15 @@ import { createServerAdapter } from '@whatwg-node/server';
2
2
import { IncomingMessage , ServerResponse } from 'http' ;
3
3
import { createTestServer , TestServer } from './test-server' ;
4
4
import { createTestContainer } from './create-test-container' ;
5
- import { Http2ServerRequest , Http2ServerResponse } from 'http2' ;
5
+ import {
6
+ createSecureServer as createHttp2SecureServer ,
7
+ Http2ServerRequest ,
8
+ Http2ServerResponse ,
9
+ connect as connectHttp2 ,
10
+ constants as constantsHttp2 ,
11
+ } from 'http2' ;
12
+ import { AddressInfo } from 'net' ;
13
+ import { createFetch } from '@whatwg-node/fetch' ;
6
14
7
15
describe ( 'Node Specific Cases' , ( ) => {
8
16
let testServer : TestServer ;
@@ -113,6 +121,122 @@ describe('Node Specific Cases', () => {
113
121
adapter . handle ( req , res ) ;
114
122
adapter ( req , res ) ;
115
123
} ) ;
124
+
125
+ it . each ( [
126
+ {
127
+ fetchImpl : 'default' ,
128
+ fetchAPI : createFetch ( { useNodeFetch : false } ) ,
129
+ } ,
130
+ {
131
+ fetchImpl : 'node-fetch' ,
132
+ fetchAPI : createFetch ( { useNodeFetch : true } ) ,
133
+ } ,
134
+ ] ) ( 'should support http2 and respond as expected when using $fetchImpl implementation' , async ( { fetchAPI } ) => {
135
+ const adapter = createServerAdapter ( req => {
136
+ expect ( req . method ) . toBe ( 'POST' ) ;
137
+ // TODO: only passes if create-node-ponyfill.js is used
138
+ // expect(req.headers.get('host')).toMatch(/^localhost:\d+$/);
139
+ // expect(req.url).toMatch(/^https:\/\/localhost:\d+\/hi$/);
140
+ return new fetchAPI . Response ( 'Hey there!' , { status : 418 , headers : { 'x-is-this-http2' : 'yes' } } ) ;
141
+ } , fetchAPI . Request ) ;
142
+
143
+ const key = `-----BEGIN PRIVATE KEY-----
144
+ MIIEvwIBADANBgkqhkiG9w0BAQEFAASCBKkwggSlAgEAAoIBAQDL2k3sKtqBQ9lw
145
+ ouLuCewSuTCazFjSdzJKLWmm9d9OLRi9SVPaIaes0ItExHFXwVNSXGUlabTSXxVP
146
+ x9cJXDtloBnlN+YKK5f8vcpP7a9hquYDKMhM27kP6e8CIugDfXP4rz52o6Jn2ZEz
147
+ JrzpbrF3eDtD4uVfXfZeAgR9jilfFI+L5qu5AjZSWtL/YwqVRus1r3ChXBOgvLy/
148
+ MN7NJ1W7fDgyCLge1HvDGPidyrHoVezGEtzWUpGatgR6PNhdtI5M/bf+l4+xAHL6
149
+ sYeTpg6iAsrE+K3VkBIFgxye7lzXUIXyeQ6ij3DsBVlT6bY80g1QpcTDBoXCOnkS
150
+ GEyFuC33AgMBAAECggEBAK7FA8d1Wg43GGW8EKiaMx4+TVB537DZZnE4C/uLkp6Y
151
+ hTxLcKtz7Sh5Rt13OeFNqtzSwBjaTp+Jy2Cx6UdqHrZbE7h0OzH++/hA0wHBunoW
152
+ pcqRnWBfhIMDQdloCdhsJxBPVlMqqWM1oYnkLVRIhbfyiYUDMzmW+lDQk/788bVE
153
+ BmTVY9qkHYt+6Cu97Wt4mVQZS6CS9oaJn3btuUbT7V3x3q5ER7jRmwRUPwFc4uVv
154
+ lEFP/UCc3JeK+rEoZVVcafImetLfzwTszQ18BV5Y4plt+kB7OFW8OVpAgrnK6e3g
155
+ +RVsN3FhN6QkgkWhhpQOVCqBTNphxmrOnL3shmEJ7gECgYEA/qGeSA+l3Wh9+aUk
156
+ wBo7nsyqJa/61K10uLNe47tJe5ZxB11lT3JCNvNhuJ/BTxiGclRTRCSl/VQOZ3JY
157
+ s6TR3i6LtykfypyaQCjMDWXRZpEoBpEdwKP+o/9M03oIRs3eGxTm83iC/GCYooQR
158
+ tfHJMLlgQufsq5+uGnU/7QMGDwECgYEAzPLQH/lsM7yROyc7Q877scFnYVLX/U+r
159
+ 6lQROFWuLM3a3DGafg9+kFziZVK7jQ41z/EywuU//XH7UtrjmVlGRZCSbhFGPokw
160
+ gO4q2KaDuFyq1iSRIorj3pjXO+zYZoX7fcbMInlpC+oBpU+S1jyRreGgdhkEXtYq
161
+ 9bQSUntTtPcCgYEA1T661PSt3tfUsI7aUTtm9N3IHNndQeGmH8ywSh4eMy9Rp25T
162
+ Gw7AX07CZyD7fmc2qWbveOEMVjTf/0hm+sOsstreTV1Wb5NpJxRDl3DOxowILj+3
163
+ 4A43glabm3vWlJ1yRdHifMJPSFcJXQkn3+0GphSJhl6++Rg4cZYCHFbs6wECgYEA
164
+ xsAWa1uTvdx5LtdN1uVsGqbHHY+cXFAeFOGvzWTxwwti2jTUcLmP8GnTN5Vywkjs
165
+ kJqEspJlauBVbLVPENCNoDqidlEUQOMEAZR2QqHAjVJ4bbEKemgcsSqhV8DI3yvB
166
+ huj539jDsUUekXTInjAgynJLDRwXq+yfvqUBO7HTrGMCgYBmPS4dcLoBC04MiSIQ
167
+ mDYzpcI51XzlyJPQQKjHjck5H4WDV80EIX22krvFMh44IOyqZu3Ou+iSPCR1hi1z
168
+ Mp0YOF+YKJ9PCrJu4W/xt1pnxfXe9bTg5HKtN6DmYlSz78EMelSVemaqOgNoIBqC
169
+ t6Ra3NuebwL/VQ1JpBhh4eJYZg==
170
+ -----END PRIVATE KEY-----` ;
171
+ const cert = `-----BEGIN CERTIFICATE-----
172
+ MIICpDCCAYwCCQClE698xX22XDANBgkqhkiG9w0BAQsFADAUMRIwEAYDVQQDDAls
173
+ b2NhbGhvc3QwHhcNMjIxMjI4MTc0NDMxWhcNMjMwMTI3MTc0NDMxWjAUMRIwEAYD
174
+ VQQDDAlsb2NhbGhvc3QwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEKAoIBAQDL
175
+ 2k3sKtqBQ9lwouLuCewSuTCazFjSdzJKLWmm9d9OLRi9SVPaIaes0ItExHFXwVNS
176
+ XGUlabTSXxVPx9cJXDtloBnlN+YKK5f8vcpP7a9hquYDKMhM27kP6e8CIugDfXP4
177
+ rz52o6Jn2ZEzJrzpbrF3eDtD4uVfXfZeAgR9jilfFI+L5qu5AjZSWtL/YwqVRus1
178
+ r3ChXBOgvLy/MN7NJ1W7fDgyCLge1HvDGPidyrHoVezGEtzWUpGatgR6PNhdtI5M
179
+ /bf+l4+xAHL6sYeTpg6iAsrE+K3VkBIFgxye7lzXUIXyeQ6ij3DsBVlT6bY80g1Q
180
+ pcTDBoXCOnkSGEyFuC33AgMBAAEwDQYJKoZIhvcNAQELBQADggEBAL3BU99gtkpT
181
+ 9KwkFtn18+j3OFaJzoj+WPrC0YvbPx3KqnZeEH3MvqyRk7WMcUVrPnmLY9S7oPYb
182
+ AYpkSwuvh0374zVcAn0CYRWSafj6nM9xmEWk3F28jfF+XemS1F8/Z0NyLJSVytIb
183
+ bdEO2Po5v+S/RlE/QE7ONaKYecOPMTcW7FeEze77DOJXTvkuM5ab/Wj1mbSE40sH
184
+ VhEJmi7pGnPZOobUh3QhhpvqJ4myRCyrHKS53l1RJJ+7/XXVq6WDHAcMxHseRKnb
185
+ ziIZM/48ENV+m5yXVvUZJaKOggThi+RhLSwIyVzn8ScawkXS70bZtI4CrSTXu3H9
186
+ /huiHkWkMUs=
187
+ -----END CERTIFICATE-----` ;
188
+
189
+ const server = createHttp2SecureServer ( { key, cert } , adapter ) ;
190
+ server . listen ( 0 ) ;
191
+ const port = ( server . address ( ) as AddressInfo ) . port ;
192
+
193
+ // Node's fetch API does not support HTTP/2, we use the http2 module directly instead
194
+
195
+ const client = connectHttp2 ( `https://localhost:${ port } ` , { ca : cert } ) ;
196
+
197
+ const req = client . request ( {
198
+ [ constantsHttp2 . HTTP2_HEADER_METHOD ] : 'POST' ,
199
+ [ constantsHttp2 . HTTP2_HEADER_PATH ] : '/hi' ,
200
+ } ) ;
201
+
202
+ await expect (
203
+ new Promise ( ( resolve , reject ) => {
204
+ req . on (
205
+ 'response' ,
206
+ ( {
207
+ date, // omit date from snapshot
208
+ ...headers
209
+ } ) => {
210
+ let data = '' ;
211
+ req . on ( 'data' , chunk => {
212
+ data += chunk ;
213
+ } ) ;
214
+ req . on ( 'end' , ( ) => {
215
+ resolve ( {
216
+ headers,
217
+ data,
218
+ } ) ;
219
+ } ) ;
220
+ }
221
+ ) ;
222
+ req . on ( 'error' , reject ) ;
223
+ } )
224
+ ) . resolves . toMatchInlineSnapshot ( `
225
+ {
226
+ "data": "Hey there!",
227
+ "headers": {
228
+ ":status": 418,
229
+ "content-type": "text/plain;charset=UTF-8",
230
+ "x-is-this-http2": "yes",
231
+ Symbol(nodejs.http2.sensitiveHeaders): [],
232
+ },
233
+ }
234
+ ` ) ;
235
+
236
+ req . end ( ) ;
237
+ client . close ( ) ;
238
+ server . close ( ) ;
239
+ } ) ;
116
240
} ) ;
117
241
118
242
function sleep ( ms : number ) {
0 commit comments