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 |