]> CyberLeo.Net >> Repos - SourceForge/phpwiki.git/blob - lib/Request.php
Fix file upload bug.
[SourceForge/phpwiki.git] / lib / Request.php
1 <?php rcs_id('$Id: Request.php,v 1.3 2001-11-17 16:39:08 dairiki Exp $');
2
3 // FIXME: write log entry.
4
5 class Request {
6         
7     function Request() {
8
9         $this->_fix_magic_quotes_gpc();
10         $this->_fix_multipart_form_data();
11
12         switch($this->get('REQUEST_METHOD')) {
13         case 'GET':
14         case 'HEAD':
15             $this->args = &$GLOBALS['HTTP_GET_VARS'];
16             break;
17         case 'POST':
18             $this->args = &$GLOBALS['HTTP_POST_VARS'];
19             break;
20         default:
21             $this->args = array();
22             break;
23         }
24         
25         $this->session = new Request_SessionVars;
26         $this->cookies = new Request_CookieVars;
27
28         $this->_log_entry = new Request_AccessLogEntry($this);
29         
30         $TheRequest = $this;
31     }
32
33     function get($key) {
34         $vars = &$GLOBALS['HTTP_SERVER_VARS'];
35
36         if (isset($vars[$key]))
37             return $vars[$key];
38
39         switch ($key) {
40         case 'REMOTE_HOST':
41             $addr = $vars['REMOTE_ADDR'];
42             if (defined('ENABLE_REVERSE_DNS') && ENABLE_REVERSE_DNS)
43                 return $vars[$key] = gethostbyaddr($addr);
44             else
45                 return $addr;
46         default:
47             return false;
48         }
49     }
50
51     function getArg($key) {
52         if (isset($this->args[$key]))
53             return $this->args[$key];
54         return false;
55     }
56
57     function setArg($key, $val) {
58         $this->args[$key] = $val;
59     }
60
61     
62     function redirect($url) {
63         header("Location: $url");
64         $this->_log_entry->setStatus(302);
65     }
66
67     function compress_output() {
68         if (function_exists('ob_gzhandler')) {
69             ob_start('ob_gzhandler');
70             $this->_is_compressing_output = true;
71         }
72     }
73
74     function finish() {
75         if (!empty($this->_is_compressing_output))
76             ob_end_flush();
77     }
78     
79
80     function getSessionVar($key) {
81         return $this->session->get($key);
82     }
83     function setSessionVar($key, $val) {
84         return $this->session->set($key, $val);
85     }
86     function deleteSessionVar($key) {
87         return $this->session->delete($key);
88     }
89
90     function getCookieVar($key) {
91         return $this->cookies->get($key);
92     }
93     function setCookieVar($key, $val, $lifetime_in_days = false) {
94         return $this->cookies->set($key, $val, $lifetime_in_days);
95     }
96     function deleteCookieVar($key) {
97         return $this->cookies->delete($key);
98     }
99     
100     function getUploadedFile($key) {
101         return Request_UploadedFile::getUploadedFile($key);
102     }
103     
104
105     function _fix_magic_quotes_gpc() {
106         $needs_fix = array('HTTP_POST_VARS',
107                            'HTTP_GET_VARS',
108                            'HTTP_COOKIE_VARS',
109                            'HTTP_SERVER_VARS',
110                            'HTTP_POST_FILES');
111         
112         // Fix magic quotes.
113         if (get_magic_quotes_gpc()) {
114             foreach ($needs_fix as $vars)
115                 $this->_stripslashes($GLOBALS[$vars]);
116         }
117     }
118
119
120     function _stripslashes(&$var) {
121         if (is_array($var)) {
122             foreach ($var as $key => $val)
123                 $this->_stripslashes($var[$key]);
124         }
125         elseif (is_string($var))
126             $var = stripslashes($var);
127     }
128
129     function _fix_multipart_form_data () {
130         if (preg_match('|^multipart/form-data|', $this->get('CONTENT_TYPE')))
131             $this->_strip_leading_nl($GLOBALS['HTTP_POST_VARS']);
132     }
133     
134     function _strip_leading_nl(&$var) {
135         if (is_array($var)) {
136             foreach ($var as $key => $val)
137                 $this->_strip_leading_nl($var[$key]);
138         }
139         elseif (is_string($var))
140             $var = preg_replace('|^\r?\n?|', '', $var);
141     }
142 }
143
144 class Request_SessionVars {
145     function Request_SessionVars() {
146         session_start();
147     }
148
149     function get($key) {
150         $vars = &$GLOBALS['HTTP_SESSION_VARS'];
151         if (isset($vars[$key]))
152             return $vars[$key];
153         return false;
154     }
155
156     function set($key, $val) {
157         $vars = &$GLOBALS['HTTP_SESSION_VARS'];
158         if (ini_get('register_globals')) {
159             // This is funky but necessary, at least in some PHP's
160             $GLOBALS[$key] = $val;
161         }
162         $vars[$key] = $val;
163         session_register($key);
164     }
165     
166     function delete($key) {
167         $vars = &$GLOBALS['HTTP_SESSION_VARS'];
168         if (ini_get('register_globals'))
169             unset($GLOBALS[$key]);
170         unset($vars[$key]);
171         session_unregister($key);
172     }
173 }
174
175 class Request_CookieVars {
176
177     function get($key) {
178         $vars = &$GLOBALS['HTTP_COOKIE_VARS'];
179         if (isset($vars[$key])) {
180             @$val = unserialize($vars[$key]);
181             if (!empty($val))
182                 return $val;
183         }
184         return false;
185     }
186         
187     function set($key, $val, $persist_days = false) {
188         $vars = &$GLOBALS['HTTP_COOKIE_VARS'];
189
190         if (is_numeric($persist_days)) {
191             $expires = time() + (24 * 3600) * $persist_days;
192         }
193         else {
194             $expires = 0;
195         }
196         
197         $packedval = serialize($val);
198         $vars[$key] = $packedval;
199         setcookie($key, $packedval, $expires, '/');
200     }
201
202     function delete($key) {
203         $vars = &$GLOBALS['HTTP_COOKIE_VARS'];
204         setcookie($key);
205         unset($vars[$key]);
206     }
207 }
208
209 class Request_UploadedFile {
210     function getUploadedFile($postname) {
211         global $HTTP_POST_FILES;
212
213         if (!isset($HTTP_POST_FILES[$postname]))
214             return false;
215         
216         $fileinfo = &$HTTP_POST_FILES[$postname];
217         if (!is_uploaded_file($fileinfo['tmp_name']))
218             return false;       // possible malicious attack.
219
220         return new Request_UploadedFile($fileinfo);
221     }
222     
223     function Request_UploadedFile($fileinfo) {
224         $this->_info = $fileinfo;
225     }
226
227     function getSize() {
228         return $this->_info['size'];
229     }
230
231     function getName() {
232         return $this->_info['name'];
233     }
234
235     function getType() {
236         return $this->_info['type'];
237     }
238
239     function open() {
240         if ( ($fd = fopen($this->_info['tmp_name'], "rb")) ) {
241             if ($this->getSize() < filesize($this->_info['tmp_name'])) {
242                 // FIXME: Some PHP's (or is it some browsers?) put
243                 //    HTTP/MIME headers in the file body, some don't.
244                 //
245                 // At least, I think that's the case.  I know I used
246                 // to need this code, now I don't.
247                 //
248                 // This code is more-or-less untested currently.
249                 //
250                 // Dump HTTP headers.
251                 while ( ($header = fgets($fd, 4096)) ) {
252                     if (trim($header) == '') {
253                         break;
254                     }
255                     else if (!preg_match('/^content-(length|type):/i', $header)) {
256                         rewind($fd);
257                         break;
258                     }
259                 }
260             }
261         }
262         return $fd;
263     }
264
265     function getContents() {
266         $fd = $this->open();
267         $data = fread($fd, $this->getSize());
268         fclose($fd);
269         return $data;
270     }
271 }
272
273 class Request_AccessLogEntry
274 {
275    function AccessLogEntry ($request) {
276       $this->host = $req->get('REMOTE_HOST');
277       $this->ident = $req->get('REMOTE_IDENT');
278       if (!$this->ident)
279           $this->ident = '-';
280       $this->user = '-';
281       $this->time = time();
282       $this->request = join(' ', array($req->get('REQUEST_METHOD'),
283                                        $req->get('REQUEST_URI'),
284                                        $req->get('SERVER_PROTOCOL')));
285       $this->status = 200;
286       $this->size = 0;
287       $this->referer = (string) $req->get('HTTP_REFERER');
288       $this->user_agent = (string) $req->get('HTTP_USER_AGENT');
289    }
290
291    //
292    // Returns zone offset, like "-0800" for PST.
293    //
294    function _zone_offset () {
295       $offset = date("Z", $this->time);
296       if ($offset < 0)
297       {
298          $negoffset = "-";
299          $offset = -$offset;
300       }
301       $offhours = floor($offset / 3600);
302       $offmins = $offset / 60 - $offhours * 60;
303       return sprintf("%s%02d%02d", $negoffset, $offhours, $offmins);
304    }
305   
306    // Format time into NCSA format.
307    function _ncsa_time($time = false) {
308       if (!$time)
309          $time = time();
310
311       return date("d/M/Y:H:i:s", $time) .
312          " " . $this->_zone_offset();
313    }
314
315    function write($logfile) {
316       $entry = sprintf('%s %s %s [%s] "%s" %d %d "%s" "%s"',
317                        $this->host, $this->ident, $this->user,
318                        $this->_ncsa_time($this->time),
319                        $this->request, $this->status, $this->size,
320                        $this->referer, $this->user_agent);
321       
322       //Error log doesn't provide locking.
323       //error_log("$entry\n", 3, $logfile);
324
325       // Alternate method 
326       if (($fp = fopen($logfile, "a")))
327       {
328          flock($fp, LOCK_EX);
329          fputs($fp, "$entry\n");
330          fclose($fp);
331       }
332    }
333 }
334
335 // Local Variables:
336 // mode: php
337 // tab-width: 8
338 // c-basic-offset: 4
339 // c-hanging-comment-ender-p: nil
340 // indent-tabs-mode: nil
341 // End:   
342 ?>