Skip to content

Commit 85be282

Browse files
serrislewSerris Lew
andauthored
Serve stale content when DNS lookup fails (#8484)
* serve stale when dns lookups fails * updated max-age in autest to run shorter Co-authored-by: Serris Lew <lserris@apple.com>
1 parent 4af0b77 commit 85be282

File tree

3 files changed

+144
-10
lines changed

3 files changed

+144
-10
lines changed

proxy/http/HttpTransact.cc

Lines changed: 8 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1942,6 +1942,13 @@ HttpTransact::OSDNSLookup(State *s)
19421942
} else {
19431943
TxnDebug("http_seq", "[HttpTransact::OSDNSLookup] DNS Lookup unsuccessful");
19441944

1945+
// Even with unsuccessful DNS lookup, return stale object from cache if applicable
1946+
if (is_cache_hit(s->cache_lookup_result) && is_stale_cache_response_returnable(s)) {
1947+
s->source = SOURCE_CACHE;
1948+
TxnDebug("http_trans", "[hscno] serving stale doc to client");
1949+
build_response_from_cache(s, HTTP_WARNING_CODE_REVALIDATION_FAILED);
1950+
return;
1951+
}
19451952
// output the DNS failure error message
19461953
SET_VIA_STRING(VIA_DETAIL_TUNNEL, VIA_DETAIL_TUNNEL_NO_FORWARD);
19471954
// Set to internal server error so later logging will pick up SQUID_LOG_ERR_DNS_FAIL
@@ -2642,16 +2649,7 @@ HttpTransact::HandleCacheOpenReadHitFreshness(State *s)
26422649
SET_VIA_STRING(VIA_CACHE_RESULT, VIA_IN_CACHE_STALE);
26432650
}
26442651

2645-
if (!s->force_dns) { // If DNS is not performed before
2646-
if (need_to_revalidate(s)) {
2647-
TRANSACT_RETURN(SM_ACTION_API_CACHE_LOOKUP_COMPLETE,
2648-
CallOSDNSLookup); // content needs to be revalidated and we did not perform a dns ....calling DNS lookup
2649-
} else { // document can be served can cache
2650-
TRANSACT_RETURN(SM_ACTION_API_CACHE_LOOKUP_COMPLETE, HttpTransact::HandleCacheOpenReadHit);
2651-
}
2652-
} else { // we have done dns . Its up to HandleCacheOpenReadHit to decide to go OS or serve from cache
2653-
TRANSACT_RETURN(SM_ACTION_API_CACHE_LOOKUP_COMPLETE, HttpTransact::HandleCacheOpenReadHit);
2654-
}
2652+
TRANSACT_RETURN(SM_ACTION_API_CACHE_LOOKUP_COMPLETE, HttpTransact::HandleCacheOpenReadHit);
26552653
}
26562654

26572655
///////////////////////////////////////////////////////////////////////////////
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
``
2+
> GET / HTTP/1.1
3+
> Host: ``
4+
> User-Agent: curl/``
5+
> Accept: */*
6+
``
7+
< HTTP/1.1 200 OK
8+
< Server: ATS``
9+
< Accept-Ranges: bytes
10+
< Content-Length: 6
11+
< Cache-Control: public, max-age=5
12+
< Expires: ``
13+
< Age: ``
14+
< Date: ``
15+
< Connection: keep-alive
16+
``
17+
> GET / HTTP/1.1
18+
> Host: ``
19+
> User-Agent: curl/``
20+
> Accept: */*
21+
``
22+
< HTTP/1.1 500 Cannot find server.
23+
< Date: ``
24+
< Server: ATS``
25+
< Cache-Control: no-store
26+
< Content-Type: ``
27+
< Content-Language: ``
28+
< Content-Length: ``
29+
< Connection: keep-alive
30+
``
31+
> GET / HTTP/1.1
32+
> Host: ``
33+
> User-Agent: curl/``
34+
> Accept: */*
35+
``
36+
< HTTP/1.1 200 OK
37+
< Server: ATS``
38+
< Accept-Ranges: bytes
39+
< Content-Length: 6
40+
< Cache-Control: public, max-age=5
41+
< Age: ``
42+
< Date: ``
43+
< Connection: keep-alive
44+
``
45+
> GET / HTTP/1.1
46+
> Host: ``
47+
> User-Agent: curl/``
48+
> Accept: */*
49+
``
50+
< HTTP/1.1 500 Cannot find server.
51+
< Date: ``
52+
< Server: ATS``
53+
< Cache-Control: no-store
54+
< Content-Type: ``
55+
< Content-Language: ``
56+
< Content-Length: ``
57+
``
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
'''
2+
Test proxy serving stale content when DNS lookup fails
3+
'''
4+
# Licensed to the Apache Software Foundation (ASF) under one
5+
# or more contributor license agreements. See the NOTICE file
6+
# distributed with this work for additional information
7+
# regarding copyright ownership. The ASF licenses this file
8+
# to you under the Apache License, Version 2.0 (the
9+
# "License"); you may not use this file except in compliance
10+
# with the License. You may obtain a copy of the License at
11+
#
12+
# http://www.apache.org/licenses/LICENSE-2.0
13+
#
14+
# Unless required by applicable law or agreed to in writing, software
15+
# distributed under the License is distributed on an "AS IS" BASIS,
16+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17+
# See the License for the specific language governing permissions and
18+
# limitations under the License.
19+
20+
Test.ContinueOnFail = True
21+
# Set up hierarchical caching processes
22+
ts_child = Test.MakeATSProcess("ts_child")
23+
ts_parent = Test.MakeATSProcess("ts_parent")
24+
server_name = "http://unknown.domain.com/"
25+
26+
Test.testName = "STALE"
27+
28+
# Config child proxy to route to parent proxy
29+
ts_child.Disk.records_config.update({
30+
'proxy.config.url_remap.pristine_host_hdr': 1,
31+
'proxy.config.http.cache.max_stale_age': 10,
32+
'proxy.config.http.parent_proxy.self_detect': 0,
33+
})
34+
ts_child.Disk.parent_config.AddLine(
35+
f'dest_domain=. parent=localhost:{ts_parent.Variables.port} round_robin=consistent_hash go_direct=false'
36+
)
37+
ts_child.Disk.remap_config.AddLine(
38+
f'map http://localhost:{ts_child.Variables.port} {server_name}'
39+
)
40+
41+
# Configure parent proxy
42+
ts_parent.Disk.records_config.update({
43+
'proxy.config.url_remap.pristine_host_hdr': 1,
44+
'proxy.config.http.cache.max_stale_age': 10,
45+
})
46+
ts_parent.Disk.remap_config.AddLine(
47+
f'map http://localhost:{ts_parent.Variables.port} {server_name}'
48+
)
49+
ts_parent.Disk.remap_config.AddLine(
50+
f'map {server_name} {server_name}'
51+
)
52+
53+
# Object to push to proxies
54+
stale_5 = "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: bytes\nContent-Length: 6\nCache-Control: public, max-age=5\n\nCACHED"
55+
stale_10 = "HTTP/1.1 200 OK\nServer: ATS/10.0.0\nAccept-Ranges: bytes\nContent-Length: 6\nCache-Control: public, max-age=10\n\nCACHED"
56+
57+
58+
# Testing scenarios
59+
child_curl_request = (
60+
# Test child serving stale with failed DNS OS lookup
61+
f'curl -X PUSH -d "{stale_5}" "http://localhost:{ts_child.Variables.port}";'
62+
f'curl -X PUSH -d "{stale_10}" "http://localhost:{ts_parent.Variables.port}";'
63+
f'sleep 7; curl -s -v http://localhost:{ts_child.Variables.port};'
64+
f'sleep 15; curl -s -v http://localhost:{ts_child.Variables.port};'
65+
# Test parent serving stale with failed DNS OS lookup
66+
f'curl -X PUSH -d "{stale_5}" "http://localhost:{ts_parent.Variables.port}";'
67+
f'sleep 7; curl -s -v http://localhost:{ts_parent.Variables.port};'
68+
f'sleep 15; curl -s -v http://localhost:{ts_parent.Variables.port};'
69+
)
70+
71+
# Test case for when parent server is down but child proxy can serve cache object
72+
tr = Test.AddTestRun()
73+
tr.Processes.Default.Command = child_curl_request
74+
tr.Processes.Default.ReturnCode = 0
75+
tr.Processes.Default.StartBefore(ts_child)
76+
tr.Processes.Default.StartBefore(ts_parent)
77+
tr.Processes.Default.Streams.stderr = "gold/serve_stale_dns_fail.gold"
78+
tr.StillRunningAfter = ts_child
79+
tr.StillRunningAfter = ts_parent

0 commit comments

Comments
 (0)