1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Http;
9:
10: use Nette,
11: Nette\Utils\Strings;
12:
13:
14: 15: 16: 17: 18:
19: class RequestFactory extends Nette\Object
20: {
21:
22: const NONCHARS = '#[^\x09\x0A\x0D\x20-\x7E\xA0-\x{10FFFF}]#u';
23:
24:
25: public $urlFilters = array(
26: 'path' => array('#/{2,}#' => '/'),
27: 'url' => array(),
28: );
29:
30:
31: private $encoding;
32:
33:
34: 35: 36: 37:
38: public function setEncoding($encoding)
39: {
40: $this->encoding = $encoding;
41: return $this;
42: }
43:
44:
45: 46: 47: 48:
49: public function createHttpRequest()
50: {
51:
52: $url = new UrlScript;
53: $url->scheme = !empty($_SERVER['HTTPS']) && strcasecmp($_SERVER['HTTPS'], 'off') ? 'https' : 'http';
54: $url->user = isset($_SERVER['PHP_AUTH_USER']) ? $_SERVER['PHP_AUTH_USER'] : '';
55: $url->password = isset($_SERVER['PHP_AUTH_PW']) ? $_SERVER['PHP_AUTH_PW'] : '';
56:
57:
58: if ((isset($_SERVER[$tmp = 'HTTP_HOST']) || isset($_SERVER[$tmp = 'SERVER_NAME']))
59: && preg_match('#^([a-z0-9_.-]+|\[[a-fA-F0-9:]+\])(:\d+)?\z#', $_SERVER[$tmp], $pair)
60: ) {
61: $url->host = strtolower($pair[1]);
62: if (isset($pair[2])) {
63: $url->port = (int) substr($pair[2], 1);
64: } elseif (isset($_SERVER['SERVER_PORT'])) {
65: $url->port = (int) $_SERVER['SERVER_PORT'];
66: }
67: }
68:
69:
70: if (isset($_SERVER['REQUEST_URI'])) {
71: $requestUrl = $_SERVER['REQUEST_URI'];
72:
73: } elseif (isset($_SERVER['ORIG_PATH_INFO'])) {
74: $requestUrl = $_SERVER['ORIG_PATH_INFO'];
75: if (isset($_SERVER['QUERY_STRING']) && $_SERVER['QUERY_STRING'] != '') {
76: $requestUrl .= '?' . $_SERVER['QUERY_STRING'];
77: }
78: } else {
79: $requestUrl = '';
80: }
81:
82: $requestUrl = Strings::replace($requestUrl, $this->urlFilters['url']);
83: $tmp = explode('?', $requestUrl, 2);
84: $url->path = Strings::replace($tmp[0], $this->urlFilters['path']);
85: $url->query = isset($tmp[1]) ? $tmp[1] : '';
86:
87:
88: $url->canonicalize();
89: $url->path = Strings::fixEncoding($url->path);
90:
91:
92: if (isset($_SERVER['SCRIPT_NAME'])) {
93: $script = $_SERVER['SCRIPT_NAME'];
94: } elseif (isset($_SERVER['DOCUMENT_ROOT'], $_SERVER['SCRIPT_FILENAME'])
95: && strncmp($_SERVER['DOCUMENT_ROOT'], $_SERVER['SCRIPT_FILENAME'], strlen($_SERVER['DOCUMENT_ROOT'])) === 0
96: ) {
97: $script = '/' . ltrim(strtr(substr($_SERVER['SCRIPT_FILENAME'], strlen($_SERVER['DOCUMENT_ROOT'])), '\\', '/'), '/');
98: } else {
99: $script = '/';
100: }
101:
102: $path = strtolower($url->path) . '/';
103: $script = strtolower($script) . '/';
104: $max = min(strlen($path), strlen($script));
105: for ($i = 0; $i < $max; $i++) {
106: if ($path[$i] !== $script[$i]) {
107: break;
108: } elseif ($path[$i] === '/') {
109: $url->scriptPath = substr($url->path, 0, $i + 1);
110: }
111: }
112:
113:
114: $useFilter = (!in_array(ini_get('filter.default'), array('', 'unsafe_raw'), TRUE) || ini_get('filter.default_flags'));
115:
116: parse_str($url->query, $query);
117: if (!$query) {
118: $query = $useFilter ? filter_input_array(INPUT_GET, FILTER_UNSAFE_RAW) : (empty($_GET) ? array() : $_GET);
119: }
120: $post = $useFilter ? filter_input_array(INPUT_POST, FILTER_UNSAFE_RAW) : (empty($_POST) ? array() : $_POST);
121: $cookies = $useFilter ? filter_input_array(INPUT_COOKIE, FILTER_UNSAFE_RAW) : (empty($_COOKIE) ? array() : $_COOKIE);
122:
123: $gpc = (bool) get_magic_quotes_gpc();
124: $old = error_reporting(error_reporting() ^ E_NOTICE);
125:
126:
127: if ($gpc || $this->encoding) {
128: $utf = strcasecmp($this->encoding, 'UTF-8') === 0;
129: $list = array(& $query, & $post, & $cookies);
130: while (list($key, $val) = each($list)) {
131: foreach ($val as $k => $v) {
132: unset($list[$key][$k]);
133:
134: if ($gpc) {
135: $k = stripslashes($k);
136: }
137:
138: if ($this->encoding && is_string($k) && (preg_match(self::NONCHARS, $k) || preg_last_error())) {
139:
140:
141: } elseif (is_array($v)) {
142: $list[$key][$k] = $v;
143: $list[] = & $list[$key][$k];
144:
145: } else {
146: if ($gpc && !$useFilter) {
147: $v = stripSlashes($v);
148: }
149: if ($this->encoding) {
150: if ($utf) {
151: $v = Strings::fixEncoding($v);
152:
153: } else {
154: if (!Strings::checkEncoding($v)) {
155: $v = iconv($this->encoding, 'UTF-8//IGNORE', $v);
156: }
157: $v = html_entity_decode($v, ENT_QUOTES, 'UTF-8');
158: }
159: $v = preg_replace(self::NONCHARS, '', $v);
160: }
161: $list[$key][$k] = $v;
162: }
163: }
164: }
165: unset($list, $key, $val, $k, $v);
166: }
167:
168:
169:
170: $files = array();
171: $list = array();
172: if (!empty($_FILES)) {
173: foreach ($_FILES as $k => $v) {
174: if ($this->encoding && is_string($k) && (preg_match(self::NONCHARS, $k) || preg_last_error())) {
175: continue;
176: }
177: $v['@'] = & $files[$k];
178: $list[] = $v;
179: }
180: }
181:
182: while (list(, $v) = each($list)) {
183: if (!isset($v['name'])) {
184: continue;
185:
186: } elseif (!is_array($v['name'])) {
187: if ($gpc) {
188: $v['name'] = stripSlashes($v['name']);
189: }
190: if ($this->encoding) {
191: $v['name'] = preg_replace(self::NONCHARS, '', Strings::fixEncoding($v['name']));
192: }
193: $v['@'] = new FileUpload($v);
194: continue;
195: }
196:
197: foreach ($v['name'] as $k => $foo) {
198: if ($this->encoding && is_string($k) && (preg_match(self::NONCHARS, $k) || preg_last_error())) {
199: continue;
200: }
201: $list[] = array(
202: 'name' => $v['name'][$k],
203: 'type' => $v['type'][$k],
204: 'size' => $v['size'][$k],
205: 'tmp_name' => $v['tmp_name'][$k],
206: 'error' => $v['error'][$k],
207: '@' => & $v['@'][$k],
208: );
209: }
210: }
211:
212: error_reporting($old);
213:
214:
215:
216: if (function_exists('apache_request_headers')) {
217: $headers = array_change_key_case(apache_request_headers(), CASE_LOWER);
218: } else {
219: $headers = array();
220: foreach ($_SERVER as $k => $v) {
221: if (strncmp($k, 'HTTP_', 5) == 0) {
222: $k = substr($k, 5);
223: } elseif (strncmp($k, 'CONTENT_', 8)) {
224: continue;
225: }
226: $headers[ strtr(strtolower($k), '_', '-') ] = $v;
227: }
228: }
229:
230: return new Request($url, $query, $post, $files, $cookies, $headers,
231: isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : NULL,
232: isset($_SERVER['REMOTE_ADDR']) ? $_SERVER['REMOTE_ADDR'] : NULL,
233: isset($_SERVER['REMOTE_HOST']) ? $_SERVER['REMOTE_HOST'] : NULL
234: );
235: }
236:
237: }
238: