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