Subversion Repositories Applications.bazar

Rev

Rev 468 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
468 mathias 1
<?php
2
/* vim: set expandtab tabstop=4 shiftwidth=4 softtabstop=4: */
3
 
4
/**
5
 * HTTP::Header
6
 *
7
 * PHP versions 4 and 5
8
 *
9
 * @category    HTTP
10
 * @package     HTTP_Header
11
 * @author      Wolfram Kriesing <wk@visionp.de>
12
 * @author      Davey Shafik <davey@php.net>
13
 * @author      Michael Wallner <mike@php.net>
14
 * @copyright   2003-2005 The Authors
15
 * @license     BSD, revised
16
 * @version     CVS: $Id$
17
 * @link        http://pear.php.net/package/HTTP_Header
18
 */
19
 
20
/**
21
 * Requires HTTP
22
 */
23
require_once 'HTTP.php';
24
 
25
/**#@+
26
 * Information Codes
27
 */
28
define('HTTP_HEADER_STATUS_100', '100 Continue');
29
define('HTTP_HEADER_STATUS_101', '101 Switching Protocols');
30
define('HTTP_HEADER_STATUS_102', '102 Processing');
31
define('HTTP_HEADER_STATUS_INFORMATIONAL',1);
32
/**#@-*/
33
 
34
/**#+
35
 * Success Codes
36
 */
37
define('HTTP_HEADER_STATUS_200', '200 OK');
38
define('HTTP_HEADER_STATUS_201', '201 Created');
39
define('HTTP_HEADER_STATUS_202', '202 Accepted');
40
define('HTTP_HEADER_STATUS_203', '203 Non-Authoritative Information');
41
define('HTTP_HEADER_STATUS_204', '204 No Content');
42
define('HTTP_HEADER_STATUS_205', '205 Reset Content');
43
define('HTTP_HEADER_STATUS_206', '206 Partial Content');
44
define('HTTP_HEADER_STATUS_207', '207 Multi-Status');
45
define('HTTP_HEADER_STATUS_SUCCESSFUL',2);
46
/**#@-*/
47
 
48
/**#@+
49
 * Redirection Codes
50
 */
51
define('HTTP_HEADER_STATUS_300', '300 Multiple Choices');
52
define('HTTP_HEADER_STATUS_301', '301 Moved Permanently');
53
define('HTTP_HEADER_STATUS_302', '302 Found');
54
define('HTTP_HEADER_STATUS_303', '303 See Other');
55
define('HTTP_HEADER_STATUS_304', '304 Not Modified');
56
define('HTTP_HEADER_STATUS_305', '305 Use Proxy');
57
define('HTTP_HEADER_STATUS_306', '306 (Unused)');
58
define('HTTP_HEADER_STATUS_307', '307 Temporary Redirect');
59
define('HTTP_HEADER_STATUS_REDIRECT',3);
60
/**#@-*/
61
 
62
/**#@+
63
 * Error Codes
64
 */
65
define('HTTP_HEADER_STATUS_400', '400 Bad Request');
66
define('HTTP_HEADER_STATUS_401', '401 Unauthorized');
67
define('HTTP_HEADER_STATUS_402', '402 Payment Granted');
68
define('HTTP_HEADER_STATUS_403', '403 Forbidden');
69
define('HTTP_HEADER_STATUS_404', '404 File Not Found');
70
define('HTTP_HEADER_STATUS_405', '405 Method Not Allowed');
71
define('HTTP_HEADER_STATUS_406', '406 Not Acceptable');
72
define('HTTP_HEADER_STATUS_407', '407 Proxy Authentication Required');
73
define('HTTP_HEADER_STATUS_408', '408 Request Time-out');
74
define('HTTP_HEADER_STATUS_409', '409 Conflict');
75
define('HTTP_HEADER_STATUS_410', '410 Gone');
76
define('HTTP_HEADER_STATUS_411', '411 Length Required');
77
define('HTTP_HEADER_STATUS_412', '412 Precondition Failed');
78
define('HTTP_HEADER_STATUS_413', '413 Request Entity Too Large');
79
define('HTTP_HEADER_STATUS_414', '414 Request-URI Too Large');
80
define('HTTP_HEADER_STATUS_415', '415 Unsupported Media Type');
81
define('HTTP_HEADER_STATUS_416', '416 Requested range not satisfiable');
82
define('HTTP_HEADER_STATUS_417', '417 Expectation Failed');
83
define('HTTP_HEADER_STATUS_422', '422 Unprocessable Entity');
84
define('HTTP_HEADER_STATUS_423', '423 Locked');
85
define('HTTP_HEADER_STATUS_424', '424 Failed Dependency');
86
define('HTTP_HEADER_STATUS_CLIENT_ERROR',4);
87
/**#@-*/
88
 
89
/**#@+
90
 * Server Errors
91
 */
92
define('HTTP_HEADER_STATUS_500', '500 Internal Server Error');
93
define('HTTP_HEADER_STATUS_501', '501 Not Implemented');
94
define('HTTP_HEADER_STATUS_502', '502 Bad Gateway');
95
define('HTTP_HEADER_STATUS_503', '503 Service Unavailable');
96
define('HTTP_HEADER_STATUS_504', '504 Gateway Time-out');
97
define('HTTP_HEADER_STATUS_505', '505 HTTP Version not supported');
98
define('HTTP_HEADER_STATUS_507', '507 Insufficient Storage');
99
define('HTTP_HEADER_STATUS_SERVER_ERROR',5);
100
/**#@-*/
101
 
102
/**
103
 * HTTP_Header
104
 *
105
 * @package     HTTP_Header
106
 * @category    HTTP
107
 * @access      public
108
 * @version     $Revision$
109
 */
110
class HTTP_Header extends HTTP
111
{
112
    /**
113
     * Default Headers
114
     *
115
     * The values that are set as default, are the same as PHP sends by default.
116
     *
117
     * @var     array
118
     * @access  private
119
     */
120
    var $_headers = array(
121
        'content-type'  =>  'text/html',
122
        'pragma'        =>  'no-cache',
123
        'cache-control' =>  'no-store, no-cache, must-revalidate, post-check=0, pre-check=0'
124
    );
125
 
126
    /**
127
     * HTTP version
128
     *
129
     * @var     string
130
     * @access  private
131
     */
132
    var $_httpVersion = '1.0';
133
 
134
    /**
135
     * Constructor
136
     *
137
     * Sets HTTP version.
138
     *
139
     * @access  public
140
     * @return  object  HTTP_Header
141
     */
142
    function HTTP_Header()
143
    {
144
        if (isset($_SERVER['SERVER_PROTOCOL'])) {
145
            $this->setHttpVersion(substr($_SERVER['SERVER_PROTOCOL'], -3));
146
        }
147
    }
148
 
149
    /**
150
     * Set HTTP version
151
     *
152
     * @access  public
153
     * @return  bool    Returns true on success or false if version doesn't
154
     *                  match 1.0 or 1.1 (note: 1 will result in 1.0)
155
     * @param   mixed   $version HTTP version, either 1.0 or 1.1
156
     */
157
    function setHttpVersion($version)
158
    {
159
        $version = round((float) $version, 1);
160
        if ($version < 1.0 || $version > 1.1) {
161
            return false;
162
        }
163
        $this->_httpVersion = sprintf('%0.1f', $version);
164
        return true;
165
    }
166
 
167
    /**
168
     * Get HTTP version
169
     *
170
     * @access  public
171
     * @return  string
172
     */
173
    function getHttpVersion()
174
    {
175
        return $this->_httpVersion;
176
    }
177
 
178
    /**
179
     * Set Header
180
     *
181
     * The default value for the Last-Modified header will be current
182
     * date and atime if $value is omitted.
183
     *
184
     * @access  public
185
     * @return  bool    Returns true on success or false if $key was empty or
186
     *                  $value was not of an scalar type.
187
     * @param   string  $key The name of the header.
188
     * @param   string  $value The value of the header. (NULL to unset header)
189
     */
190
    function setHeader($key, $value = null)
191
    {
192
        if (empty($key) || (isset($value) && !is_scalar($value))) {
193
            return false;
194
        }
195
 
196
        $key = strToLower($key);
197
        if ($key == 'last-modified') {
198
            if (!isset($value)) {
199
                $value = HTTP::Date(time());
200
            } elseif (is_numeric($value)) {
201
                $value = HTTP::Date($value);
202
            }
203
        }
204
 
205
        if (isset($value)) {
206
            $this->_headers[$key] = $value;
207
        } else {
208
            unset($this->_headers[$key]);
209
        }
210
 
211
        return true;
212
    }
213
 
214
    /**
215
     * Get Header
216
     *
217
     * If $key is omitted, all stored headers will be returned.
218
     *
219
     * @access  public
220
     * @return  mixed   Returns string value of the requested header,
221
     *                  array values of all headers or false if header $key
222
     *                  is not set.
223
     * @param   string  $key    The name of the header to fetch.
224
     */
225
    function getHeader($key = null)
226
    {
227
        if (!isset($key)) {
228
            return $this->_headers;
229
        }
230
 
231
        $key = strToLower($key);
232
 
233
        if (!isset($this->_headers[$key])) {
234
            return false;
235
        }
236
 
237
        return $this->_headers[$key];
238
    }
239
 
240
    /**
241
     * Send Headers
242
     *
243
     * Send out the header that you set via setHeader().
244
     *
245
     * @access  public
246
     * @return  bool    Returns true on success or false if headers are already
247
     *                  sent.
248
     * @param   array   $keys Headers to (not) send, see $include.
249
     * @param   array   $include If true only $keys matching headers will be
250
     *                  sent, if false only header not matching $keys will be
251
     *                  sent.
252
     */
253
    function sendHeaders($keys = array(), $include = true)
254
    {
255
        if (headers_sent()) {
256
            return false;
257
        }
258
 
259
        if (count($keys)) {
260
            array_change_key_case($keys, CASE_LOWER);
261
            foreach ($this->_headers as $key => $value) {
262
                if ($include ? in_array($key, $keys) : !in_array($key, $keys)) {
263
                    header($key .': '. $value);
264
                }
265
            }
266
        } else {
267
            foreach ($this->_headers as $header => $value) {
268
                header($header .': '. $value);
269
            }
270
        }
271
        return true;
272
    }
273
 
274
    /**
275
     * Send Satus Code
276
     *
277
     * Send out the given HTTP-Status code. Use this for example when you
278
     * want to tell the client this page is cached, then you would call
279
     * sendStatusCode(304).
280
     *
281
     * @see HTTP_Header_Cache::exitIfCached()
282
     *
283
     * @access  public
284
     * @return  bool    Returns true on success or false if headers are already
285
     *                  sent.
286
     * @param   int     $code The status code to send, i.e. 404, 304, 200, etc.
287
     */
288
    function sendStatusCode($code)
289
    {
290
        if (headers_sent()) {
291
            return false;
292
        }
293
 
294
        if ($code == (int) $code && defined('HTTP_HEADER_STATUS_'. $code)) {
295
            $code = constant('HTTP_HEADER_STATUS_'. $code);
296
        }
297
 
298
        if (strncasecmp(PHP_SAPI, 'cgi', 3)) {
299
            header('HTTP/'. $this->_httpVersion .' '. $code);
300
        } else {
301
            header('Status: '. $code);
302
        }
303
        return true;
304
    }
305
 
306
    /**
307
     * Date to Timestamp
308
     *
309
     * Converts dates like
310
     *      Mon, 31 Mar 2003 15:26:34 GMT
311
     *      Tue, 15 Nov 1994 12:45:26 GMT
312
     * into a timestamp, strtotime() didn't do it in older versions.
313
     *
314
     * @deprecated      Use PHPs strtotime() instead.
315
     * @access  public
316
     * @return  mixed   Returns int unix timestamp or false if the date doesn't
317
     *                  seem to be a valid GMT date.
318
     * @param   string  $date The GMT date.
319
     */
320
    function dateToTimestamp($date)
321
    {
322
        static $months = array(
323
            null => 0, 'Jan' => 1, 'Feb' => 2, 'Mar' => 3, 'Apr' => 4,
324
            'May' => 5, 'Jun' => 6, 'Jul' => 7, 'Aug' => 8, 'Sep' => 9,
325
            'Oct' => 10, 'Nov' => 11, 'Dec' => 12
326
        );
327
 
328
        if (-1 < $timestamp = strToTime($date)) {
329
            return $timestamp;
330
        }
331
 
332
        if (!preg_match('~[^,]*,\s(\d+)\s(\w+)\s(\d+)\s(\d+):(\d+):(\d+).*~',
333
            $date, $m)) {
334
            return false;
335
        }
336
 
337
        // [0] => Mon, 31 Mar 2003 15:42:55 GMT
338
        // [1] => 31 [2] => Mar [3] => 2003 [4] => 15 [5] => 42 [6] => 55
339
        return mktime($m[4], $m[5], $m[6], $months[$m[2]], $m[1], $m[3]);
340
    }
341
 
342
    /**
343
     * Redirect
344
     *
345
     * This function redirects the client. This is done by issuing a Location
346
     * header and exiting.  Additionally to HTTP::redirect() you can also add
347
     * parameters to the url.
348
     *
349
     * If you dont need parameters to be added, simply use HTTP::redirect()
350
     * otherwise use HTTP_Header::redirect().
351
     *
352
     * @see     HTTP::redirect()
353
     * @author  Wolfram Kriesing <wk@visionp.de>
354
     * @access  public
355
     * @return  void
356
     * @param   string  $url The URL to redirect to, if none is given it
357
     *                  redirects to the current page.
358
     * @param   array   $param Array of query string parameters to add; usually
359
     *                  a set of key => value pairs; if an array entry consists
360
     *                  only of an value it is used as key and the respective
361
     *                  value is fetched from $GLOBALS[$value]
362
     * @param   bool    $session Whether the session name/id should be added
363
     */
364
    function redirect($url = null, $param = array(), $session = false)
365
    {
366
        if (!isset($url)) {
367
            $url = $_SERVER['PHP_SELF'];
368
        }
369
 
370
        $qs = array();
371
 
372
        if ($session) {
373
            $qs[] = session_name() .'='. session_id();
374
        }
375
 
376
        if (is_array($param) && count($param)) {
377
            if (count($param)) {
378
                foreach ($param as $key => $val) {
379
                    if (is_string($key)) {
380
                        $qs[] = urlencode($key) .'='. urlencode($val);
381
                    } else {
382
                        $qs[] = urlencode($val) .'='. urlencode(@$GLOBALS[$val]);
383
                    }
384
                }
385
            }
386
        }
387
 
388
        if ($qstr = implode('&', $qs)) {
389
            $purl = parse_url($url);
390
            $url .= (isset($purl['query']) ? '&' : '?') . $qstr;
391
        }
392
 
393
        parent::redirect($url);
394
    }
395
 
396
    /**#@+
397
     * @author  Davey Shafik <davey@php.net>
398
     * @param   int $http_code HTTP Code to check
399
     * @access  public
400
     */
401
 
402
    /**
403
     * Return HTTP Status Code Type
404
     *
405
     * @return int|false
406
     */
407
    function getStatusType($http_code)
408
    {
409
        if(is_int($http_code) && defined('HTTP_HEADER_STATUS_' .$http_code) || defined($http_code)) {
410
            $type = substr($http_code,0,1);
411
            switch ($type) {
412
                case HTTP_HEADER_STATUS_INFORMATIONAL:
413
                case HTTP_HEADER_STATUS_SUCCESSFUL:
414
                case HTTP_HEADER_STATUS_REDIRECT:
415
                case HTTP_HEADER_STATUS_CLIENT_ERROR:
416
                case HTTP_HEADER_STATUS_SERVER_ERROR:
417
                    return $type;
418
                    break;
419
                default:
420
                    return false;
421
                    break;
422
            }
423
        } else {
424
            return false;
425
        }
426
    }
427
 
428
    /**
429
     * Return Status Code Message
430
     *
431
     * @return string|false
432
     */
433
    function getStatusText($http_code)
434
    {
435
        if ($this->getStatusType($http_code)) {
436
            if (is_int($http_code) && defined('HTTP_HEADER_STATUS_' .$http_code)) {
437
                return substr(constant('HTTP_HEADER_STATUS_' .$http_code),4);
438
            } else {
439
                return substr($http_code,4);
440
            }
441
        } else {
442
            return false;
443
        }
444
    }
445
 
446
    /**
447
     * Checks if HTTP Status code is Information (1xx)
448
     *
449
     * @return boolean
450
     */
451
    function isInformational($http_code)
452
    {
453
        if ($status_type = $this->getStatusType($http_code)) {
454
            return $status_type{0} == HTTP_HEADER_STATUS_INFORMATIONAL;
455
        } else {
456
            return false;
457
        }
458
    }
459
 
460
    /**
461
     * Checks if HTTP Status code is Successful (2xx)
462
     *
463
     * @return boolean
464
     */
465
    function isSuccessful($http_code)
466
    {
467
        if ($status_type = $this->getStatusType($http_code)) {
468
            return $status_type{0} == HTTP_HEADER_STATUS_SUCCESSFUL;
469
        } else {
470
            return false;
471
        }
472
    }
473
 
474
    /**
475
     * Checks if HTTP Status code is a Redirect (3xx)
476
     *
477
     * @return boolean
478
     */
479
    function isRedirect($http_code)
480
    {
481
        if ($status_type = $this->getStatusType($http_code)) {
482
            return $status_type{0} == HTTP_HEADER_STATUS_REDIRECT;
483
        } else {
484
            return false;
485
        }
486
    }
487
 
488
    /**
489
     * Checks if HTTP Status code is a Client Error (4xx)
490
     *
491
     * @return boolean
492
     */
493
    function isClientError($http_code)
494
    {
495
        if ($status_type = $this->getStatusType($http_code)) {
496
            return $status_type{0} == HTTP_HEADER_STATUS_CLIENT_ERROR;
497
        } else {
498
            return false;
499
        }
500
    }
501
 
502
    /**
503
     * Checks if HTTP Status code is Server Error (5xx)
504
     *
505
     * @return boolean
506
     */
507
    function isServerError($http_code)
508
    {
509
        if ($status_type = $this->getStatusType($http_code)) {
510
            return $status_type{0} == HTTP_HEADER_STATUS_SERVER_ERROR;
511
        } else {
512
            return false;
513
        }
514
    }
515
 
516
    /**
517
     * Checks if HTTP Status code is Server OR Client Error (4xx or 5xx)
518
     *
519
     * @return boolean
520
     */
521
    function isError($http_code)
522
    {
523
        if ($status_type = $this->getStatusType($http_code)) {
524
            return (($status_type == HTTP_HEADER_STATUS_CLIENT_ERROR) || ($status_type == HTTP_HEADER_STATUS_SERVER_ERROR)) ? true : false;
525
        } else {
526
            return false;
527
        }
528
    }
529
    /**#@-*/
530
}
531
?>