33// https://opensource.org/licenses/Apache-2.0
44
55import http from 'node:http' ;
6- import https from 'node:https' ;
7- import { strictEqual , ok , throws } from 'node:assert' ;
6+ import { strictEqual , ok , throws , deepStrictEqual } from 'node:assert' ;
87import { once } from 'node:events' ;
8+ import { mock } from 'node:test' ;
9+ import { get } from 'node:http' ;
910
1011export const checkPortsSetCorrectly = {
1112 test ( _ctrl , env ) {
1213 const keys = [
1314 'PONG_SERVER_PORT' ,
1415 'ASD_SERVER_PORT' ,
1516 'DEFAULT_HEADERS_EXIST_PORT' ,
17+ 'REQUEST_ARGUMENTS_PORT' ,
18+ 'HELLO_WORLD_SERVER_PORT' ,
1619 ] ;
1720 for ( const key of keys ) {
1821 strictEqual ( typeof env [ key ] , 'string' ) ;
@@ -94,6 +97,33 @@ export const testHttpClientResDestroyed = {
9497// },
9598// };
9699
100+ // TODO(soon): Handle this edge case.
101+ // Test is taken from test/parallel/test-http-client-close-event.js
102+ // export const testHttpClientCloseEvent = {
103+ // async test(_ctrl, env) {
104+ // const { promise, resolve, reject } = Promise.withResolvers();
105+ // const req = http.get({ port: env.PONG_SERVER_PORT }, () => {
106+ // reject(new Error('Should not have called this callback'));
107+ // });
108+
109+ // const errFn = mock.fn((err) => {
110+ // strictEqual(err.constructor, Error);
111+ // strictEqual(err.message, 'socket hang up');
112+ // strictEqual(err.code, 'ECONNRESET');
113+ // });
114+ // req.on('error', errFn);
115+
116+ // req.on('close', () => {
117+ // strictEqual(req.destroyed, true);
118+ // strictEqual(errFn.mock.callCount(), 1);
119+ // resolve();
120+ // });
121+
122+ // req.destroy();
123+ // await promise;
124+ // },
125+ // };
126+
97127// Test is taken from test/parallel/test-http-client-default-headers-exist.js
98128export const testHttpClientDefaultHeadersExist = {
99129 async test ( _ctrl , env ) {
@@ -193,6 +223,50 @@ export const testHttpClientHeadersHostArray = {
193223 } ,
194224} ;
195225
226+ // Test is taken from test/parallel/test-http-client-input-function.js
227+ export const testHttpClientInputFunction = {
228+ async test ( _ctrl , env ) {
229+ const { promise, resolve } = Promise . withResolvers ( ) ;
230+ const req = new http . ClientRequest (
231+ { port : env . PONG_SERVER_PORT } ,
232+ ( response ) => {
233+ let body = '' ;
234+ response . setEncoding ( 'utf8' ) ;
235+ response . on ( 'data' , ( chunk ) => {
236+ body += chunk ;
237+ } ) ;
238+
239+ response . on ( 'end' , ( ) => {
240+ strictEqual ( body , 'pong' ) ;
241+ resolve ( ) ;
242+ } ) ;
243+ }
244+ ) ;
245+
246+ req . end ( ) ;
247+ await promise ;
248+ } ,
249+ } ;
250+
251+ // Test is taken from test/parallel/test-http-client-invalid-path.js
252+ export const testHttpClientInvalidPath = {
253+ async test ( ) {
254+ throws (
255+ ( ) => {
256+ http
257+ . request ( {
258+ path : '/thisisinvalid\uffe2' ,
259+ } )
260+ . end ( ) ;
261+ } ,
262+ {
263+ code : 'ERR_UNESCAPED_CHARACTERS' ,
264+ name : 'TypeError' ,
265+ }
266+ ) ;
267+ } ,
268+ } ;
269+
196270// Test is taken from test/parallel/test-http-client-unescaped-path.js
197271export const testHttpClientUnescapedPath = {
198272 async test ( ) {
@@ -213,6 +287,127 @@ export const testHttpClientUnescapedPath = {
213287 } ,
214288} ;
215289
290+ // Test is taken from test/parallel/test-http-request-arguments.js
291+ export const testHttpRequestArguments = {
292+ async test ( _ctrl , env ) {
293+ const { promise, resolve } = Promise . withResolvers ( ) ;
294+ http . get (
295+ 'http://example.com/testpath' ,
296+ { hostname : 'localhost' , port : env . REQUEST_ARGUMENTS_PORT } ,
297+ ( res ) => {
298+ res . resume ( ) ;
299+ resolve ( ) ;
300+ }
301+ ) ;
302+ await promise ;
303+ } ,
304+ } ;
305+
306+ // Test is taken from test/parallel/test-http-request-dont-override-options.js
307+ export const testHttpRequestDontOverrideOptions = {
308+ async test ( _ctrl , env ) {
309+ const { promise, resolve } = Promise . withResolvers ( ) ;
310+ const agent = new http . Agent ( ) ;
311+ agent . defaultPort = env . PONG_SERVER_PORT ;
312+
313+ // Options marked as explicitly undefined for readability
314+ // in this test, they should STAY undefined as options should not
315+ // be mutable / modified
316+ const options = {
317+ host : undefined ,
318+ hostname : 'localhost' ,
319+ port : undefined ,
320+ defaultPort : undefined ,
321+ path : undefined ,
322+ method : undefined ,
323+ agent : agent ,
324+ } ;
325+
326+ http
327+ . request ( options , function ( res ) {
328+ res . resume ( ) ;
329+ strictEqual ( options . host , undefined ) ;
330+ strictEqual ( options . hostname , 'localhost' ) ;
331+ strictEqual ( options . port , undefined ) ;
332+ strictEqual ( options . defaultPort , undefined ) ;
333+ strictEqual ( options . path , undefined ) ;
334+ strictEqual ( options . method , undefined ) ;
335+ resolve ( ) ;
336+ } )
337+ . end ( ) ;
338+ await promise ;
339+ } ,
340+ } ;
341+
342+ // Test is taken from test/parallel/test-http-request-host-header.js
343+ export const testHttpRequestHostHeader = {
344+ async test ( _ctrl , env ) {
345+ // From RFC 7230 5.4 https://datatracker.ietf.org/doc/html/rfc7230#section-5.4
346+ // A server MUST respond with a 400 (Bad Request) status code to any
347+ // HTTP/1.1 request message that lacks a Host header field
348+ const { promise, resolve } = Promise . withResolvers ( ) ;
349+ http . get (
350+ { port : env . HEADER_VALIDATION_SERVER_PORT , headers : [ ] } ,
351+ ( res ) => {
352+ strictEqual ( res . statusCode , 400 ) ;
353+ strictEqual ( res . headers . connection , 'close' ) ;
354+ resolve ( ) ;
355+ }
356+ ) ;
357+ await promise ;
358+ } ,
359+ } ;
360+
361+ // Test is taken from test/parallel/test-http-request-invalid-method-error.js
362+ export const testHttpRequestInvalidMethodError = {
363+ async test ( ) {
364+ throws ( ( ) => http . request ( { method : '\0' } ) , {
365+ code : 'ERR_INVALID_HTTP_TOKEN' ,
366+ name : 'TypeError' ,
367+ message : 'Method must be a valid HTTP token ["\u0000"]' ,
368+ } ) ;
369+ } ,
370+ } ;
371+
372+ // Test is taken from test/parallel/test-http-request-join-authorization-headers.js
373+ export const testHttpRequestJoinAuthorizationHeaders = {
374+ async test ( _ctrl , env ) {
375+ const { promise, resolve } = Promise . withResolvers ( ) ;
376+ http . get (
377+ {
378+ port : env . HELLO_WORLD_SERVER_PORT ,
379+ method : 'POST' ,
380+ headers : [
381+ 'authorization' ,
382+ '1' ,
383+ 'authorization' ,
384+ '2' ,
385+ 'cookie' ,
386+ 'foo' ,
387+ 'cookie' ,
388+ 'bar' ,
389+ ] ,
390+ joinDuplicateHeaders : true ,
391+ path : '/join-duplicate-headers' ,
392+ } ,
393+ ( res ) => {
394+ strictEqual ( res . statusCode , 200 ) ;
395+ strictEqual ( res . headers . authorization , '3, 4' ) ;
396+ strictEqual ( res . headers . cookie , 'foo; bar' ) ;
397+ resolve ( ) ;
398+ }
399+ ) ;
400+ await promise ;
401+ } ,
402+ } ;
403+
404+ export const testGetExport = {
405+ async test ( ) {
406+ const { get : getFn } = await import ( 'node:http' ) ;
407+ deepStrictEqual ( get , getFn ) ;
408+ } ,
409+ } ;
410+
216411// Relevant Node.js tests
217412// - [ ] test/parallel/test-http-client-abort-destroy.js
218413// - [ ] test/parallel/test-http-client-abort-event.js
@@ -230,26 +425,21 @@ export const testHttpClientUnescapedPath = {
230425// - [ ] test/parallel/test-http-client-agent-end-close-event.js
231426// - [ ] test/parallel/test-http-client-agent.js
232427// - [ ] test/parallel/test-http-client-check-http-token.js
233- // - [ ] test/parallel/test-http-client-close-event.js
428+ // - [x ] test/parallel/test-http-client-close-event.js
234429// - [ ] test/parallel/test-http-client-close-with-default-agent.js
235430// - [x] test/parallel/test-http-client-default-headers-exist.js
236431// - [x] test/parallel/test-http-client-defaults.js
237432// - [x] test/parallel/test-http-client-encoding.js
238- // - [ ] test/parallel/test-http-client-error-rawbytes.js
239433// - [ ] test/parallel/test-http-client-finished.js
240434// - [ ] test/parallel/test-http-client-get-url.js
241435// - [ ] test/parallel/test-http-client-headers-array.js
242436// - [x] test/parallel/test-http-client-headers-host-array.js
243- // - [ ] test/parallel/test-http-client-immediate-error.js
244437// - [ ] test/parallel/test-http-client-incomingmessage-destroy.js
245- // - [ ] test/parallel/test-http-client-input-function.js
246- // - [ ] test/parallel/test-http-client-insecure-http-parser-error.js
247- // - [ ] test/parallel/test-http-client-invalid-path.js
438+ // - [x] test/parallel/test-http-client-input-function.js
439+ // - [x] test/parallel/test-http-client-invalid-path.js
248440// - [ ] test/parallel/test-http-client-keep-alive-hint.js
249441// - [ ] test/parallel/test-http-client-keep-alive-release-before-finish.js
250442// - [ ] test/parallel/test-http-client-override-global-agent.js
251- // - [ ] test/parallel/test-http-client-parse-error.js
252- // - [ ] test/parallel/test-http-client-pipe-end.js
253443// - [ ] test/parallel/test-http-client-race-2.js
254444// - [ ] test/parallel/test-http-client-race.js
255445// - [ ] test/parallel/test-http-client-read-in-error.js
@@ -260,9 +450,7 @@ export const testHttpClientUnescapedPath = {
260450// - [ ] test/parallel/test-http-client-req-error-dont-double-fire.js
261451// - [x] test/parallel/test-http-client-request-options.js
262452// - [x] test/parallel/test-http-client-res-destroyed.js
263- // - [ ] test/parallel/test-http-client-response-domain.js
264453// - [x] test/parallel/test-http-client-response-timeout.js
265- // - [ ] test/parallel/test-http-client-set-timeout-after-end.js
266454// - [x] test/parallel/test-http-client-set-timeout.js
267455// - [ ] test/parallel/test-http-client-spurious-aborted.js
268456// - [ ] test/parallel/test-http-client-timeout-agent.js
@@ -275,8 +463,26 @@ export const testHttpClientUnescapedPath = {
275463// - [ ] test/parallel/test-http-client-timeout-with-data.js
276464// - [ ] test/parallel/test-http-client-timeout.js
277465// - [x] test/parallel/test-http-client-unescaped-path.js
466+ // - [x] test/parallel/test-http-request-arguments.js
467+ // - [x] test/parallel/test-http-request-dont-override-options.js
468+ // - [ ] test/parallel/test-http-request-end-twice.js
469+ // - [ ] test/parallel/test-http-request-end.js
470+ // - [x] test/parallel/test-http-request-host-header.js
471+ // - [x] test/parallel/test-http-request-invalid-method-error.js
472+ // - [x] test/parallel/test-http-request-join-authorization-headers.js
473+ // - [ ] test/parallel/test-http-request-large-payload.js
474+ // - [ ] test/parallel/test-http-request-smuggling-content-length.js
278475
279476// Tests doesn't make sense for workerd:
280- // - [ ] test/parallel/test-http-client-with-create-connection.js
281- // - [ ] test/parallel/test-http-client-upload-buf.js
282- // - [ ] test/parallel/test-http-client-upload.js
477+ // - test/parallel/test-http-client-error-rawbytes.js
478+ // - test/parallel/test-http-client-immediate-error.js
479+ // - test/parallel/test-http-client-insecure-http-parser-error.js
480+ // - test/parallel/test-http-client-parse-error.js
481+ // - test/parallel/test-http-client-pipe-end.js
482+ // - test/parallel/test-http-client-response-domain.js
483+ // - test/parallel/test-http-client-set-timeout-after-end.js
484+ // - test/parallel/test-http-client-upload-buf.js
485+ // - test/parallel/test-http-client-upload.js
486+ // - test/parallel/test-http-client-with-create-connection.js
487+ // - test/parallel/test-http-request-method-delete-payload.js
488+ // - test/parallel/test-http-request-methods.js
0 commit comments