1
+ import net from 'node:net'
2
+ import path from 'node:path'
3
+ import { fileURLToPath } from 'node:url'
1
4
import fetch from 'node-fetch'
2
5
import {
3
6
afterEach ,
@@ -12,6 +15,8 @@ import WebSocket from 'ws'
12
15
import testJSON from '../safe.json'
13
16
import { browser , isServe , page , viteServer , viteTestUrl } from '~utils'
14
17
18
+ const __dirname = path . dirname ( fileURLToPath ( import . meta. url ) )
19
+
15
20
const getViteTestIndexHtmlUrl = ( ) => {
16
21
const srcPrefix = viteTestUrl . endsWith ( '/' ) ? '' : '/'
17
22
// NOTE: viteTestUrl is set lazily
@@ -391,3 +396,73 @@ describe('cross origin', () => {
391
396
)
392
397
} )
393
398
} )
399
+
400
+ describe . runIf ( isServe ) ( 'invalid request' , ( ) => {
401
+ const sendRawRequest = async ( baseUrl : string , requestTarget : string ) => {
402
+ return new Promise < string > ( ( resolve , reject ) => {
403
+ const parsedUrl = new URL ( baseUrl )
404
+
405
+ const buf : Buffer [ ] = [ ]
406
+ const client = net . createConnection (
407
+ { port : + parsedUrl . port , host : parsedUrl . hostname } ,
408
+ ( ) => {
409
+ client . write (
410
+ [
411
+ `GET ${ encodeURI ( requestTarget ) } HTTP/1.1` ,
412
+ `Host: ${ parsedUrl . host } ` ,
413
+ 'Connection: Close' ,
414
+ '\r\n' ,
415
+ ] . join ( '\r\n' ) ,
416
+ )
417
+ } ,
418
+ )
419
+ client . on ( 'data' , ( data ) => {
420
+ buf . push ( data )
421
+ } )
422
+ client . on ( 'end' , ( hadError ) => {
423
+ if ( ! hadError ) {
424
+ resolve ( Buffer . concat ( buf ) . toString ( ) )
425
+ }
426
+ } )
427
+ client . on ( 'error' , ( err ) => {
428
+ reject ( err )
429
+ } )
430
+ } )
431
+ }
432
+
433
+ const root = path
434
+ . resolve ( __dirname . replace ( 'playground' , 'playground-temp' ) , '..' )
435
+ . replace ( / \\ / g, '/' )
436
+
437
+ test ( 'request with sendRawRequest should work' , async ( ) => {
438
+ const response = await sendRawRequest ( viteTestUrl , '/src/safe.txt' )
439
+ expect ( response ) . toContain ( 'HTTP/1.1 200 OK' )
440
+ expect ( response ) . toContain ( 'KEY=safe' )
441
+ } )
442
+
443
+ test ( 'request with sendRawRequest should work with /@fs/' , async ( ) => {
444
+ const response = await sendRawRequest (
445
+ viteTestUrl ,
446
+ path . posix . join ( '/@fs/' , root , 'root/src/safe.txt' ) ,
447
+ )
448
+ expect ( response ) . toContain ( 'HTTP/1.1 200 OK' )
449
+ expect ( response ) . toContain ( 'KEY=safe' )
450
+ } )
451
+
452
+ test ( 'should reject request that has # in request-target' , async ( ) => {
453
+ const response = await sendRawRequest (
454
+ viteTestUrl ,
455
+ '/src/safe.txt#/../../unsafe.txt' ,
456
+ )
457
+ expect ( response ) . toContain ( 'HTTP/1.1 400 Bad Request' )
458
+ } )
459
+
460
+ test ( 'should reject request that has # in request-target with /@fs/' , async ( ) => {
461
+ const response = await sendRawRequest (
462
+ viteTestUrl ,
463
+ path . posix . join ( '/@fs/' , root , 'root/src/safe.txt' ) +
464
+ '#/../../unsafe.txt' ,
465
+ )
466
+ expect ( response ) . toContain ( 'HTTP/1.1 400 Bad Request' )
467
+ } )
468
+ } )
0 commit comments