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