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