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