HTTP.php 7.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210
  1. <?php
  2. //
  3. // +----------------------------------------------------------------------+
  4. // | PHP Version 4 |
  5. // +----------------------------------------------------------------------+
  6. // | Copyright (c) 1997-2003 The PHP Group |
  7. // +----------------------------------------------------------------------+
  8. // | This source file is subject to version 2.02 of the PHP license, |
  9. // | that is bundled with this package in the file LICENSE, and is |
  10. // | available at through the world-wide-web at |
  11. // | http://www.php.net/license/2_02.txt. |
  12. // | If you did not receive a copy of the PHP license and are unable to |
  13. // | obtain it through the world-wide-web, please send a note to |
  14. // | license@php.net so we can mail you a copy immediately. |
  15. // +----------------------------------------------------------------------+
  16. // | Authors: Stig Bakken <ssb@fast.no> |
  17. // | |
  18. // +----------------------------------------------------------------------+
  19. //
  20. // $Id: HTTP.php,v 1.20 2003/12/09 12:27:47 pajoye Exp $
  21. //
  22. // HTTP utility functions.
  23. //
  24. class HTTP
  25. {
  26. /**
  27. * Format a RFC compliant HTTP header. This function
  28. * honors the "y2k_compliance" php.ini directive.
  29. *
  30. * @param int $time UNIX timestamp
  31. *
  32. * @return mixed HTTP date string, or false for an invalid timestamp.
  33. *
  34. * @author Stig Bakken <ssb@fast.no>
  35. * @author Sterling Hughes <sterling@php.net>
  36. */
  37. function Date($time)
  38. {
  39. /* If we're y2k compliant, use the newer, reccomended RFC 822
  40. format */
  41. if (ini_get("y2k_compliance") == true) {
  42. return gmdate("D, d M Y H:i:s \G\M\T", $time);
  43. }
  44. /* Use RFC-850 which supports two character year numbers */
  45. else {
  46. return gmdate("F, d-D-y H:i:s \G\M\T", $time);
  47. }
  48. }
  49. /**
  50. * Negotiate language with the user's browser through the
  51. * Accept-Language HTTP header or the user's host address.
  52. * Language codes are generally in the form "ll" for a language
  53. * spoken in only one country, or "ll-CC" for a language spoken in
  54. * a particular country. For example, U.S. English is "en-US",
  55. * while British English is "en-UK". Portugese as spoken in
  56. * Portugal is "pt-PT", while Brazilian Portugese is "pt-BR".
  57. * Two-letter country codes can be found in the ISO 3166 standard.
  58. *
  59. * Quantities in the Accept-Language: header are supported, for
  60. * example:
  61. *
  62. * Accept-Language: en-UK;q=0.7, en-US;q=0.6, no;q=1.0, dk;q=0.8
  63. *
  64. * @param array $supported an associative array indexed by language
  65. * codes (country codes) supported by the application. Values
  66. * must evaluate to true.
  67. *
  68. * @param string $default the default language to use if none is found
  69. * during negotiation, defaults to "en-US" for U.S. English
  70. *
  71. * @return string the negotiated language result
  72. *
  73. * @author Stig Bakken <ssb@fast.no>
  74. */
  75. function negotiateLanguage(&$supported, $default = 'en-US')
  76. {
  77. global $HTTP_SERVER_VARS;
  78. $supported = array_change_key_case($supported, CASE_LOWER);
  79. /* If the client has sent an Accept-Language: header, see if
  80. * it contains a language we support.
  81. */
  82. if (isset($HTTP_SERVER_VARS['HTTP_ACCEPT_LANGUAGE'])) {
  83. $accepted = split(',[[:space:]]*', $HTTP_SERVER_VARS['HTTP_ACCEPT_LANGUAGE']);
  84. for ($i = 0; $i < count($accepted); $i++) {
  85. if (eregi('^([a-z_-]+);[[:space:]]*q=([0-9\.]+)', $accepted[$i], $arr)) {
  86. $q = (double)$arr[2];
  87. $l = $arr[1];
  88. } else {
  89. $q = 42;
  90. $l = strtolower($accepted[$i]);
  91. }
  92. if (!empty($supported[$l]) && ($q > 0.0)) {
  93. if ($q == 42) {
  94. return $l;
  95. }
  96. $candidates[$l] = $q;
  97. }
  98. }
  99. if (isset($candidates)) {
  100. arsort($candidates);
  101. reset($candidates);
  102. return key($candidates);
  103. }
  104. }
  105. /* Check for a valid language code in the top-level domain of
  106. * the client's host address.
  107. */
  108. if (isset($HTTP_SERVER_VARS['REMOTE_HOST']) &&
  109. ereg("\.[^\.]+$", $HTTP_SERVER_VARS['REMOTE_HOST'], $arr)) {
  110. $lang = strtolower($arr[1]);
  111. if (!empty($supported[$lang])) {
  112. return $lang;
  113. }
  114. }
  115. return $default;
  116. }
  117. /**
  118. * Sends a "HEAD" HTTP command to a server and returns the headers
  119. * as an associative array. Example output could be:
  120. * Array
  121. * (
  122. * [response_code] => 200 // The HTTP response code
  123. * [response] => HTTP/1.1 200 OK // The full HTTP response string
  124. * [Date] => Fri, 11 Jan 2002 01:41:44 GMT
  125. * [Server] => Apache/1.3.20 (Unix) PHP/4.1.1
  126. * [X-Powered-By] => PHP/4.1.1
  127. * [Connection] => close
  128. * [Content-Type] => text/html
  129. * )
  130. *
  131. * @param string $url A valid url, for ex: http://pear.php.net/credits.php
  132. * @return mixed Assoc array or PEAR error
  133. *
  134. * @author Tomas V.V.Cox <cox@idecnet.com>
  135. */
  136. function head($url)
  137. {
  138. $purl = parse_url($url);
  139. $port = (isset($purl['port'])) ? $purl['port'] : 80;
  140. $fp = fsockopen($purl['host'], $port, $errno, $errstr, 10);
  141. if (!$fp) {
  142. include_once "PEAR.php";
  143. return PEAR::raiseError("HTTP::head Error $errstr ($erno)");
  144. }
  145. $path = (!empty($purl['path'])) ? $purl['path'] : '/';
  146. fputs($fp, "HEAD $path HTTP/1.0\r\n");
  147. fputs($fp, "Host: " . $purl['host'] . "\r\n");
  148. fputs($fp, "Connection: close\r\n\r\n");
  149. $response = rtrim(fgets($fp, 4096));
  150. if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|", $response, $status)) {
  151. $headers['response_code'] = $status[1];
  152. }
  153. $headers['response'] = $response;
  154. while ($line = fgets($fp, 4096)) {
  155. if (!trim($line)) {
  156. break;
  157. }
  158. if (($pos = strpos($line, ':')) !== false) {
  159. $header = substr($line, 0, $pos);
  160. $value = trim(substr($line, $pos + 1));
  161. $headers[$header] = $value;
  162. }
  163. }
  164. fclose($fp);
  165. return $headers;
  166. }
  167. /**
  168. * This function redirects the client. This is done by issuing
  169. * a Location: header and exiting.
  170. *
  171. * @author Richard Heyes <richard@php.net>
  172. * @param string $url URL where the redirect should go to
  173. */
  174. function redirect($url)
  175. {
  176. global $HTTP_SERVER_VARS;
  177. if (!preg_match('/^(https?|ftp):\/\//', $url)) {
  178. $server = 'http' . (@$HTTP_SERVER_VARS['HTTPS'] == 'on' ? 's' : '') . '://' . $HTTP_SERVER_VARS['SERVER_NAME'];
  179. if ($HTTP_SERVER_VARS['SERVER_PORT'] != 80 &&
  180. $HTTP_SERVER_VARS['SERVER_PORT'] != 443) {
  181. $server .= ':' . $HTTP_SERVER_VARS['SERVER_PORT'];
  182. }
  183. $path = dirname($HTTP_SERVER_VARS['PHP_SELF']);
  184. if ($url{0} != '/') {
  185. $path .= $url;
  186. $server .= dirname($HTTP_SERVER_VARS['PHP_SELF']);
  187. $url = $server . '/' . preg_replace('!^\./!', '', $url);
  188. } else {
  189. $url = $server . $url;
  190. }
  191. }
  192. header('Location: ' . $url);
  193. exit;
  194. }
  195. }
  196. ?>