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
@@ -392,3 +397,73 @@ describe('cross origin', () => {
392
397
)
393
398
} )
394
399
} )
400
+
401
+ describe . runIf ( isServe ) ( 'invalid request' , ( ) => {
402
+ const sendRawRequest = async ( baseUrl : string , requestTarget : string ) => {
403
+ return new Promise < string > ( ( resolve , reject ) => {
404
+ const parsedUrl = new URL ( baseUrl )
405
+
406
+ const buf : Buffer [ ] = [ ]
407
+ const client = net . createConnection (
408
+ { port : + parsedUrl . port , host : parsedUrl . hostname } ,
409
+ ( ) => {
410
+ client . write (
411
+ [
412
+ `GET ${ encodeURI ( requestTarget ) } HTTP/1.1` ,
413
+ `Host: ${ parsedUrl . host } ` ,
414
+ 'Connection: Close' ,
415
+ '\r\n' ,
416
+ ] . join ( '\r\n' ) ,
417
+ )
418
+ } ,
419
+ )
420
+ client . on ( 'data' , ( data ) => {
421
+ buf . push ( data )
422
+ } )
423
+ client . on ( 'end' , ( hadError ) => {
424
+ if ( ! hadError ) {
425
+ resolve ( Buffer . concat ( buf ) . toString ( ) )
426
+ }
427
+ } )
428
+ client . on ( 'error' , ( err ) => {
429
+ reject ( err )
430
+ } )
431
+ } )
432
+ }
433
+
434
+ const root = path
435
+ . resolve ( __dirname . replace ( 'playground' , 'playground-temp' ) , '..' )
436
+ . replace ( / \\ / g, '/' )
437
+
438
+ test ( 'request with sendRawRequest should work' , async ( ) => {
439
+ const response = await sendRawRequest ( viteTestUrl , '/src/safe.txt' )
440
+ expect ( response ) . toContain ( 'HTTP/1.1 200 OK' )
441
+ expect ( response ) . toContain ( 'KEY=safe' )
442
+ } )
443
+
444
+ test ( 'request with sendRawRequest should work with /@fs/' , async ( ) => {
445
+ const response = await sendRawRequest (
446
+ viteTestUrl ,
447
+ path . posix . join ( '/@fs/' , root , 'root/src/safe.txt' ) ,
448
+ )
449
+ expect ( response ) . toContain ( 'HTTP/1.1 200 OK' )
450
+ expect ( response ) . toContain ( 'KEY=safe' )
451
+ } )
452
+
453
+ test ( 'should reject request that has # in request-target' , async ( ) => {
454
+ const response = await sendRawRequest (
455
+ viteTestUrl ,
456
+ '/src/safe.txt#/../../unsafe.txt' ,
457
+ )
458
+ expect ( response ) . toContain ( 'HTTP/1.1 400 Bad Request' )
459
+ } )
460
+
461
+ test ( 'should reject request that has # in request-target with /@fs/' , async ( ) => {
462
+ const response = await sendRawRequest (
463
+ viteTestUrl ,
464
+ path . posix . join ( '/@fs/' , root , 'root/src/safe.txt' ) +
465
+ '#/../../unsafe.txt' ,
466
+ )
467
+ expect ( response ) . toContain ( 'HTTP/1.1 400 Bad Request' )
468
+ } )
469
+ } )
0 commit comments