WordPress 4.3
[autoinstalls/wordpress.git] / wp-includes / class-http.php
index 8a23836385e7f9d69d509c0b9a40bcad1d812433..5c0829700be416d9f319b4c6debcb365096cc40e 100644 (file)
@@ -5,7 +5,7 @@
  * Standardizes the HTTP requests for WordPress. Handles cookies, gzip encoding and decoding, chunk
  * decoding, if HTTP 1.1 and various other difficult HTTP protocol implementations.
  *
- * @link http://trac.wordpress.org/ticket/4779 HTTP API Proposal
+ * @link https://core.trac.wordpress.org/ticket/4779 HTTP API Proposal
  *
  * @package WordPress
  * @subpackage HTTP
@@ -36,6 +36,8 @@ class WP_Http {
         * @access public
         * @since 2.7.0
         *
+        * @global string $wp_version
+        *
         * @param string       $url  The request URL.
         * @param string|array $args {
         *     Optional. Array or string of HTTP request arguments.
@@ -182,7 +184,9 @@ class WP_Http {
                if ( function_exists( 'wp_kses_bad_protocol' ) ) {
                        if ( $r['reject_unsafe_urls'] )
                                $url = wp_http_validate_url( $url );
-                       $url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) );
+                       if ( $url ) {
+                               $url = wp_kses_bad_protocol( $url, array( 'http', 'https', 'ssl' ) );
+                       }
                }
 
                $arrURL = @parse_url( $url );
@@ -208,8 +212,9 @@ class WP_Http {
                 * If we are streaming to a file but no filename was given drop it in the WP temp dir
                 * and pick its name using the basename of the $url.
                 */
-               if ( $r['stream']  && empty( $r['filename'] ) )
-                       $r['filename'] = get_temp_dir() . basename( $url );
+               if ( $r['stream']  && empty( $r['filename'] ) ) {
+                       $r['filename'] = get_temp_dir() . wp_unique_filename( get_temp_dir(), basename( $url ) );
+               }
 
                /*
                 * Force some settings if we are streaming to a file and check for existence and perms
@@ -225,7 +230,7 @@ class WP_Http {
                        $r['headers'] = array();
 
                if ( ! is_array( $r['headers'] ) ) {
-                       $processedHeaders = WP_Http::processHeaders( $r['headers'], $url );
+                       $processedHeaders = self::processHeaders( $r['headers'], $url );
                        $r['headers'] = $processedHeaders['headers'];
                }
 
@@ -244,7 +249,7 @@ class WP_Http {
                }
 
                // Construct Cookie: header if any cookies are set.
-               WP_Http::buildCookieHeader( $r );
+               self::buildCookieHeader( $r );
 
                // Avoid issues where mbstring.func_overload is enabled.
                mbstring_binary_safe_encoding();
@@ -298,7 +303,7 @@ class WP_Http {
         * @param array $args Request arguments
         * @param string $url URL to Request
         *
-        * @return string|bool Class name for the first transport that claims to support the request. False if no transport claims to support the request.
+        * @return string|false Class name for the first transport that claims to support the request. False if no transport claims to support the request.
         */
        public function _get_first_available_transport( $args, $url = null ) {
                /**
@@ -336,6 +341,8 @@ class WP_Http {
         * The order for requests is cURL, and then PHP Streams.
         *
         * @since 3.2.0
+        *
+        * @static
         * @access private
         *
         * @param string $url URL to Request
@@ -524,6 +531,9 @@ class WP_Http {
                                $cookies[] = new WP_Http_Cookie( $value, $url );
                }
 
+               // Cast the Response Code to an int
+               $response['code'] = intval( $response['code'] );
+
                return array('response' => $response, 'headers' => $newheaders, 'cookies' => $cookies);
        }
 
@@ -615,8 +625,11 @@ class WP_Http {
         * are supported, eg *.wordpress.org will allow for all subdomains of wordpress.org to be contacted.
         *
         * @since 2.8.0
-        * @link http://core.trac.wordpress.org/ticket/8927 Allow preventing external requests.
-        * @link http://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_ACCESSIBLE_HOSTS
+        * @link https://core.trac.wordpress.org/ticket/8927 Allow preventing external requests.
+        * @link https://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_ACCESSIBLE_HOSTS
+        *
+        * @staticvar array|null $accessible_hosts
+        * @staticvar array      $wildcard_regex
         *
         * @param string $uri URI of url.
         * @return bool True to block, false to allow.
@@ -648,9 +661,9 @@ class WP_Http {
                if ( !defined('WP_ACCESSIBLE_HOSTS') )
                        return true;
 
-               static $accessible_hosts;
-               static $wildcard_regex = false;
-               if ( null == $accessible_hosts ) {
+               static $accessible_hosts = null;
+               static $wildcard_regex = array();
+               if ( null === $accessible_hosts ) {
                        $accessible_hosts = preg_split('|,\s*|', WP_ACCESSIBLE_HOSTS);
 
                        if ( false !== strpos(WP_ACCESSIBLE_HOSTS, '*') ) {
@@ -668,23 +681,93 @@ class WP_Http {
 
        }
 
+       /**
+        * A wrapper for PHP's parse_url() function that handles edgecases in < PHP 5.4.7
+        *
+        * PHP 5.4.7 expanded parse_url()'s ability to handle non-absolute url's, including
+        * schemeless and relative url's with :// in the path, this works around those
+        * limitations providing a standard output on PHP 5.2~5.4+.
+        *
+        * Error suppression is used as prior to PHP 5.3.3, an E_WARNING would be generated
+        * when URL parsing failed.
+        *
+        * @since 4.1.0
+        *
+        * @static
+        * @access protected
+        *
+        * @param string $url The URL to parse.
+        * @return bool|array False on failure; Array of URL components on success;
+        *                    See parse_url()'s return values.
+        */
+       protected static function parse_url( $url ) {
+               $parts = @parse_url( $url );
+               if ( ! $parts ) {
+                       // < PHP 5.4.7 compat, trouble with relative paths including a scheme break in the path
+                       if ( '/' == $url[0] && false !== strpos( $url, '://' ) ) {
+                               // Since we know it's a relative path, prefix with a scheme/host placeholder and try again
+                               if ( ! $parts = @parse_url( 'placeholder://placeholder' . $url ) ) {
+                                       return $parts;
+                               }
+                               // Remove the placeholder values
+                               unset( $parts['scheme'], $parts['host'] );
+                       } else {
+                               return $parts;
+                       }
+               }
+
+               // < PHP 5.4.7 compat, doesn't detect schemeless URL's host field
+               if ( '//' == substr( $url, 0, 2 ) && ! isset( $parts['host'] ) ) {
+                       list( $parts['host'], $slashless_path ) = explode( '/', substr( $parts['path'], 2 ), 2 );
+                       $parts['path'] = "/{$slashless_path}";
+               }
+
+               return $parts;
+       }
+
+       /**
+        * Converts a relative URL to an absolute URL relative to a given URL.
+        *
+        * If an Absolute URL is provided, no processing of that URL is done.
+        *
+        * @since 3.4.0
+        *
+        * @static
+        * @access public
+        *
+        * @param string $maybe_relative_path The URL which might be relative
+        * @param string $url                 The URL which $maybe_relative_path is relative to
+        * @return string An Absolute URL, in a failure condition where the URL cannot be parsed, the relative URL will be returned.
+        */
        public static function make_absolute_url( $maybe_relative_path, $url ) {
                if ( empty( $url ) )
                        return $maybe_relative_path;
 
-               // Check for a scheme.
-               if ( false !== strpos( $maybe_relative_path, '://' ) )
+               if ( ! $url_parts = WP_HTTP::parse_url( $url ) ) {
                        return $maybe_relative_path;
+               }
 
-               if ( ! $url_parts = @parse_url( $url ) )
+               if ( ! $relative_url_parts = WP_HTTP::parse_url( $maybe_relative_path ) ) {
                        return $maybe_relative_path;
+               }
 
-               if ( ! $relative_url_parts = @parse_url( $maybe_relative_path ) )
+               // Check for a scheme on the 'relative' url
+               if ( ! empty( $relative_url_parts['scheme'] ) ) {
                        return $maybe_relative_path;
+               }
+
+               $absolute_path = $url_parts['scheme'] . '://';
 
-               $absolute_path = $url_parts['scheme'] . '://' . $url_parts['host'];
-               if ( isset( $url_parts['port'] ) )
-                       $absolute_path .= ':' . $url_parts['port'];
+               // Schemeless URL's will make it this far, so we check for a host in the relative url and convert it to a protocol-url
+               if ( isset( $relative_url_parts['host'] ) ) {
+                       $absolute_path .= $relative_url_parts['host'];
+                       if ( isset( $relative_url_parts['port'] ) )
+                               $absolute_path .= ':' . $relative_url_parts['port'];
+               } else {
+                       $absolute_path .= $url_parts['host'];
+                       if ( isset( $url_parts['port'] ) )
+                               $absolute_path .= ':' . $url_parts['port'];
+               }
 
                // Start off with the Absolute URL path.
                $path = ! empty( $url_parts['path'] ) ? $url_parts['path'] : '/';
@@ -722,6 +805,8 @@ class WP_Http {
         *
         * @since 3.7.0
         *
+        * @static
+        *
         * @param string $url The URL which was requested.
         * @param array $args The Arguments which were used to make the request.
         * @param array $response The Response of the HTTP request.
@@ -823,12 +908,12 @@ class WP_Http_Streams {
 
                $r = wp_parse_args( $args, $defaults );
 
-               if ( isset($r['headers']['User-Agent']) ) {
+               if ( isset( $r['headers']['User-Agent'] ) ) {
                        $r['user-agent'] = $r['headers']['User-Agent'];
-                       unset($r['headers']['User-Agent']);
-               } else if ( isset($r['headers']['user-agent']) ) {
+                       unset( $r['headers']['User-Agent'] );
+               } elseif ( isset( $r['headers']['user-agent'] ) ) {
                        $r['user-agent'] = $r['headers']['user-agent'];
-                       unset($r['headers']['user-agent']);
+                       unset( $r['headers']['user-agent'] );
                }
 
                // Construct Cookie: header if any cookies are set.
@@ -848,6 +933,11 @@ class WP_Http_Streams {
                        }
                }
 
+               // Always pass a Path, defaulting to the root in cases such as http://example.com
+               if ( ! isset( $arrURL['path'] ) ) {
+                       $arrURL['path'] = '/';
+               }
+
                if ( isset( $r['headers']['Host'] ) || isset( $r['headers']['host'] ) ) {
                        if ( isset( $r['headers']['Host'] ) )
                                $arrURL['host'] = $r['headers']['Host'];
@@ -952,15 +1042,19 @@ class WP_Http_Streams {
                else
                        $requestPath = $arrURL['path'] . ( isset($arrURL['query']) ? '?' . $arrURL['query'] : '' );
 
-               if ( empty($requestPath) )
-                       $requestPath .= '/';
-
                $strHeaders = strtoupper($r['method']) . ' ' . $requestPath . ' HTTP/' . $r['httpversion'] . "\r\n";
 
-               if ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) )
+               $include_port_in_host_header = (
+                       ( $proxy->is_enabled() && $proxy->send_through_proxy( $url ) ) ||
+                       ( 'http'  == $arrURL['scheme'] && 80  != $arrURL['port'] ) ||
+                       ( 'https' == $arrURL['scheme'] && 443 != $arrURL['port'] )
+               );
+
+               if ( $include_port_in_host_header ) {
                        $strHeaders .= 'Host: ' . $arrURL['host'] . ':' . $arrURL['port'] . "\r\n";
-               else
+               } else {
                        $strHeaders .= 'Host: ' . $arrURL['host'] . "\r\n";
+               }
 
                if ( isset($r['user-agent']) )
                        $strHeaders .= 'User-agent: ' . $r['user-agent'] . "\r\n";
@@ -1020,8 +1114,10 @@ class WP_Http_Streams {
 
                                $this_block_size = strlen( $block );
 
-                               if ( isset( $r['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $r['limit_response_size'] )
-                                       $block = substr( $block, 0, ( $r['limit_response_size'] - $bytes_written ) );
+                               if ( isset( $r['limit_response_size'] ) && ( $bytes_written + $this_block_size ) > $r['limit_response_size'] ) {
+                                       $this_block_size = ( $r['limit_response_size'] - $bytes_written );
+                                       $block = substr( $block, 0, $this_block_size );
+                               }
 
                                $bytes_written_to_file = fwrite( $stream_handle, $block );
 
@@ -1159,7 +1255,7 @@ class WP_Http_Streams {
         * @since 2.7.0
         * @since 3.7.0 Combined with the fsockopen transport and switched to stream_socket_client().
         *
-        * @return boolean False means this class can not be used, true means it can.
+        * @return bool False means this class can not be used, true means it can.
         */
        public static function test( $args = array() ) {
                if ( ! function_exists( 'stream_socket_client' ) )
@@ -1248,6 +1344,15 @@ class WP_Http_Curl {
         */
        private $stream_handle = false;
 
+       /**
+        * The total bytes written in the current request.
+        *
+        * @since 4.1.0
+        * @access private
+        * @var int
+        */
+       private $bytes_written_total = 0;
+
        /**
         * Send a HTTP request to a URI using cURL extension.
         *
@@ -1268,12 +1373,12 @@ class WP_Http_Curl {
 
                $r = wp_parse_args( $args, $defaults );
 
-               if ( isset($r['headers']['User-Agent']) ) {
+               if ( isset( $r['headers']['User-Agent'] ) ) {
                        $r['user-agent'] = $r['headers']['User-Agent'];
-                       unset($r['headers']['User-Agent']);
-               } else if ( isset($r['headers']['user-agent']) ) {
+                       unset( $r['headers']['User-Agent'] );
+               } elseif ( isset( $r['headers']['user-agent'] ) ) {
                        $r['user-agent'] = $r['headers']['user-agent'];
-                       unset($r['headers']['user-agent']);
+                       unset( $r['headers']['user-agent'] );
                }
 
                // Construct Cookie: header if any cookies are set.
@@ -1420,21 +1525,32 @@ class WP_Http_Curl {
                curl_exec( $handle );
                $theHeaders = WP_Http::processHeaders( $this->headers, $url );
                $theBody = $this->body;
+               $bytes_written_total = $this->bytes_written_total;
 
                $this->headers = '';
                $this->body = '';
+               $this->bytes_written_total = 0;
 
                $curl_error = curl_errno( $handle );
 
                // If an error occurred, or, no response.
                if ( $curl_error || ( 0 == strlen( $theBody ) && empty( $theHeaders['headers'] ) ) ) {
-                       if ( CURLE_WRITE_ERROR /* 23 */ == $curl_error &&  $r['stream'] ) {
-                               fclose( $this->stream_handle );
-                               return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) );
-                       }
-                       if ( $curl_error = curl_error( $handle ) ) {
-                               curl_close( $handle );
-                               return new WP_Error( 'http_request_failed', $curl_error );
+                       if ( CURLE_WRITE_ERROR /* 23 */ == $curl_error ) {
+                               if ( ! $this->max_body_length || $this->max_body_length != $bytes_written_total ) {
+                                       if ( $r['stream'] ) {
+                                               curl_close( $handle );
+                                               fclose( $this->stream_handle );
+                                               return new WP_Error( 'http_request_failed', __( 'Failed to write request to temporary file.' ) );
+                                       } else {
+                                               curl_close( $handle );
+                                               return new WP_Error( 'http_request_failed', curl_error( $handle ) );
+                                       }
+                               }
+                       } else {
+                               if ( $curl_error = curl_error( $handle ) ) {
+                                       curl_close( $handle );
+                                       return new WP_Error( 'http_request_failed', $curl_error );
+                               }
                        }
                        if ( in_array( curl_getinfo( $handle, CURLINFO_HTTP_CODE ), array( 301, 302 ) ) ) {
                                curl_close( $handle );
@@ -1442,10 +1558,6 @@ class WP_Http_Curl {
                        }
                }
 
-               $response = array();
-               $response['code'] = curl_getinfo( $handle, CURLINFO_HTTP_CODE );
-               $response['message'] = get_status_header_desc($response['code']);
-
                curl_close( $handle );
 
                if ( $r['stream'] )
@@ -1454,7 +1566,7 @@ class WP_Http_Curl {
                $response = array(
                        'headers' => $theHeaders['headers'],
                        'body' => null,
-                       'response' => $response,
+                       'response' => $theHeaders['response'],
                        'cookies' => $theHeaders['cookies'],
                        'filename' => $r['filename']
                );
@@ -1489,7 +1601,7 @@ class WP_Http_Curl {
         * Grab the body of the cURL request
         *
         * The contents of the document are passed in chunks, so we append to the $body property for temporary storage.
-        * Returning a length shorter than the length of $data passed in will cause cURL to abort the request as "completed"
+        * Returning a length shorter than the length of $data passed in will cause cURL to abort the request with CURLE_WRITE_ERROR
         *
         * @since 3.6.0
         * @access private
@@ -1498,8 +1610,10 @@ class WP_Http_Curl {
        private function stream_body( $handle, $data ) {
                $data_length = strlen( $data );
 
-               if ( $this->max_body_length && ( strlen( $this->body ) + $data_length ) > $this->max_body_length )
-                       $data = substr( $data, 0, ( $this->max_body_length - $data_length ) );
+               if ( $this->max_body_length && ( $this->bytes_written_total + $data_length ) > $this->max_body_length ) {
+                       $data_length = ( $this->max_body_length - $this->bytes_written_total );
+                       $data = substr( $data, 0, $data_length );
+               }
 
                if ( $this->stream_handle ) {
                        $bytes_written = fwrite( $this->stream_handle, $data );
@@ -1508,6 +1622,8 @@ class WP_Http_Curl {
                        $bytes_written = $data_length;
                }
 
+               $this->bytes_written_total += $bytes_written;
+
                // Upon event of this function returning less than strlen( $data ) curl will error with CURLE_WRITE_ERROR.
                return $bytes_written;
        }
@@ -1518,7 +1634,7 @@ class WP_Http_Curl {
         * @static
         * @since 2.7.0
         *
-        * @return boolean False means this class can not be used, true means it can.
+        * @return bool False means this class can not be used, true means it can.
         */
        public static function test( $args = array() ) {
                if ( ! function_exists( 'curl_init' ) || ! function_exists( 'curl_exec' ) )
@@ -1567,14 +1683,13 @@ class WP_Http_Curl {
  * </ol>
  *
  * An example can be as seen below.
- * <code>
- * define('WP_PROXY_HOST', '192.168.84.101');
- * define('WP_PROXY_PORT', '8080');
- * define('WP_PROXY_BYPASS_HOSTS', 'localhost, www.example.com, *.wordpress.org');
- * </code>
  *
- * @link http://core.trac.wordpress.org/ticket/4011 Proxy support ticket in WordPress.
- * @link http://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_PROXY_BYPASS_HOSTS
+ *     define('WP_PROXY_HOST', '192.168.84.101');
+ *     define('WP_PROXY_PORT', '8080');
+ *     define('WP_PROXY_BYPASS_HOSTS', 'localhost, www.example.com, *.wordpress.org');
+ *
+ * @link https://core.trac.wordpress.org/ticket/4011 Proxy support ticket in WordPress.
+ * @link https://core.trac.wordpress.org/ticket/14636 Allow wildcard domains in WP_PROXY_BYPASS_HOSTS
  * @since 2.8.0
  */
 class WP_HTTP_Proxy {
@@ -1692,9 +1807,11 @@ class WP_HTTP_Proxy {
         * some proxies can not handle this. We also have the constant available for defining other
         * hosts that won't be sent through the proxy.
         *
-        * @uses WP_PROXY_BYPASS_HOSTS
         * @since 2.8.0
         *
+        * @staticvar array|null $bypass_hosts
+        * @staticvar array      $wildcard_regex
+        *
         * @param string $uri URI to check.
         * @return bool True, to send through the proxy and false if, the proxy should not be used.
         */
@@ -1734,9 +1851,9 @@ class WP_HTTP_Proxy {
                if ( !defined('WP_PROXY_BYPASS_HOSTS') )
                        return true;
 
-               static $bypass_hosts;
-               static $wildcard_regex = false;
-               if ( null == $bypass_hosts ) {
+               static $bypass_hosts = null;
+               static $wildcard_regex = array();
+               if ( null === $bypass_hosts ) {
                        $bypass_hosts = preg_split('|,\s*|', WP_PROXY_BYPASS_HOSTS);
 
                        if ( false !== strpos(WP_PROXY_BYPASS_HOSTS, '*') ) {
@@ -1868,7 +1985,7 @@ class WP_Http_Cookie {
                        }
                } else {
                        if ( !isset( $data['name'] ) )
-                               return false;
+                               return;
 
                        // Set properties based directly on parameters.
                        foreach ( array( 'name', 'value', 'path', 'domain', 'port' ) as $field ) {
@@ -1892,7 +2009,7 @@ class WP_Http_Cookie {
         * @since 2.8.0
         *
         * @param string $url URL you intend to send this cookie to
-        * @return boolean true if allowed, false otherwise.
+        * @return bool true if allowed, false otherwise.
         */
        public function test( $url ) {
                if ( is_null( $this->name ) )
@@ -1984,10 +2101,12 @@ class WP_Http_Encoding {
         *
         * @since 2.8.0
         *
+        * @static
+        *
         * @param string $raw String to compress.
         * @param int $level Optional, default is 9. Compression level, 9 is highest.
         * @param string $supports Optional, not used. When implemented it will choose the right compression based on what the server supports.
-        * @return string|bool False on failure.
+        * @return string|false False on failure.
         */
        public static function compress( $raw, $level = 9, $supports = null ) {
                return gzdeflate( $raw, $level );
@@ -2003,6 +2122,8 @@ class WP_Http_Encoding {
         *
         * @since 2.8.0
         *
+        * @static
+        *
         * @param string $compressed String to decompress.
         * @param int $length The optional length of the compressed data.
         * @return string|bool False on failure.
@@ -2015,7 +2136,7 @@ class WP_Http_Encoding {
                if ( false !== ( $decompressed = @gzinflate( $compressed ) ) )
                        return $decompressed;
 
-               if ( false !== ( $decompressed = WP_Http_Encoding::compatible_gzinflate( $compressed ) ) )
+               if ( false !== ( $decompressed = self::compatible_gzinflate( $compressed ) ) )
                        return $decompressed;
 
                if ( false !== ( $decompressed = @gzuncompress( $compressed ) ) )
@@ -2041,13 +2162,15 @@ class WP_Http_Encoding {
         * Warning: Magic numbers within. Due to the potential different formats that the compressed
         * data may be returned in, some "magic offsets" are needed to ensure proper decompression
         * takes place. For a simple progmatic way to determine the magic offset in use, see:
-        * http://core.trac.wordpress.org/ticket/18273
+        * https://core.trac.wordpress.org/ticket/18273
         *
         * @since 2.8.1
-        * @link http://core.trac.wordpress.org/ticket/18273
+        * @link https://core.trac.wordpress.org/ticket/18273
         * @link http://au2.php.net/manual/en/function.gzinflate.php#70875
         * @link http://au2.php.net/manual/en/function.gzinflate.php#77336
         *
+        * @static
+        *
         * @param string $gzData String to decompress.
         * @return string|bool False on failure.
         */
@@ -2087,11 +2210,15 @@ class WP_Http_Encoding {
         *
         * @since 2.8.0
         *
+        * @static
+        *
+        * @param string $url
+        * @param array  $args
         * @return string Types of encoding to accept.
         */
        public static function accept_encoding( $url, $args ) {
                $type = array();
-               $compression_enabled = WP_Http_Encoding::is_available();
+               $compression_enabled = self::is_available();
 
                if ( ! $args['decompress'] ) // Decompression specifically disabled.
                        $compression_enabled = false;
@@ -2131,6 +2258,8 @@ class WP_Http_Encoding {
         *
         * @since 2.8.0
         *
+        * @static
+        *
         * @return string Content-Encoding string to send in the header.
         */
        public static function content_encoding() {
@@ -2142,6 +2271,8 @@ class WP_Http_Encoding {
         *
         * @since 2.8.0
         *
+        * @static
+        *
         * @param array|string $headers All of the available headers.
         * @return bool
         */
@@ -2149,7 +2280,7 @@ class WP_Http_Encoding {
                if ( is_array( $headers ) ) {
                        if ( array_key_exists('content-encoding', $headers) && ! empty( $headers['content-encoding'] ) )
                                return true;
-               } else if ( is_string( $headers ) ) {
+               } elseif ( is_string( $headers ) ) {
                        return ( stripos($headers, 'content-encoding:') !== false );
                }
 
@@ -2165,6 +2296,8 @@ class WP_Http_Encoding {
         *
         * @since 2.8.0
         *
+        * @static
+        *
         * @return bool
         */
        public static function is_available() {