810 | | * HTTP request method uses fopen function to retrieve the url. |
811 | | * |
812 | | * Requires PHP version greater than 4.3.0 for stream support. Does not allow for $context support, |
813 | | * but should still be okay, to write the headers, before getting the response. Also requires that |
814 | | * 'allow_url_fopen' to be enabled. |
815 | | * |
816 | | * @package WordPress |
817 | | * @subpackage HTTP |
818 | | * @since 2.7.0 |
819 | | */ |
820 | | class WP_Http_Fopen { |
821 | | /** |
822 | | * Send a HTTP request to a URI using fopen(). |
823 | | * |
824 | | * This transport does not support sending of headers and body, therefore should not be used in |
825 | | * the instances, where there is a body and headers. |
826 | | * |
827 | | * Notes: Does not support non-blocking mode. Ignores 'redirection' option. |
828 | | * |
829 | | * @see WP_Http::retrieve For default options descriptions. |
830 | | * |
831 | | * @access public |
832 | | * @since 2.7.0 |
833 | | * |
834 | | * @param string $url URI resource. |
835 | | * @param str|array $args Optional. Override the defaults. |
836 | | * @return array 'headers', 'body', 'cookies' and 'response' keys. |
837 | | */ |
838 | | function request($url, $args = array()) { |
839 | | $defaults = array( |
840 | | 'method' => 'GET', 'timeout' => 5, |
841 | | 'redirection' => 5, 'httpversion' => '1.0', |
842 | | 'blocking' => true, |
843 | | 'headers' => array(), 'body' => null, 'cookies' => array() |
844 | | ); |
845 | | |
846 | | $r = wp_parse_args( $args, $defaults ); |
847 | | |
848 | | $arrURL = parse_url($url); |
849 | | |
850 | | if ( false === $arrURL ) |
851 | | return new WP_Error('http_request_failed', sprintf(__('Malformed URL: %s'), $url)); |
852 | | |
853 | | if ( 'http' != $arrURL['scheme'] && 'https' != $arrURL['scheme'] ) |
854 | | $url = str_replace($arrURL['scheme'], 'http', $url); |
855 | | |
856 | | if ( is_null( $r['headers'] ) ) |
857 | | $r['headers'] = array(); |
858 | | |
859 | | if ( is_string($r['headers']) ) { |
860 | | $processedHeaders = WP_Http::processHeaders($r['headers']); |
861 | | $r['headers'] = $processedHeaders['headers']; |
862 | | } |
863 | | |
864 | | $initial_user_agent = ini_get('user_agent'); |
865 | | |
866 | | if ( !empty($r['headers']) && is_array($r['headers']) ) { |
867 | | $user_agent_extra_headers = ''; |
868 | | foreach ( $r['headers'] as $header => $value ) |
869 | | $user_agent_extra_headers .= "\r\n$header: $value"; |
870 | | @ini_set('user_agent', $r['user-agent'] . $user_agent_extra_headers); |
871 | | } else { |
872 | | @ini_set('user_agent', $r['user-agent']); |
873 | | } |
874 | | |
875 | | if ( !WP_DEBUG ) |
876 | | $handle = @fopen($url, 'r'); |
877 | | else |
878 | | $handle = fopen($url, 'r'); |
879 | | |
880 | | if (! $handle) |
881 | | return new WP_Error('http_request_failed', sprintf(__('Could not open handle for fopen() to %s'), $url)); |
882 | | |
883 | | $timeout = (int) floor( $r['timeout'] ); |
884 | | $utimeout = $timeout == $r['timeout'] ? 0 : 1000000 * $r['timeout'] % 1000000; |
885 | | stream_set_timeout( $handle, $timeout, $utimeout ); |
886 | | |
887 | | if ( ! $r['blocking'] ) { |
888 | | fclose($handle); |
889 | | @ini_set('user_agent', $initial_user_agent); //Clean up any extra headers added |
890 | | return array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
891 | | } |
892 | | |
893 | | $strResponse = ''; |
894 | | while ( ! feof($handle) ) |
895 | | $strResponse .= fread($handle, 4096); |
896 | | |
897 | | if ( function_exists('stream_get_meta_data') ) { |
898 | | $meta = stream_get_meta_data($handle); |
899 | | |
900 | | $theHeaders = $meta['wrapper_data']; |
901 | | if ( isset( $meta['wrapper_data']['headers'] ) ) |
902 | | $theHeaders = $meta['wrapper_data']['headers']; |
903 | | } else { |
904 | | //$http_response_header is a PHP reserved variable which is set in the current-scope when using the HTTP Wrapper |
905 | | //see http://php.oregonstate.edu/manual/en/reserved.variables.httpresponseheader.php |
906 | | $theHeaders = $http_response_header; |
907 | | } |
908 | | |
909 | | fclose($handle); |
910 | | |
911 | | @ini_set('user_agent', $initial_user_agent); //Clean up any extra headers added |
912 | | |
913 | | $processedHeaders = WP_Http::processHeaders($theHeaders); |
914 | | |
915 | | if ( ! empty( $strResponse ) && isset( $processedHeaders['headers']['transfer-encoding'] ) && 'chunked' == $processedHeaders['headers']['transfer-encoding'] ) |
916 | | $strResponse = WP_Http::chunkTransferDecode($strResponse); |
917 | | |
918 | | if ( true === $r['decompress'] && true === WP_Http_Encoding::should_decode($processedHeaders['headers']) ) |
919 | | $strResponse = WP_Http_Encoding::decompress( $strResponse ); |
920 | | |
921 | | return array('headers' => $processedHeaders['headers'], 'body' => $strResponse, 'response' => $processedHeaders['response'], 'cookies' => $processedHeaders['cookies']); |
922 | | } |
923 | | |
924 | | /** |
925 | | * Whether this class can be used for retrieving an URL. |
926 | | * |
927 | | * @since 2.7.0 |
928 | | * @static |
929 | | * @return boolean False means this class can not be used, true means it can. |
930 | | */ |
931 | | function test($args = array()) { |
932 | | if ( ! function_exists('fopen') || (function_exists('ini_get') && true != ini_get('allow_url_fopen')) ) |
933 | | return false; |
934 | | |
935 | | if ( isset($args['method']) && 'HEAD' == $args['method'] ) //This transport cannot make a HEAD request |
936 | | return false; |
937 | | |
938 | | $use = true; |
939 | | //PHP does not verify SSL certs, We can only make a request via this transports if SSL Verification is turned off. |
940 | | $is_ssl = isset($args['ssl']) && $args['ssl']; |
941 | | if ( $is_ssl ) { |
942 | | $is_local = isset($args['local']) && $args['local']; |
943 | | $ssl_verify = isset($args['sslverify']) && $args['sslverify']; |
944 | | if ( $is_local && true != apply_filters('https_local_ssl_verify', true) ) |
945 | | $use = true; |
946 | | elseif ( !$is_local && true != apply_filters('https_ssl_verify', true) ) |
947 | | $use = true; |
948 | | elseif ( !$ssl_verify ) |
949 | | $use = true; |
950 | | else |
951 | | $use = false; |
952 | | } |
953 | | |
954 | | return apply_filters('use_fopen_transport', $use, $args); |
955 | | } |
956 | | } |
957 | | |
958 | | /** |