Skip to content

Commit 8f16f2d

Browse files
jasmine-nahraincmcfarlen
authored andcommitted
Content-type lost when sent after duplicate headers (#11821)
* Fix for #11784 * Just specify content-type not be altered * Update HttpTransact.cc (cherry picked from commit 8671ddb)
1 parent f480e43 commit 8f16f2d

File tree

3 files changed

+328
-0
lines changed

3 files changed

+328
-0
lines changed

src/proxy/http/HttpTransact.cc

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5022,6 +5022,17 @@ HttpTransact::merge_response_header_with_cached_header(HTTPHdr *cached_header, H
50225022
MIMEField &field2{*spot2};
50235023
name2 = field2.name_get(&name_len2);
50245024

5025+
// It is specified above that content type should not
5026+
// be altered here however when a duplicate header
5027+
// is present, all headers following are delete and
5028+
// re-added back. This includes content type if it follows
5029+
// any duplicate header. This leads to the loss of
5030+
// content type in the client response.
5031+
// This ensures that it is not altered when duplicate
5032+
// headers are present.
5033+
if (name2 == MIME_FIELD_CONTENT_TYPE) {
5034+
continue;
5035+
}
50255036
cached_header->field_delete(name2, name_len2);
50265037
}
50275038
dups_seen = true;
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
'''
2+
Test cached responses and requests with bodies
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.Summary = '''
21+
Test revalidating cached objects
22+
'''
23+
testName = "RevalidateCacheObject"
24+
Test.ContinueOnFail = True
25+
26+
27+
class CachedHeaderValidationTest:
28+
replay_file = "replays/cache-test.replay.yaml"
29+
30+
def __init__(self):
31+
self.setupOriginServer()
32+
self.setupTS()
33+
34+
def setupOriginServer(self):
35+
self.server = Test.MakeVerifierServerProcess("cached-header-verifier-server", self.replay_file)
36+
37+
def setupTS(self):
38+
self.ts = Test.MakeATSProcess("ts", enable_tls=True)
39+
self.ts.Disk.plugin_config.AddLine('xdebug.so --enable=x-cache,x-cache-key,via')
40+
self.ts.Disk.records_config.update(
41+
{
42+
'proxy.config.diags.debug.enabled': 1,
43+
'proxy.config.diags.debug.tags': 'http',
44+
'proxy.config.http.response_via_str': 3,
45+
})
46+
self.ts.Disk.remap_config.AddLine('map / http://127.0.0.1:{0}'.format(self.server.Variables.http_port))
47+
48+
def runTraffic(self):
49+
tr = Test.AddTestRun()
50+
tr.AddVerifierClientProcess("cached-header-verifier-client", self.replay_file, http_ports=[self.ts.Variables.port])
51+
tr.Processes.Default.StartBefore(self.server)
52+
tr.Processes.Default.StartBefore(self.ts)
53+
tr.StillRunningAfter = self.ts
54+
tr.StillRunningAfter = self.server
55+
56+
def run(self):
57+
self.runTraffic()
58+
59+
60+
CachedHeaderValidationTest().run()
Lines changed: 257 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,257 @@
1+
# Licensed to the Apache Software Foundation (ASF) under one
2+
# or more contributor license agreements. See the NOTICE file
3+
# distributed with this work for additional information
4+
# regarding copyright ownership. The ASF licenses this file
5+
# to you under the Apache License, Version 2.0 (the
6+
# "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at
8+
#
9+
# http://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
17+
meta:
18+
version: "1.0"
19+
20+
# Note 1:
21+
# When testing duplicate headers here, replay files cannot
22+
# handle two seperate values. So make sure that duplicate headers
23+
# have the same value in testing.
24+
25+
sessions:
26+
- transactions:
27+
# Test 0: Cache fill with content-type after duplicate headers
28+
- client-request:
29+
method: "GET"
30+
version: "1.1"
31+
url: /1
32+
headers:
33+
fields:
34+
- [Host, example.com]
35+
- [uuid, fill_1]
36+
- [x-debug, "x-cache,x-cache-key,via"]
37+
38+
server-response:
39+
status: 200
40+
reason: OK
41+
headers:
42+
fields:
43+
- [Date, "Mon, 23 Sep 2024 14:22:14 GMT"]
44+
- [X-Reveal-Duplicate, same]
45+
- [Cache-Control, "max-age=1, stale-if-error=1, stale-while-revalidate=1, public"]
46+
- [Content-Length, 3]
47+
- [Content-Type, application/javascript]
48+
- [Expires, "Mon, 23 Sep 2024 14:22:44 GMT"]
49+
- [Last-Modified, "Mon, 23 Sep 2024 14:22:14 GMT"]
50+
- [X-Reveal-Duplicate, same]
51+
52+
proxy-response:
53+
status: 200
54+
reason: OK
55+
headers:
56+
fields:
57+
- [Date, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
58+
- [X-Reveal-Duplicate, { value: same, as: equal }]
59+
- [Cache-Control, { value: "max-age=1, stale-if-error=1, stale-while-revalidate=1, public", as: equal }]
60+
- [Content-Length, { value: 3, as: equal }]
61+
- [Content-Type, { value: application/javascript, as: equal }]
62+
- [Expires, { value: "Mon, 23 Sep 2024 14:22:44 GMT", as: equal }]
63+
- [Last-Modified, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
64+
- [X-Cache, { value: miss, as: equal }]
65+
- [X-Reveal-Duplicate, { value: same, as: equal }]
66+
67+
# Test 1: Cache hit stale with content-type after duplicate headers
68+
- client-request:
69+
method: "GET"
70+
version: "1.1"
71+
url: /1
72+
headers:
73+
fields:
74+
- [Host, example.com]
75+
- [uuid, stale_1]
76+
- [x-debug, "x-cache,x-cache-key,via"]
77+
78+
server-response:
79+
status: 304
80+
reason: Not Modified
81+
headers:
82+
fields:
83+
- [Date, "Mon, 23 Sep 2024 14:22:14 GMT"]
84+
- [X-Reveal-Duplicate, same]
85+
- [Cache-Control, "max-age=1, stale-if-error=1, stale-while-revalidate=1, public"]
86+
- [Content-Length, 3]
87+
- [Content-Type, application/javascript]
88+
- [Expires, "Mon, 23 Sep 2024 14:22:44 GMT"]
89+
- [Last-Modified, "Mon, 23 Sep 2024 14:22:14 GMT"]
90+
- [X-Reveal-Duplicate, same]
91+
92+
proxy-response:
93+
status: 200
94+
reason: OK
95+
headers:
96+
fields:
97+
- [Date, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
98+
- [X-Reveal-Duplicate, { value: same, as: equal }]
99+
- [Cache-Control, { value: "max-age=1, stale-if-error=1, stale-while-revalidate=1, public", as: equal }]
100+
- [Content-Length, { value: 3, as: equal }]
101+
- [Content-Type, { value: application/javascript, as: equal }]
102+
- [Expires, { value: "Mon, 23 Sep 2024 14:22:44 GMT", as: equal }]
103+
- [Last-Modified, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
104+
- [X-Cache, { value: hit-stale, as: equal }]
105+
- [X-Reveal-Duplicate, { value: same, as: equal }]
106+
107+
# Test 2: Cache fill with content-type before duplicate headers
108+
- client-request:
109+
method: "GET"
110+
version: "1.1"
111+
url: /2
112+
headers:
113+
fields:
114+
- [Host, example.com]
115+
- [uuid, fill_2]
116+
- [x-debug, "x-cache,x-cache-key,via"]
117+
118+
server-response:
119+
status: 200
120+
reason: OK
121+
headers:
122+
fields:
123+
- [Date, "Mon, 23 Sep 2024 14:22:14 GMT"]
124+
- [Content-Type, application/javascript]
125+
- [X-Reveal-Duplicate, same]
126+
- [Cache-Control, "max-age=1, stale-if-error=1, stale-while-revalidate=1, public"]
127+
- [Content-Length, 3]
128+
- [Expires, "Mon, 23 Sep 2024 14:22:44 GMT"]
129+
- [Last-Modified, "Mon, 23 Sep 2024 14:22:14 GMT"]
130+
- [X-Reveal-Duplicate, same]
131+
132+
proxy-response:
133+
status: 200
134+
reason: OK
135+
headers:
136+
fields:
137+
- [Date, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
138+
- [X-Reveal-Duplicate, { value: same, as: equal }]
139+
- [Cache-Control, { value: "max-age=1, stale-if-error=1, stale-while-revalidate=1, public", as: equal }]
140+
- [Content-Length, { value: 3, as: equal }]
141+
- [Content-Type, { value: application/javascript, as: equal }]
142+
- [Expires, { value: "Mon, 23 Sep 2024 14:22:44 GMT", as: equal }]
143+
- [Last-Modified, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
144+
- [X-Cache, { value: miss, as: equal }]
145+
- [X-Reveal-Duplicate, { value: same, as: equal }]
146+
147+
# Test 3: Cache hit stale with content-type before duplicate headers
148+
- client-request:
149+
method: "GET"
150+
version: "1.1"
151+
url: /2
152+
headers:
153+
fields:
154+
- [Host, example.com]
155+
- [uuid, stale_2]
156+
- [x-debug, "x-cache,x-cache-key,via"]
157+
158+
server-response:
159+
status: 304
160+
reason: Not Modified
161+
headers:
162+
fields:
163+
- [Date, "Mon, 23 Sep 2024 14:22:14 GMT"]
164+
- [Content-Type, application/javascript]
165+
- [X-Reveal-Duplicate, same]
166+
- [X-Reveal-Duplicate, same]
167+
- [Cache-Control, "max-age=1, stale-if-error=1, stale-while-revalidate=1, public"]
168+
- [Content-Length, 3]
169+
- [Expires, "Mon, 23 Sep 2024 14:22:44 GMT"]
170+
- [Last-Modified, "Mon, 23 Sep 2024 14:22:14 GMT"]
171+
172+
proxy-response:
173+
status: 200
174+
reason: OK
175+
headers:
176+
fields:
177+
- [Date, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
178+
- [X-Reveal-Duplicate, { value: same, as: equal }]
179+
- [X-Reveal-Duplicate, { value: same, as: equal }]
180+
- [Cache-Control, { value: "max-age=1, stale-if-error=1, stale-while-revalidate=1, public", as: equal }]
181+
- [Content-Length, { value: 3, as: equal }]
182+
- [Content-Type, { value: application/javascript, as: equal }]
183+
- [Expires, { value: "Mon, 23 Sep 2024 14:22:44 GMT", as: equal }]
184+
- [Last-Modified, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
185+
- [X-Cache, { value: hit-stale, as: equal }]
186+
187+
# Test 4: Cache fill with no duplicate headers
188+
- client-request:
189+
method: "GET"
190+
version: "1.1"
191+
url: /3
192+
headers:
193+
fields:
194+
- [Host, example.com]
195+
- [uuid, fill_3]
196+
- [x-debug, "x-cache,x-cache-key,via"]
197+
198+
server-response:
199+
status: 200
200+
reason: OK
201+
headers:
202+
fields:
203+
- [Date, "Mon, 23 Sep 2024 14:22:14 GMT"]
204+
- [Content-Type, application/javascript]
205+
- [Cache-Control, "max-age=1, stale-if-error=1, stale-while-revalidate=1, public"]
206+
- [Content-Length, 3]
207+
- [Expires, "Mon, 23 Sep 2024 14:22:44 GMT"]
208+
- [Last-Modified, "Mon, 23 Sep 2024 14:22:14 GMT"]
209+
210+
proxy-response:
211+
status: 200
212+
reason: OK
213+
headers:
214+
fields:
215+
- [Date, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
216+
- [Cache-Control, { value: "max-age=1, stale-if-error=1, stale-while-revalidate=1, public", as: equal }]
217+
- [Content-Length, { value: 3, as: equal }]
218+
- [Content-Type, { value: application/javascript, as: equal }]
219+
- [Expires, { value: "Mon, 23 Sep 2024 14:22:44 GMT", as: equal }]
220+
- [Last-Modified, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
221+
- [X-Cache, { value: miss, as: equal }]
222+
223+
# Test 5: Cache hit stale no duplicate headers
224+
- client-request:
225+
method: "GET"
226+
version: "1.1"
227+
url: /3
228+
headers:
229+
fields:
230+
- [Host, example.com]
231+
- [uuid, stale_3]
232+
- [x-debug, "x-cache,x-cache-key,via"]
233+
234+
server-response:
235+
status: 304
236+
reason: Not Modified
237+
headers:
238+
fields:
239+
- [Date, "Mon, 23 Sep 2024 14:22:14 GMT"]
240+
- [Content-Type, application/javascript]
241+
- [Cache-Control, "max-age=1, stale-if-error=1, stale-while-revalidate=1, public"]
242+
- [Content-Length, 3]
243+
- [Expires, "Mon, 23 Sep 2024 14:22:44 GMT"]
244+
- [Last-Modified, "Mon, 23 Sep 2024 14:22:14 GMT"]
245+
246+
proxy-response:
247+
status: 200
248+
reason: OK
249+
headers:
250+
fields:
251+
- [Date, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
252+
- [Cache-Control, { value: "max-age=1, stale-if-error=1, stale-while-revalidate=1, public", as: equal }]
253+
- [Content-Length, { value: 3, as: equal }]
254+
- [Content-Type, { value: application/javascript, as: equal }]
255+
- [Expires, { value: "Mon, 23 Sep 2024 14:22:44 GMT", as: equal }]
256+
- [Last-Modified, { value: "Mon, 23 Sep 2024 14:22:14 GMT", as: equal }]
257+
- [X-Cache, { value: hit-stale, as: equal }]

0 commit comments

Comments
 (0)