1: <?php
2:
3: /**
4: * This file is part of the Nette Framework (https://nette.org)
5: * Copyright (c) 2004 David Grudl (https://davidgrudl.com)
6: */
7:
8: namespace Nette\Http;
9:
10: use Nette;
11:
12:
13: /**
14: * HTTP-specific tasks.
15: *
16: * @author David Grudl
17: *
18: * @property-read bool $modified
19: * @property-read IRequest $request
20: * @property-read IResponse $response
21: */
22: class Context extends Nette\Object
23: {
24: /** @var IRequest */
25: private $request;
26:
27: /** @var IResponse */
28: private $response;
29:
30:
31: public function __construct(IRequest $request, IResponse $response)
32: {
33: $this->request = $request;
34: $this->response = $response;
35: }
36:
37:
38: /**
39: * Attempts to cache the sent entity by its last modification date.
40: * @param string|int|\DateTime last modified time
41: * @param string strong entity tag validator
42: * @return bool
43: */
44: public function isModified($lastModified = NULL, $etag = NULL)
45: {
46: if ($lastModified) {
47: $this->response->setHeader('Last-Modified', $this->response->date($lastModified));
48: }
49: if ($etag) {
50: $this->response->setHeader('ETag', '"' . addslashes($etag) . '"');
51: }
52:
53: $ifNoneMatch = $this->request->getHeader('If-None-Match');
54: if ($ifNoneMatch === '*') {
55: $match = TRUE; // match, check if-modified-since
56:
57: } elseif ($ifNoneMatch !== NULL) {
58: $etag = $this->response->getHeader('ETag');
59:
60: if ($etag == NULL || strpos(' ' . strtr($ifNoneMatch, ",\t", ' '), ' ' . $etag) === FALSE) {
61: return TRUE;
62:
63: } else {
64: $match = TRUE; // match, check if-modified-since
65: }
66: }
67:
68: $ifModifiedSince = $this->request->getHeader('If-Modified-Since');
69: if ($ifModifiedSince !== NULL) {
70: $lastModified = $this->response->getHeader('Last-Modified');
71: if ($lastModified != NULL && strtotime($lastModified) <= strtotime($ifModifiedSince)) {
72: $match = TRUE;
73:
74: } else {
75: return TRUE;
76: }
77: }
78:
79: if (empty($match)) {
80: return TRUE;
81: }
82:
83: $this->response->setCode(IResponse::S304_NOT_MODIFIED);
84: return FALSE;
85: }
86:
87:
88: /**
89: * @return IRequest
90: */
91: public function getRequest()
92: {
93: return $this->request;
94: }
95:
96:
97: /**
98: * @return IResponse
99: */
100: public function getResponse()
101: {
102: return $this->response;
103: }
104:
105: }
106: