| 41 | | * PHP4 style Constructor - Calls PHP5 Style Constructor |
| 42 | | * |
| 43 | | * @since 2.7.0 |
| 44 | | * @return WP_Http |
| 45 | | */ |
| 46 | | function WP_Http() { |
| 47 | | $this->__construct(); |
| 48 | | } |
| 49 | | |
| 50 | | /** |
| 51 | | * PHP5 style Constructor - Set up available transport if not available. |
| 52 | | * |
| 53 | | * PHP4 does not have the 'self' keyword and since WordPress supports PHP4, the class needs to |
| 54 | | * be used for the static call. The transport are set up to save time and will only be created |
| 55 | | * once. This class can be created many times without having to go through the step of finding |
| 56 | | * which transports are available. |
| 57 | | * |
| 58 | | * @since 2.7.0 |
| 59 | | * @return WP_Http |
| 60 | | */ |
| 61 | | function __construct() { |
| 62 | | WP_Http::_getTransport(); |
| 63 | | WP_Http::_postTransport(); |
| 64 | | } |
| 65 | | |
| 66 | | /** |
| 67 | | * Tests the WordPress HTTP objects for an object to use and returns it. |
| 68 | | * |
| 69 | | * Tests all of the objects and returns the object that passes. Also caches that object to be |
| 70 | | * used later. |
| 71 | | * |
| 72 | | * The order for the GET/HEAD requests are HTTP Extension, cURL, Streams, Fopen, and finally |
| 73 | | * Fsockopen. fsockopen() is used last, because it has the most overhead in its implementation. |
| 74 | | * There isn't any real way around it, since redirects have to be supported, much the same way |
| 75 | | * the other transports also handle redirects. |
| 76 | | * |
| 77 | | * There are currently issues with "localhost" not resolving correctly with DNS. This may cause |
| 78 | | * an error "failed to open stream: A connection attempt failed because the connected party did |
| 79 | | * not properly respond after a period of time, or established connection failed because [the] |
| 80 | | * connected host has failed to respond." |
| 81 | | * |
| 82 | | * @since 2.7.0 |
| 83 | | * @access private |
| 84 | | * |
| 85 | | * @param array $args Request args, default us an empty array |
| 86 | | * @return object|null Null if no transports are available, HTTP transport object. |
| 87 | | */ |
| 88 | | function &_getTransport( $args = array() ) { |
| 89 | | static $working_transport, $blocking_transport, $nonblocking_transport; |
| 90 | | |
| 91 | | if ( is_null($working_transport) ) { |
| 92 | | if ( true === WP_Http_ExtHttp::test($args) ) { |
| 93 | | $working_transport['exthttp'] = new WP_Http_ExtHttp(); |
| 94 | | $blocking_transport[] = &$working_transport['exthttp']; |
| 95 | | } else if ( true === WP_Http_Curl::test($args) ) { |
| 96 | | $working_transport['curl'] = new WP_Http_Curl(); |
| 97 | | $blocking_transport[] = &$working_transport['curl']; |
| 98 | | } else if ( true === WP_Http_Streams::test($args) ) { |
| 99 | | $working_transport['streams'] = new WP_Http_Streams(); |
| 100 | | $blocking_transport[] = &$working_transport['streams']; |
| 101 | | } else if ( true === WP_Http_Fopen::test($args) ) { |
| 102 | | $working_transport['fopen'] = new WP_Http_Fopen(); |
| 103 | | $blocking_transport[] = &$working_transport['fopen']; |
| 104 | | } else if ( true === WP_Http_Fsockopen::test($args) ) { |
| 105 | | $working_transport['fsockopen'] = new WP_Http_Fsockopen(); |
| 106 | | $blocking_transport[] = &$working_transport['fsockopen']; |
| 107 | | } |
| 108 | | |
| 109 | | foreach ( array('curl', 'streams', 'fopen', 'fsockopen', 'exthttp') as $transport ) { |
| 110 | | if ( isset($working_transport[$transport]) ) |
| 111 | | $nonblocking_transport[] = &$working_transport[$transport]; |
| 112 | | } |
| 113 | | } |
| 114 | | |
| 115 | | do_action( 'http_transport_get_debug', $working_transport, $blocking_transport, $nonblocking_transport ); |
| 116 | | |
| 117 | | if ( isset($args['blocking']) && !$args['blocking'] ) |
| 118 | | return $nonblocking_transport; |
| 119 | | else |
| 120 | | return $blocking_transport; |
| 121 | | } |
| 122 | | |
| 123 | | /** |
| 124 | | * Tests the WordPress HTTP objects for an object to use and returns it. |
| 125 | | * |
| 126 | | * Tests all of the objects and returns the object that passes. Also caches |
| 127 | | * that object to be used later. This is for posting content to a URL and |
| 128 | | * is used when there is a body. The plain Fopen Transport can not be used |
| 129 | | * to send content, but the streams transport can. This is a limitation that |
| 130 | | * is addressed here, by just not including that transport. |
| 131 | | * |
| 132 | | * @since 2.7.0 |
| 133 | | * @access private |
| 134 | | * |
| 135 | | * @param array $args Request args, default us an empty array |
| 136 | | * @return object|null Null if no transports are available, HTTP transport object. |
| 137 | | */ |
| 138 | | function &_postTransport( $args = array() ) { |
| 139 | | static $working_transport, $blocking_transport, $nonblocking_transport; |
| 140 | | |
| 141 | | if ( is_null($working_transport) ) { |
| 142 | | if ( true === WP_Http_ExtHttp::test($args) ) { |
| 143 | | $working_transport['exthttp'] = new WP_Http_ExtHttp(); |
| 144 | | $blocking_transport[] = &$working_transport['exthttp']; |
| 145 | | } else if ( true === WP_Http_Curl::test($args) ) { |
| 146 | | $working_transport['curl'] = new WP_Http_Curl(); |
| 147 | | $blocking_transport[] = &$working_transport['curl']; |
| 148 | | } else if ( true === WP_Http_Streams::test($args) ) { |
| 149 | | $working_transport['streams'] = new WP_Http_Streams(); |
| 150 | | $blocking_transport[] = &$working_transport['streams']; |
| 151 | | } else if ( true === WP_Http_Fsockopen::test($args) ) { |
| 152 | | $working_transport['fsockopen'] = new WP_Http_Fsockopen(); |
| 153 | | $blocking_transport[] = &$working_transport['fsockopen']; |
| 154 | | } |
| 155 | | |
| 156 | | foreach ( array('curl', 'streams', 'fsockopen', 'exthttp') as $transport ) { |
| 157 | | if ( isset($working_transport[$transport]) ) |
| 158 | | $nonblocking_transport[] = &$working_transport[$transport]; |
| 159 | | } |
| 160 | | } |
| 161 | | |
| 162 | | do_action( 'http_transport_post_debug', $working_transport, $blocking_transport, $nonblocking_transport ); |
| 163 | | |
| 164 | | if ( isset($args['blocking']) && !$args['blocking'] ) |
| 165 | | return $nonblocking_transport; |
| 166 | | else |
| 167 | | return $blocking_transport; |
| 168 | | } |
| 169 | | |
| 170 | | /** |
| 326 | | return $response; |
| | 189 | // Check to see if this transport is a possibility |
| | 190 | if ( ! $class::test($r, $url) ) //Note: ::test() does not use $url |
| | 191 | continue; |
| | 192 | |
| | 193 | // Class claims to support request, Instantate it and give it a whirl. |
| | 194 | if ( empty($transports[$transport]) ) |
| | 195 | $transports[$transport] = new $class; |
| | 196 | |
| | 197 | // Make the request already! |
| | 198 | $response = $transports[$transport]->request( $url, $r ); |
| | 199 | |
| | 200 | do_action( 'http_api_debug', $response, 'response', $class ); |
| | 201 | |
| | 202 | // Remove this If block to have pre-3.2 style responses, ie. Only try *one* transport then give up, |
| | 203 | // Putting this here as a possibility for enabling requests to attmept another transport if it fails |
| | 204 | // or as a means to do staged-backoff's in times where requests consistently fail with a transport |
| | 205 | // as happens with cURL on some errors on certain hosts. |
| | 206 | if ( is_wp_error( $response ) ) { |
| | 207 | // Set an increasing count of transport failures? Ie. If cURL fails 3 times, just discard it? |
| | 208 | //get_transient(); set_transient(); |
| | 209 | |
| | 210 | // If the arg 'try-other-transports' is set, and this request failed, Try the next transport instead of failure. |
| | 211 | if ( !empty($r['try-other-transports']) ) |
| | 212 | continue; |
| | 213 | } |
| | 214 | |
| | 215 | return apply_filters( 'http_response', $response, $r, $url ); |
| | 216 | } |
| | 217 | // Pre-3.2 this would've been returned in the event that nothing could handle it: |
| | 218 | // array( 'headers' => array(), 'body' => '', 'response' => array('code' => false, 'message' => false), 'cookies' => array() ); |
| | 219 | return new WP_Error('http_failure', __('HTTP Failure - There are no transports available which can serve your request.')); //@TODO: String change |