@@ -1437,8 +1437,11 @@ describe('Cache Interceptor', () => {
1437
1437
} )
1438
1438
} )
1439
1439
1440
+ // Partial list.
1440
1441
const cacheableStatusCodes = [
1441
1442
{ code : 204 , body : '' } ,
1443
+ { code : 302 , body : 'Found' } ,
1444
+ { code : 307 , body : 'Temporary Redirect' } ,
1442
1445
{ code : 404 , body : 'Not Found' } ,
1443
1446
{ code : 410 , body : 'Gone' }
1444
1447
]
@@ -1489,13 +1492,71 @@ describe('Cache Interceptor', () => {
1489
1492
} )
1490
1493
}
1491
1494
1492
- test ( 'does not cache non-heuristically cacheable error status codes' , async ( ) => {
1495
+ // Partial list.
1496
+ const nonHeuristicallyCacheableStatusCodes = [
1497
+ { code : 201 , body : 'Created' } ,
1498
+ { code : 307 , body : 'Temporary Redirect' } ,
1499
+ { code : 418 , body : 'I am a teapot' }
1500
+ ]
1501
+
1502
+ for ( const { code, body } of nonHeuristicallyCacheableStatusCodes ) {
1503
+ test ( `does not cache non-heuristically cacheable status ${ code } without explicit directive` , async ( ) => {
1504
+ let requestsToOrigin = 0
1505
+ const server = createServer ( { joinDuplicateHeaders : true } , ( _ , res ) => {
1506
+ requestsToOrigin ++
1507
+ res . statusCode = code
1508
+ // By default the response may have a date and last-modified header set to 'now',
1509
+ // causing the cache to compute a 0 heuristic expiry, causing the test to not ascertain
1510
+ // it is really not cached.
1511
+ res . setHeader ( 'date' , '' )
1512
+ res . end ( body )
1513
+ } ) . listen ( 0 )
1514
+
1515
+ const client = new Client ( `http://localhost:${ server . address ( ) . port } ` )
1516
+ . compose ( interceptors . cache ( { cacheByDefault : 60 } ) )
1517
+
1518
+ after ( async ( ) => {
1519
+ server . close ( )
1520
+ await client . close ( )
1521
+ } )
1522
+
1523
+ await once ( server , 'listening' )
1524
+
1525
+ equal ( requestsToOrigin , 0 )
1526
+
1527
+ const request = {
1528
+ origin : 'localhost' ,
1529
+ method : 'GET' ,
1530
+ path : '/'
1531
+ }
1532
+
1533
+ // First request should hit the origin
1534
+ {
1535
+ const res = await client . request ( request )
1536
+ equal ( requestsToOrigin , 1 )
1537
+ equal ( res . statusCode , code )
1538
+ strictEqual ( await res . body . text ( ) , body )
1539
+ }
1540
+
1541
+ // Second request should also hit the origin (not cached)
1542
+ {
1543
+ const res = await client . request ( request )
1544
+ equal ( requestsToOrigin , 2 ) // Should be 2 (not cached)
1545
+ equal ( res . statusCode , code )
1546
+ strictEqual ( await res . body . text ( ) , body )
1547
+ }
1548
+ } )
1549
+ }
1550
+
1551
+ test ( 'discriminates caching of range requests, or does not cache them' , async ( ) => {
1493
1552
let requestsToOrigin = 0
1553
+ const body = 'Fake range request response'
1554
+ const code = 206
1494
1555
const server = createServer ( { joinDuplicateHeaders : true } , ( _ , res ) => {
1495
1556
requestsToOrigin ++
1496
- res . statusCode = 418 // I'm a teapot - not in heuristically cacheable list
1557
+ res . statusCode = code
1497
1558
res . setHeader ( 'cache-control' , 'public, max-age=60' )
1498
- res . end ( 'I am a teapot' )
1559
+ res . end ( body )
1499
1560
} ) . listen ( 0 )
1500
1561
1501
1562
const client = new Client ( `http://localhost:${ server . address ( ) . port } ` )
@@ -1513,23 +1574,127 @@ describe('Cache Interceptor', () => {
1513
1574
const request = {
1514
1575
origin : 'localhost' ,
1515
1576
method : 'GET' ,
1516
- path : '/'
1577
+ path : '/' ,
1578
+ headers : {
1579
+ range : 'bytes=10-'
1580
+ }
1517
1581
}
1518
1582
1519
1583
// First request should hit the origin
1520
1584
{
1521
1585
const res = await client . request ( request )
1522
1586
equal ( requestsToOrigin , 1 )
1523
- equal ( res . statusCode , 418 )
1524
- strictEqual ( await res . body . text ( ) , 'I am a teapot' )
1587
+ equal ( res . statusCode , code )
1588
+ strictEqual ( await res . body . text ( ) , body )
1525
1589
}
1526
1590
1527
- // Second request should also hit the origin (not cached)
1591
+ // Second request with different range should hit the origin too
1592
+ request . headers . range = 'bytes=5-'
1528
1593
{
1529
1594
const res = await client . request ( request )
1530
- equal ( requestsToOrigin , 2 ) // Should be 2 (not cached)
1531
- equal ( res . statusCode , 418 )
1532
- strictEqual ( await res . body . text ( ) , 'I am a teapot' )
1595
+ equal ( requestsToOrigin , 2 )
1596
+ equal ( res . statusCode , code )
1597
+ strictEqual ( await res . body . text ( ) , body )
1598
+ }
1599
+ } )
1600
+
1601
+ test ( 'discriminates caching of conditionnal requests (if-none-match), or does not cache them' , async ( ) => {
1602
+ let requestsToOrigin = 0
1603
+ const body = ''
1604
+ const code = 304
1605
+ const server = createServer ( { joinDuplicateHeaders : true } , ( _ , res ) => {
1606
+ requestsToOrigin ++
1607
+ res . statusCode = code
1608
+ res . setHeader ( 'cache-control' , 'public, max-age=60' )
1609
+ res . end ( body )
1610
+ } ) . listen ( 0 )
1611
+
1612
+ const client = new Client ( `http://localhost:${ server . address ( ) . port } ` )
1613
+ . compose ( interceptors . cache ( ) )
1614
+
1615
+ after ( async ( ) => {
1616
+ server . close ( )
1617
+ await client . close ( )
1618
+ } )
1619
+
1620
+ await once ( server , 'listening' )
1621
+
1622
+ equal ( requestsToOrigin , 0 )
1623
+
1624
+ const request = {
1625
+ origin : 'localhost' ,
1626
+ method : 'GET' ,
1627
+ path : '/' ,
1628
+ headers : {
1629
+ 'if-none-match' : 'some-etag'
1630
+ }
1631
+ }
1632
+
1633
+ // First request should hit the origin
1634
+ {
1635
+ const res = await client . request ( request )
1636
+ equal ( requestsToOrigin , 1 )
1637
+ equal ( res . statusCode , code )
1638
+ strictEqual ( await res . body . text ( ) , body )
1639
+ }
1640
+
1641
+ // Second request with different etag should hit the origin too
1642
+ request . headers [ 'if-none-match' ] = 'another-etag'
1643
+ {
1644
+ const res = await client . request ( request )
1645
+ equal ( requestsToOrigin , 2 )
1646
+ equal ( res . statusCode , code )
1647
+ strictEqual ( await res . body . text ( ) , body )
1648
+ }
1649
+ } )
1650
+
1651
+ test ( 'discriminates caching of conditionnal requests (if-modified-since), or does not cache them' , async ( ) => {
1652
+ let requestsToOrigin = 0
1653
+ const body = ''
1654
+ const code = 304
1655
+ const server = createServer ( { joinDuplicateHeaders : true } , ( _ , res ) => {
1656
+ requestsToOrigin ++
1657
+ res . statusCode = code
1658
+ res . setHeader ( 'cache-control' , 'public, max-age=60' )
1659
+ res . end ( body )
1660
+ } ) . listen ( 0 )
1661
+
1662
+ const client = new Client ( `http://localhost:${ server . address ( ) . port } ` )
1663
+ . compose ( interceptors . cache ( ) )
1664
+
1665
+ after ( async ( ) => {
1666
+ server . close ( )
1667
+ await client . close ( )
1668
+ } )
1669
+
1670
+ await once ( server , 'listening' )
1671
+
1672
+ equal ( requestsToOrigin , 0 )
1673
+
1674
+ const request = {
1675
+ origin : 'localhost' ,
1676
+ method : 'GET' ,
1677
+ path : '/' ,
1678
+ headers : {
1679
+ 'if-modified-since' : new Date ( ) . toUTCString ( )
1680
+ }
1681
+ }
1682
+
1683
+ // First request should hit the origin
1684
+ {
1685
+ const res = await client . request ( request )
1686
+ equal ( requestsToOrigin , 1 )
1687
+ equal ( res . statusCode , code )
1688
+ strictEqual ( await res . body . text ( ) , body )
1689
+ }
1690
+
1691
+ // Second request with different since should hit the origin too
1692
+ request . headers [ 'if-modified-since' ] = new Date ( 0 ) . toUTCString ( )
1693
+ {
1694
+ const res = await client . request ( request )
1695
+ equal ( requestsToOrigin , 2 )
1696
+ equal ( res . statusCode , code )
1697
+ strictEqual ( await res . body . text ( ) , body )
1533
1698
}
1534
1699
} )
1535
1700
} )
0 commit comments