@@ -1483,13 +1483,80 @@ tfw_http_nip_req_resched_err(TfwSrvConn *srv_conn, TfwHttpReq *req,
1483
1483
" re-forwarded or re-scheduled" );
1484
1484
}
1485
1485
1486
- static inline void
1487
- tfw_http_send_err_resp_nolog (TfwHttpReq * req , int status )
1486
+ /**
1487
+ * The request is serviced from cache.
1488
+ * Send the response as is and unrefer its data.
1489
+ */
1490
+ static void
1491
+ tfw_http_req_cache_service (TfwHttpResp * resp )
1488
1492
{
1493
+ TfwHttpReq * req = resp -> req ;
1494
+
1495
+ WARN_ON_ONCE (!list_empty (& req -> fwd_list ));
1496
+ WARN_ON_ONCE (!list_empty (& req -> nip_list ));
1497
+
1489
1498
if (TFW_MSG_H2 (req ))
1490
- tfw_h2_send_err_resp ( req , status , false );
1499
+ tfw_h2_resp_fwd ( resp );
1491
1500
else
1492
- tfw_h1_send_err_resp (req , status );
1501
+ tfw_http_resp_fwd (resp );
1502
+
1503
+ TFW_INC_STAT_BH (clnt .msgs_fromcache );
1504
+ }
1505
+
1506
+ /**
1507
+ * Build stale response from the @req->stale_ce and link request with response.
1508
+ * Forward response to client, free previous unsuccessful response from upstream
1509
+ * @hmresp.
1510
+ *
1511
+ * @return true if response successfully forwarded otherwise false.
1512
+ */
1513
+ static bool
1514
+ __tfw_http_resp_fwd_stale (TfwHttpMsg * hmresp )
1515
+ {
1516
+ TfwHttpReq * req = hmresp -> req ;
1517
+ TfwHttpResp * stale_resp ;
1518
+ bool sent = false;
1519
+
1520
+ tfw_stream_unlink_msg (hmresp -> stream );
1521
+ /* Unlink response. */
1522
+ req -> resp = NULL ;
1523
+
1524
+ stale_resp = tfw_cache_build_resp_stale (req );
1525
+ /* For HTTP2 response will not be built if stream already closed. */
1526
+ if (!stale_resp )
1527
+ goto free ;
1528
+
1529
+ req -> resp -> conn = hmresp -> conn ;
1530
+ hmresp -> pair = NULL ;
1531
+
1532
+ if (TFW_MSG_H2 (req ))
1533
+ tfw_h2_req_unlink_stream (req );
1534
+
1535
+ tfw_http_req_cache_service (req -> resp );
1536
+ sent = true;
1537
+
1538
+ free :
1539
+ tfw_http_msg_free (hmresp );
1540
+
1541
+ return sent ;
1542
+ }
1543
+
1544
+ /**
1545
+ * The same as @__tfw_http_resp_fwd_stale(), but used in case when we don't
1546
+ * have response from upstream.
1547
+ */
1548
+ static bool
1549
+ __tfw_http_resp_fwd_stale_noresp (TfwHttpReq * req )
1550
+ {
1551
+ if (!tfw_cache_build_resp_stale (req ))
1552
+ return false;
1553
+
1554
+ if (TFW_MSG_H2 (req ))
1555
+ tfw_h2_req_unlink_stream (req );
1556
+
1557
+ tfw_http_req_cache_service (req -> resp );
1558
+
1559
+ return true;
1493
1560
}
1494
1561
1495
1562
static bool
@@ -1511,9 +1578,8 @@ static bool
1511
1578
tfw_http_resp_should_fwd_stale (TfwHttpReq * req , unsigned short status )
1512
1579
{
1513
1580
TfwCacheUseStale * stale_opt ;
1514
- TfwHttpResp * resp = req -> stale_resp ;
1515
1581
1516
- if (!resp )
1582
+ if (!req -> stale_ce )
1517
1583
return false;
1518
1584
1519
1585
stale_opt = tfw_vhost_get_cache_use_stale (req -> location , req -> vhost );
@@ -1536,29 +1602,21 @@ tfw_http_resp_should_fwd_stale(TfwHttpReq *req, unsigned short status)
1536
1602
* from cache. Therefore we response with inaccurate age or even
1537
1603
* with violation of max-stale param.
1538
1604
*/
1539
- return (resp -> cache_ctl .flags & TFW_HTTP_CC_STALE_IF_ERROR ||
1540
- req -> cache_ctl .flags & TFW_HTTP_CC_STALE_IF_ERROR ) &&
1541
- tfw_http_use_stale_if_error (status );
1605
+ return tfw_http_use_stale_if_error (status );
1542
1606
}
1543
1607
1544
- /**
1545
- * The request is serviced from cache.
1546
- * Send the response as is and unrefer its data.
1547
- */
1548
- static void
1549
- tfw_http_req_cache_service (TfwHttpResp * resp )
1608
+ static inline void
1609
+ tfw_http_send_err_resp_nolog (TfwHttpReq * req , int status )
1550
1610
{
1551
- TfwHttpReq * req = resp -> req ;
1552
-
1553
- WARN_ON_ONCE (!list_empty (& req -> fwd_list ));
1554
- WARN_ON_ONCE (!list_empty (& req -> nip_list ));
1555
-
1556
- if (TFW_MSG_H2 (req ))
1557
- tfw_h2_resp_fwd (resp );
1558
- else
1559
- tfw_http_resp_fwd (resp );
1560
-
1561
- TFW_INC_STAT_BH (clnt .msgs_fromcache );
1611
+ /* Response must be freed before calling tfw_http_send_err_resp_nolog(). */
1612
+ if (tfw_http_resp_should_fwd_stale (req , status )) {
1613
+ __tfw_http_resp_fwd_stale_noresp (req );
1614
+ } else {
1615
+ if (TFW_MSG_H2 (req ))
1616
+ tfw_h2_send_err_resp (req , status , false);
1617
+ else
1618
+ tfw_h1_send_err_resp (req , status );
1619
+ }
1562
1620
}
1563
1621
1564
1622
/* Common interface for sending error responses. */
@@ -1569,16 +1627,7 @@ tfw_http_send_err_resp(TfwHttpReq *req, int status, const char *reason)
1569
1627
T_WARN_ADDR_STATUS (reason , & req -> conn -> peer -> addr ,
1570
1628
TFW_NO_PORT , status );
1571
1629
1572
- /* Response must be freed before calling tfw_http_send_err_resp(). */
1573
- if (tfw_http_resp_should_fwd_stale (req , status )) {
1574
- req -> resp = req -> stale_resp ;
1575
- req -> stale_resp = NULL ;
1576
- if (TFW_MSG_H2 (req ))
1577
- tfw_h2_req_unlink_stream (req );
1578
- tfw_http_req_cache_service (req -> resp );
1579
- } else {
1580
- tfw_http_send_err_resp_nolog (req , status );
1581
- }
1630
+ tfw_http_send_err_resp_nolog (req , status );
1582
1631
}
1583
1632
1584
1633
static void
@@ -2647,8 +2696,8 @@ tfw_http_req_destruct(void *msg)
2647
2696
if (req -> old_head )
2648
2697
ss_skb_queue_purge (& req -> old_head );
2649
2698
2650
- if (req -> stale_resp )
2651
- tfw_http_msg_free (( TfwHttpMsg * ) req -> stale_resp );
2699
+ if (req -> stale_ce )
2700
+ tfw_cache_put_entry ( req -> stale_ce );
2652
2701
}
2653
2702
2654
2703
/**
@@ -6658,25 +6707,6 @@ tfw_http_resp_terminate(TfwHttpMsg *hm)
6658
6707
tfw_http_resp_cache (hm );
6659
6708
}
6660
6709
6661
- static void
6662
- __tfw_http_resp_fwd_stale (TfwHttpMsg * hmresp )
6663
- {
6664
- TfwHttpReq * req = hmresp -> req ;
6665
-
6666
- tfw_stream_unlink_msg (hmresp -> stream );
6667
- req -> resp = req -> stale_resp ;
6668
- req -> stale_resp = NULL ;
6669
- req -> resp -> conn = hmresp -> conn ;
6670
- hmresp -> pair = NULL ;
6671
-
6672
- if (TFW_MSG_H2 (req ))
6673
- tfw_h2_req_unlink_stream (req );
6674
-
6675
- tfw_http_req_cache_service (req -> resp );
6676
-
6677
- tfw_http_msg_free (hmresp );
6678
- }
6679
-
6680
6710
static int
6681
6711
tfw_http_resp_fwd_stale (TfwHttpMsg * hmresp )
6682
6712
{
@@ -6711,7 +6741,8 @@ tfw_http_resp_fwd_stale(TfwHttpMsg *hmresp)
6711
6741
return T_BLOCK ;
6712
6742
}
6713
6743
6714
- __tfw_http_resp_fwd_stale (hmresp );
6744
+ if (!__tfw_http_resp_fwd_stale (hmresp ))
6745
+ return T_BAD ;
6715
6746
6716
6747
return T_OK ;
6717
6748
}
@@ -6949,6 +6980,7 @@ tfw_http_resp_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb,
6949
6980
if (unlikely (r != T_OK )) {
6950
6981
if (hmsib )
6951
6982
tfw_http_conn_msg_free (hmsib );
6983
+ return r ;
6952
6984
}
6953
6985
6954
6986
* split = NULL ;
@@ -6998,7 +7030,7 @@ tfw_http_resp_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb,
6998
7030
__tfw_http_resp_fwd_stale (hmresp );
6999
7031
/*
7000
7032
* Close connection with backend immediately
7001
- * and try to reastablish it later.
7033
+ * and try to re-establish it later.
7002
7034
*/
7003
7035
r = T_BAD ;
7004
7036
} else {
@@ -7013,7 +7045,7 @@ tfw_http_resp_process(TfwConn *conn, TfwStream *stream, struct sk_buff *skb,
7013
7045
HTTP2_ECODE_PROTO );
7014
7046
/*
7015
7047
* Close connection with backend immediately
7016
- * and try to reastablish it later.
7048
+ * and try to re-establish it later.
7017
7049
*/
7018
7050
r = T_BAD ;
7019
7051
}
0 commit comments