Doxygen fixes:
[lhc/web/wiklou.git] / includes / HttpFunctions.php
1 <?php
2 /**
3 * @defgroup HTTP HTTP
4 */
5
6 /**
7 * Various HTTP related functions
8 * @ingroup HTTP
9 */
10 class Http {
11
12 /**
13 * Simple wrapper for Http::request( 'GET' )
14 * @see Http::request()
15 */
16 public static function get( $url, $timeout = 'default', $opts = array() ) {
17 return Http::request( "GET", $url, $timeout, $opts );
18 }
19
20 /**
21 * Simple wrapper for Http::request( 'POST' )
22 * @see Http::request()
23 */
24 public static function post( $url, $timeout = 'default', $opts = array() ) {
25 return Http::request( "POST", $url, $timeout, $opts );
26 }
27
28 /**
29 * Get the contents of a file by HTTP
30 * @param $method string HTTP method. Usually GET/POST
31 * @param $url string Full URL to act on
32 * @param $timeout int Seconds to timeout. 'default' falls to $wgHTTPTimeout
33 * @param $curlOptions array Optional array of extra params to pass
34 * to curl_setopt()
35 */
36 public static function request( $method, $url, $timeout = 'default', $curlOptions = array() ) {
37 global $wgHTTPTimeout, $wgHTTPProxy, $wgTitle;
38
39 // Go ahead and set the timeout if not otherwise specified
40 if ( $timeout == 'default' ) {
41 $timeout = $wgHTTPTimeout;
42 }
43
44 wfDebug( __METHOD__ . ": $method $url\n" );
45 # Use curl if available
46 if ( function_exists( 'curl_init' ) ) {
47 $c = curl_init( $url );
48 if ( self::isLocalURL( $url ) ) {
49 curl_setopt( $c, CURLOPT_PROXY, 'localhost:80' );
50 } else if ($wgHTTPProxy) {
51 curl_setopt($c, CURLOPT_PROXY, $wgHTTPProxy);
52 }
53
54 curl_setopt( $c, CURLOPT_TIMEOUT, $timeout );
55 curl_setopt( $c, CURLOPT_USERAGENT, self :: userAgent() );
56 if ( $method == 'POST' ) {
57 curl_setopt( $c, CURLOPT_POST, true );
58 curl_setopt( $c, CURLOPT_POSTFIELDS, '' );
59 }
60 else
61 curl_setopt( $c, CURLOPT_CUSTOMREQUEST, $method );
62
63 # Set the referer to $wgTitle, even in command-line mode
64 # This is useful for interwiki transclusion, where the foreign
65 # server wants to know what the referring page is.
66 # $_SERVER['REQUEST_URI'] gives a less reliable indication of the
67 # referring page.
68 if ( is_object( $wgTitle ) ) {
69 curl_setopt( $c, CURLOPT_REFERER, $wgTitle->getFullURL() );
70 }
71
72 if ( is_array( $curlOptions ) ) {
73 foreach( $curlOptions as $option => $value ) {
74 curl_setopt( $c, $option, $value );
75 }
76 }
77
78 ob_start();
79 curl_exec( $c );
80 $text = ob_get_contents();
81 ob_end_clean();
82
83 # Don't return the text of error messages, return false on error
84 $retcode = curl_getinfo( $c, CURLINFO_HTTP_CODE );
85 if ( $retcode != 200 ) {
86 wfDebug( __METHOD__ . ": HTTP return code $retcode\n" );
87 $text = false;
88 }
89 # Don't return truncated output
90 $errno = curl_errno( $c );
91 if ( $errno != CURLE_OK ) {
92 $errstr = curl_error( $c );
93 wfDebug( __METHOD__ . ": CURL error code $errno: $errstr\n" );
94 $text = false;
95 }
96 curl_close( $c );
97 } else {
98 # Otherwise use file_get_contents...
99 # This doesn't have local fetch capabilities...
100
101 $headers = array( "User-Agent: " . self :: userAgent() );
102 if( strcasecmp( $method, 'post' ) == 0 ) {
103 // Required for HTTP 1.0 POSTs
104 $headers[] = "Content-Length: 0";
105 }
106 $opts = array(
107 'http' => array(
108 'method' => $method,
109 'header' => implode( "\r\n", $headers ),
110 'timeout' => $timeout ) );
111 $ctx = stream_context_create($opts);
112
113 $text = file_get_contents( $url, false, $ctx );
114 }
115 return $text;
116 }
117
118 /**
119 * Check if the URL can be served by localhost
120 * @param $url string Full url to check
121 * @return bool
122 */
123 public static function isLocalURL( $url ) {
124 global $wgCommandLineMode, $wgConf;
125 if ( $wgCommandLineMode ) {
126 return false;
127 }
128
129 // Extract host part
130 $matches = array();
131 if ( preg_match( '!^http://([\w.-]+)[/:].*$!', $url, $matches ) ) {
132 $host = $matches[1];
133 // Split up dotwise
134 $domainParts = explode( '.', $host );
135 // Check if this domain or any superdomain is listed in $wgConf as a local virtual host
136 $domainParts = array_reverse( $domainParts );
137 for ( $i = 0; $i < count( $domainParts ); $i++ ) {
138 $domainPart = $domainParts[$i];
139 if ( $i == 0 ) {
140 $domain = $domainPart;
141 } else {
142 $domain = $domainPart . '.' . $domain;
143 }
144 if ( $wgConf->isLocalVHost( $domain ) ) {
145 return true;
146 }
147 }
148 }
149 return false;
150 }
151
152 /**
153 * Return a standard user-agent we can use for external requests.
154 */
155 public static function userAgent() {
156 global $wgVersion;
157 return "MediaWiki/$wgVersion";
158 }
159 }