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