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