* added redundand join condition for index usage as per comment on CR r88008
[lhc/web/wiklou.git] / includes / HttpFunctions.php
index c73d9a9..33c2916 100644 (file)
@@ -14,7 +14,7 @@ class Http {
         * Perform an HTTP request
         *
         * @param $method String: HTTP method. Usually GET/POST
-        * @param $url String: full URL to act on
+        * @param $url String: full URL to act on. If protocol-relative, will be expanded to an http:// URL
         * @param $options Array: options to pass to MWHttpRequest object.
         *      Possible keys for the array:
         *    - timeout             Timeout length in seconds
@@ -32,7 +32,7 @@ class Http {
         * @return Mixed: (bool)false on failure or a string on success
         */
        public static function request( $method, $url, $options = array() ) {
-               $url = wfExpandUrl( $url );
+               $url = wfExpandUrl( $url, PROTO_HTTP );
                wfDebug( "HTTP: $method: $url\n" );
                $options['method'] = strtoupper( $method );
 
@@ -209,6 +209,15 @@ class MWHttpRequest {
                }
        }
 
+       /**
+        * Simple function to test if we can make any sort of requests at all, using
+        * cURL or fopen()
+        * @return bool
+        */
+       public static function canMakeRequests() {
+               return function_exists( 'curl_init' ) || wfIniGetBool( 'allow_url_fopen' );
+       }
+
        /**
         * Generate a new request object
         * @param $url String: url to use
@@ -273,58 +282,9 @@ class MWHttpRequest {
                        $this->proxy = 'http://localhost:80/';
                } elseif ( $wgHTTPProxy ) {
                        $this->proxy = $wgHTTPProxy ;
-               } elseif ( $this->useProxy( $this->url ) ) {
-                       $this->proxy = $this->useProxy( $this->url );
-               }
-       }
-
-       /**
-        * Determine HTTP proxy from environment settings respecting
-        * 'http_proxy' and 'no_proxy' environment variables
-        */
-       public static function useProxy( $url ) {
-               if ( $proxy = getenv( "http_proxy" ) ) {
-                       $useproxy = true;
-                       if ( $url && ( $noproxy = preg_split( "#\s*,\s*#is", getenv( "no_proxy" ) ) ) ) {
-                               foreach ( $noproxy as $n ) {
-                                       if ( preg_match('#(\d+)\.(\d+)\.(\d+)\.(\d+)/(\d+)#s', $n, $m) &&
-                                                preg_match('#^[a-z0-9_]+://(?:[^/]*:[^/]*@)?([^/@]+)(?:/|$|\?)#is', $url, $ip) ) {
-                                               $mask = array(
-                                                       max( 0x100 - ( 1 << max(  8-$m[5], 0 ) ), 0 ),
-                                                       max( 0x100 - ( 1 << max( 16-$m[5], 0 ) ), 0 ),
-                                                       max( 0x100 - ( 1 << max( 24-$m[5], 0 ) ), 0 ),
-                                                       max( 0x100 - ( 1 << max( 32-$m[5], 0 ) ), 0 ),
-                                               );
-                                               $ip = @gethostbyname( $ip[1] );
-                                               if ( preg_match( '#(\d+)\.(\d+)\.(\d+)\.(\d+)#s', $ip, $ipm ) &&
-                                                       ( intval( $ipm[1] ) & $mask[0] ) == intval( $m[1] ) &&
-                                                       ( intval( $ipm[2] ) & $mask[1] ) == intval( $m[2] ) &&
-                                                       ( intval( $ipm[3] ) & $mask[2] ) == intval( $m[3] ) &&
-                                                       ( intval( $ipm[4] ) & $mask[3] ) == intval( $m[4] ) ) {
-                                                       $useproxy = false;
-                                                       break;
-                                               }
-                                       } else {
-                                               $n = preg_replace( '/#.*$/is', '', $n );
-                                               $n = preg_quote( $n );
-                                               $n = str_replace( '\\*', '.*', $n );
-                                               if ( preg_match( '#'.$n.'#is', $url ) ) {
-                                                       $useproxy = false;
-                                                       break;
-                                               }
-                                       }
-                               }
-                       }
-                       if ( $useproxy ) {
-                               $proxy = preg_replace( '#^http://#is', '', $proxy );
-                               $proxy = preg_replace( '#/*$#is', '', $proxy );
-                       }
-                       else {
-                               $proxy = null;
-                       }
-                       return $proxy;
+               } elseif ( getenv( "http_proxy" ) ) {
+                       $this->proxy = getenv( "http_proxy" );
                }
-               return null;
        }
 
        /**
@@ -421,7 +381,7 @@ class MWHttpRequest {
                }
 
                if ( is_object( $wgTitle ) && !isset( $this->reqHeaders['Referer'] ) ) {
-                       $this->setReferer( $wgTitle->getFullURL() );
+                       $this->setReferer( wfExpandUrl( $wgTitle->getFullURL(), PROTO_CURRENT ) );
                }
 
                if ( !$this->noProxy ) {
@@ -609,13 +569,44 @@ class MWHttpRequest {
        /**
         * Returns the final URL after all redirections.
         *
-        * @return String
+        * Relative values of the "Location" header are incorrect as stated in RFC, however they do happen and modern browsers support them.
+        * This function loops backwards through all locations in order to build the proper absolute URI - Marooned at wikia-inc.com
+        *
+        * @returns string
         */
        public function getFinalUrl() {
-               $location = $this->getResponseHeader( "Location" );
+               $headers = $this->getResponseHeaders();
 
-               if ( $location ) {
-                       return $location;
+               //return full url (fix for incorrect but handled relative location)
+               if ( isset( $headers[ 'location' ] ) ) {
+                       $locations = $headers[ 'location' ];
+                       $domain = '';
+                       $foundRelativeURI = false;
+                       $countLocations = count($locations);
+
+                       for ( $i = $countLocations - 1; $i >= 0; $i-- ) {
+                               $url = parse_url( $locations[ $i ] );
+
+                               if ( isset($url[ 'host' ]) ) {
+                                       $domain = $url[ 'scheme' ] . '://' . $url[ 'host' ];
+                                       break;  //found correct URI (with host)
+                               } else {
+                                       $foundRelativeURI = true;
+                               }
+                       }
+
+                       if ( $foundRelativeURI ) {
+                               if ( $domain ) {
+                                       return $domain . $locations[ $countLocations - 1 ];
+                               } else {
+                                       $url = parse_url( $this->url );
+                                       if ( isset($url[ 'host' ]) ) {
+                                               return $url[ 'scheme' ] . '://' . $url[ 'host' ] . $locations[ $countLocations - 1 ];
+                                       }
+                               }
+                       } else {
+                               return $locations[ $countLocations - 1 ];
+                       }
                }
 
                return $this->url;