Skip to content

Commit e19389d

Browse files
committed
Merge pull request #158 from lucasmichot/conditional-request
[Bugfix] : Disable conditional request feature outside API and does not overwrite existing ETag
2 parents f1e3f2f + a5d8b46 commit e19389d

File tree

2 files changed

+117
-8
lines changed

2 files changed

+117
-8
lines changed

src/Routing/Router.php

+13-7
Original file line numberDiff line numberDiff line change
@@ -287,15 +287,21 @@ protected function prepareResponse($request, $response)
287287
{
288288
$response = parent::prepareResponse($request, $response);
289289

290-
if ($response instanceof IlluminateResponse && $this->requestTargettingApi($request)) {
291-
$response = ApiResponse::makeFromExisting($response);
292-
}
290+
if ($this->requestTargettingApi($request)) {
293291

294-
if ($response->isSuccessful() && $this->getConditionalRequest()) {
295-
$response->setEtag(md5($response->getContent()));
296-
}
292+
if ($response instanceof IlluminateResponse) {
293+
$response = ApiResponse::makeFromExisting($response);
294+
}
297295

298-
$response->isNotModified($request);
296+
if ($response->isSuccessful() && $this->getConditionalRequest()) {
297+
298+
if (! $response->headers->has('ETag')) {
299+
$response->setEtag(md5($response->getContent()));
300+
}
301+
302+
$response->isNotModified($request);
303+
}
304+
}
299305

300306
return $response;
301307
}

tests/RoutingRouterTest.php

+104-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,7 @@ public function testAddingRouteFallsThroughToRouterCollection()
148148
}
149149

150150

151-
public function testRouterPreparesNotModifiedResponse()
151+
public function testRouterPreparesNotModifiedIlluminateResponse()
152152
{
153153
$this->router->api(['version' => 'v1'], function ()
154154
{
@@ -190,6 +190,109 @@ public function testRouterPreparesNotModifiedResponse()
190190
}
191191

192192

193+
public function testRouterPreparesNotModifiedNonIlluminateResponse()
194+
{
195+
$this->router->api(['version' => 'v1'], function ()
196+
{
197+
$this->router->get('foo', function () {
198+
return new \Symfony\Component\HttpFoundation\Response('bar');
199+
});
200+
});
201+
202+
$request = Request::create('foo', 'GET');
203+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
204+
$this->router->setConditionalRequest(false);
205+
$response = $this->router->dispatch($request);
206+
$this->assertEquals(200, $response->getStatusCode());
207+
$this->assertEquals('bar', $response->getContent());
208+
209+
$request = Request::create('foo', 'GET');
210+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
211+
$this->router->setConditionalRequest(true);
212+
$response = $this->router->dispatch($request);
213+
$this->assertEquals(200, $response->getStatusCode());
214+
$this->assertEquals('"'.md5('bar').'"', $response->getETag());
215+
$this->assertEquals('bar', $response->getContent());
216+
217+
$request = Request::create('foo', 'GET');
218+
$request->headers->set('If-None-Match', '"'.md5('bar').'"', true);
219+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
220+
$this->router->setConditionalRequest(true);
221+
$response = $this->router->dispatch($request);
222+
$this->assertEquals(304, $response->getStatusCode());
223+
$this->assertEquals('"'.md5('bar').'"', $response->getETag());
224+
$this->assertEquals(null, $response->getContent());
225+
226+
$request = Request::create('foo', 'GET');
227+
$request->headers->set('If-None-Match', '0123456789', true);
228+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
229+
$this->router->setConditionalRequest(true);
230+
$response = $this->router->dispatch($request);
231+
$this->assertEquals(200, $response->getStatusCode());
232+
$this->assertEquals('"'.md5('bar').'"', $response->getETag());
233+
$this->assertEquals('bar', $response->getContent());
234+
}
235+
236+
237+
public function testRouterSkipNotModifiedResponseOutsideApi()
238+
{
239+
$this->router->group([], function ()
240+
{
241+
$this->router->get('foo', function () { return 'bar'; });
242+
});
243+
244+
$request = Request::create('foo', 'GET');
245+
$this->router->setConditionalRequest(true);
246+
$response = $this->router->dispatch($request);
247+
$this->assertEquals(200, $response->getStatusCode());
248+
$this->assertFalse($response->headers->has('ETag'));
249+
$this->assertEquals('bar', $response->getContent());
250+
}
251+
252+
253+
public function testRouterHandlesExistingEtag()
254+
{
255+
$this->router->api(['version' => 'v1'], function ()
256+
{
257+
$this->router->get('foo', function () {
258+
$response = new Response('bar');
259+
$response->setEtag('custom-etag');
260+
return $response;
261+
});
262+
});
263+
264+
$request = Request::create('foo', 'GET');
265+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
266+
$this->router->setConditionalRequest(true);
267+
$response = $this->router->dispatch($request);
268+
$this->assertEquals(200, $response->getStatusCode());
269+
$this->assertEquals('"custom-etag"', $response->getETag());
270+
$this->assertEquals('bar', $response->getContent());
271+
}
272+
273+
274+
public function testRouterHandlesCustomEtag()
275+
{
276+
$this->router->api(['version' => 'v1'], function ()
277+
{
278+
$this->router->get('foo', function () {
279+
$response = new Response('bar');
280+
$response->setEtag('custom-etag');
281+
return $response;
282+
});
283+
});
284+
285+
$request = Request::create('foo', 'GET');
286+
$request->headers->set('If-None-Match', '"custom-etag"', true);
287+
$request->headers->set('accept', 'application/vnd.testing.v1+json');
288+
$this->router->setConditionalRequest(true);
289+
$response = $this->router->dispatch($request);
290+
$this->assertEquals(304, $response->getStatusCode());
291+
$this->assertEquals('"custom-etag"', $response->getETag());
292+
$this->assertEquals(null, $response->getContent());
293+
}
294+
295+
193296
public function testGettingUnkownApiCollectionThrowsException()
194297
{
195298
$this->assertNull($this->router->getApiRouteCollection('v1'));

0 commit comments

Comments
 (0)