Skip to content

Commit 11443be

Browse files
committed
Refs googleapis#369: Fix header handling during cache revalidation.
1 parent 9e4fdcb commit 11443be

File tree

2 files changed

+103
-17
lines changed

2 files changed

+103
-17
lines changed

src/Google/IO/Abstract.php

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,17 @@ abstract class Google_IO_Abstract
3030
"HTTP/1.1 200 Connection established\r\n\r\n",
3131
);
3232
private static $ENTITY_HTTP_METHODS = array("POST" => null, "PUT" => null);
33+
private static $HOP_BY_HOP = array(
34+
'connection' => true,
35+
'keep-alive' => true,
36+
'proxy-authenticate' => true,
37+
'proxy-authorization' => true,
38+
'te' => true,
39+
'trailers' => true,
40+
'transfer-encoding' => true,
41+
'upgrade' => true
42+
);
43+
3344

3445
/** @var Google_Client */
3546
protected $client;
@@ -55,13 +66,13 @@ abstract public function executeRequest(Google_Http_Request $request);
5566
* @param $options
5667
*/
5768
abstract public function setOptions($options);
58-
69+
5970
/**
6071
* Set the maximum request time in seconds.
6172
* @param $timeout in seconds
6273
*/
6374
abstract public function setTimeout($timeout);
64-
75+
6576
/**
6677
* Get the maximum request time in seconds.
6778
* @return timeout in seconds
@@ -96,7 +107,7 @@ public function setCachedRequest(Google_Http_Request $request)
96107

97108
return false;
98109
}
99-
110+
100111
/**
101112
* Execute an HTTP Request
102113
*
@@ -128,7 +139,7 @@ public function makeRequest(Google_Http_Request $request)
128139
}
129140

130141
if (!isset($responseHeaders['Date']) && !isset($responseHeaders['date'])) {
131-
$responseHeaders['Date'] = date("r");
142+
$responseHeaders['date'] = date("r");
132143
}
133144

134145
$request->setResponseHttpCode($respHttpCode);
@@ -221,23 +232,24 @@ protected function checkMustRevalidateCachedRequest($cached, $request)
221232
*/
222233
protected function updateCachedRequest($cached, $responseHeaders)
223234
{
224-
if (isset($responseHeaders['connection'])) {
225-
$hopByHop = array_merge(
226-
self::$HOP_BY_HOP,
227-
explode(
228-
',',
229-
$responseHeaders['connection']
235+
$hopByHop = self::$HOP_BY_HOP;
236+
if (!empty($responseHeaders['connection'])) {
237+
$connectionHeaders = array_map(
238+
'strtolower',
239+
array_filter(
240+
array_map('trim', explode(',', $responseHeaders['connection']))
230241
)
231242
);
243+
$hopByHop += array_fill_keys($connectionHeaders, true);
244+
}
232245

233-
$endToEnd = array();
234-
foreach ($hopByHop as $key) {
235-
if (isset($responseHeaders[$key])) {
236-
$endToEnd[$key] = $responseHeaders[$key];
237-
}
246+
$endToEnd = array();
247+
foreach ($responseHeaders as $key => $val) {
248+
if (empty($hopByHop[$key])) {
249+
$endToEnd[$key] = $val;
238250
}
239-
$cached->setResponseHeaders($endToEnd);
240251
}
252+
$cached->setResponseHeaders($endToEnd);
241253
}
242254

243255
/**
@@ -320,7 +332,7 @@ private function parseArrayHeaders($rawHeaders)
320332
// Times will have colons in - so we just want the first match.
321333
$header_parts = explode(': ', $header, 2);
322334
if (count($header_parts) == 2) {
323-
$headers[$header_parts[0]] = $header_parts[1];
335+
$headers[strtolower($header_parts[0])] = $header_parts[1];
324336
}
325337
}
326338

tests/general/IoTest.php

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -134,6 +134,80 @@ public function testCurlInvalidRequest()
134134
$this->invalidRequest($io);
135135
}
136136

137+
public function testCacheRevalidate()
138+
{
139+
$client = $this->getClient();
140+
141+
$req = new Google_Http_Request('/test', 'GET');
142+
$req->setRequestHeaders(array('Accept' => '*/*'));
143+
$req->setResponseBody('{"a": "foo"}');
144+
$req->setResponseHttpCode(200);
145+
$req->setResponseHeaders(
146+
array(
147+
'cache-control' => 'private',
148+
'etag' => '"this-is-an-etag"',
149+
'expires' => '-1',
150+
'date' => 'Sun, 1 Jan 2012 09:00:56 GMT',
151+
'content-type' => 'application/json; charset=UTF-8',
152+
)
153+
);
154+
155+
$io = $this->getMockBuilder('Google_IO_Abstract')
156+
->setConstructorArgs(array($client))
157+
->setMethods(
158+
array(
159+
'getCachedRequest',
160+
'checkMustRevalidateCachedRequest'
161+
)
162+
)
163+
->getMockForAbstractClass();
164+
165+
$io->expects($this->once())
166+
->method('getCachedRequest')
167+
->will($this->returnValue($req));
168+
169+
$io->expects($this->once())
170+
->method('checkMustRevalidateCachedRequest')
171+
->will($this->returnValue(true));
172+
173+
$io->expects($this->once())
174+
->method('executeRequest')
175+
->will(
176+
$this->returnValue(
177+
array(
178+
'{"a": "foo"}',
179+
array(
180+
'te' => 'gzip',
181+
'connection' => 'Keep-Alive, Foo, Bar',
182+
'foo' => '123',
183+
'keep-alive' => 'timeout=30',
184+
'cache-control' => 'private',
185+
'eTag' => '"this-is-a-new-etag"',
186+
"expires" => 'Sun, 22 Jan 2022 09:00:56 GMT',
187+
'date' => 'Sun, 1 Jan 2012 09:00:56 GMT',
188+
'content-type' => 'application/json; charset=UTF-8',
189+
),
190+
304
191+
)
192+
)
193+
);
194+
195+
$res = $io->makeRequest(new Google_Http_Request('/test', 'GET'));
196+
197+
$this->assertEquals('{"a": "foo"}', $res->getResponseBody());
198+
$this->assertEquals(200, $res->getResponseHttpCode());
199+
$this->assertEquals(
200+
array(
201+
'cache-control' => 'private',
202+
'etag' => '"this-is-a-new-etag"',
203+
"expires" => 'Sun, 22 Jan 2022 09:00:56 GMT',
204+
'date' => 'Sun, 1 Jan 2012 09:00:56 GMT',
205+
'content-type' => 'application/json; charset=UTF-8',
206+
),
207+
$res->getResponseHeaders()
208+
);
209+
}
210+
137211
// Asserting Functions
138212

139213
public function timeoutChecker($io)

0 commit comments

Comments
 (0)