Completed
Push — 1.11.x ( 518476...344d9e )
by José
55:02 queued 28:13
created
plugin/buycourses/src/Requests/Cookie/Jar.php 2 patches
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -13,163 +13,163 @@
 block discarded – undo
13 13
  * @subpackage Cookies
14 14
  */
15 15
 class Requests_Cookie_Jar implements ArrayAccess, IteratorAggregate {
16
-	/**
17
-	 * Actual item data
18
-	 *
19
-	 * @var array
20
-	 */
21
-	protected $cookies = array();
22
-
23
-	/**
24
-	 * Create a new jar
25
-	 *
26
-	 * @param array $cookies Existing cookie values
27
-	 */
28
-	public function __construct($cookies = array()) {
29
-		$this->cookies = $cookies;
30
-	}
31
-
32
-	/**
33
-	 * Normalise cookie data into a Requests_Cookie
34
-	 *
35
-	 * @param string|Requests_Cookie $cookie
36
-	 * @return Requests_Cookie
37
-	 */
38
-	public function normalize_cookie($cookie, $key = null) {
39
-		if ($cookie instanceof Requests_Cookie) {
40
-			return $cookie;
41
-		}
42
-
43
-		return Requests_Cookie::parse($cookie, $key);
44
-	}
45
-
46
-	/**
47
-	 * Normalise cookie data into a Requests_Cookie
48
-	 *
49
-	 * @codeCoverageIgnore
50
-	 * @deprecated Use {@see Requests_Cookie_Jar::normalize_cookie}
51
-	 * @return Requests_Cookie
52
-	 */
53
-	public function normalizeCookie($cookie, $key = null) {
54
-		return $this->normalize_cookie($cookie, $key);
55
-	}
56
-
57
-	/**
58
-	 * Check if the given item exists
59
-	 *
60
-	 * @param string $key Item key
61
-	 * @return boolean Does the item exist?
62
-	 */
63
-	public function offsetExists($key) {
64
-		return isset($this->cookies[$key]);
65
-	}
66
-
67
-	/**
68
-	 * Get the value for the item
69
-	 *
70
-	 * @param string $key Item key
71
-	 * @return string Item value
72
-	 */
73
-	public function offsetGet($key) {
74
-		if (!isset($this->cookies[$key])) {
75
-			return null;
76
-		}
77
-
78
-		return $this->cookies[$key];
79
-	}
80
-
81
-	/**
82
-	 * Set the given item
83
-	 *
84
-	 * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
85
-	 *
86
-	 * @param string $key Item name
87
-	 * @param string $value Item value
88
-	 */
89
-	public function offsetSet($key, $value) {
90
-		if ($key === null) {
91
-			throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
92
-		}
93
-
94
-		$this->cookies[$key] = $value;
95
-	}
96
-
97
-	/**
98
-	 * Unset the given header
99
-	 *
100
-	 * @param string $key
101
-	 */
102
-	public function offsetUnset($key) {
103
-		unset($this->cookies[$key]);
104
-	}
105
-
106
-	/**
107
-	 * Get an iterator for the data
108
-	 *
109
-	 * @return ArrayIterator
110
-	 */
111
-	public function getIterator() {
112
-		return new ArrayIterator($this->cookies);
113
-	}
114
-
115
-	/**
116
-	 * Register the cookie handler with the request's hooking system
117
-	 *
118
-	 * @param Requests_Hooker $hooks Hooking system
119
-	 */
120
-	public function register(Requests_Hooker $hooks) {
121
-		$hooks->register('requests.before_request', array($this, 'before_request'));
122
-		$hooks->register('requests.before_redirect_check', array($this, 'before_redirect_check'));
123
-	}
124
-
125
-	/**
126
-	 * Add Cookie header to a request if we have any
127
-	 *
128
-	 * As per RFC 6265, cookies are separated by '; '
129
-	 *
130
-	 * @param string $url
131
-	 * @param array $headers
132
-	 * @param array $data
133
-	 * @param string $type
134
-	 * @param array $options
135
-	 */
136
-	public function before_request($url, &$headers, &$data, &$type, &$options) {
137
-		if (!$url instanceof Requests_IRI) {
138
-			$url = new Requests_IRI($url);
139
-		}
140
-
141
-		if (!empty($this->cookies)) {
142
-			$cookies = array();
143
-			foreach ($this->cookies as $key => $cookie) {
144
-				$cookie = $this->normalize_cookie($cookie, $key);
145
-
146
-				// Skip expired cookies
147
-				if ($cookie->is_expired()) {
148
-					continue;
149
-				}
150
-
151
-				if ($cookie->domain_matches($url->host)) {
152
-					$cookies[] = $cookie->format_for_header();
153
-				}
154
-			}
155
-
156
-			$headers['Cookie'] = implode('; ', $cookies);
157
-		}
158
-	}
159
-
160
-	/**
161
-	 * Parse all cookies from a response and attach them to the response
162
-	 *
163
-	 * @var Requests_Response $response
164
-	 */
165
-	public function before_redirect_check(Requests_Response &$return) {
166
-		$url = $return->url;
167
-		if (!$url instanceof Requests_IRI) {
168
-			$url = new Requests_IRI($url);
169
-		}
170
-
171
-		$cookies = Requests_Cookie::parse_from_headers($return->headers, $url);
172
-		$this->cookies = array_merge($this->cookies, $cookies);
173
-		$return->cookies = $this;
174
-	}
16
+    /**
17
+     * Actual item data
18
+     *
19
+     * @var array
20
+     */
21
+    protected $cookies = array();
22
+
23
+    /**
24
+     * Create a new jar
25
+     *
26
+     * @param array $cookies Existing cookie values
27
+     */
28
+    public function __construct($cookies = array()) {
29
+        $this->cookies = $cookies;
30
+    }
31
+
32
+    /**
33
+     * Normalise cookie data into a Requests_Cookie
34
+     *
35
+     * @param string|Requests_Cookie $cookie
36
+     * @return Requests_Cookie
37
+     */
38
+    public function normalize_cookie($cookie, $key = null) {
39
+        if ($cookie instanceof Requests_Cookie) {
40
+            return $cookie;
41
+        }
42
+
43
+        return Requests_Cookie::parse($cookie, $key);
44
+    }
45
+
46
+    /**
47
+     * Normalise cookie data into a Requests_Cookie
48
+     *
49
+     * @codeCoverageIgnore
50
+     * @deprecated Use {@see Requests_Cookie_Jar::normalize_cookie}
51
+     * @return Requests_Cookie
52
+     */
53
+    public function normalizeCookie($cookie, $key = null) {
54
+        return $this->normalize_cookie($cookie, $key);
55
+    }
56
+
57
+    /**
58
+     * Check if the given item exists
59
+     *
60
+     * @param string $key Item key
61
+     * @return boolean Does the item exist?
62
+     */
63
+    public function offsetExists($key) {
64
+        return isset($this->cookies[$key]);
65
+    }
66
+
67
+    /**
68
+     * Get the value for the item
69
+     *
70
+     * @param string $key Item key
71
+     * @return string Item value
72
+     */
73
+    public function offsetGet($key) {
74
+        if (!isset($this->cookies[$key])) {
75
+            return null;
76
+        }
77
+
78
+        return $this->cookies[$key];
79
+    }
80
+
81
+    /**
82
+     * Set the given item
83
+     *
84
+     * @throws Requests_Exception On attempting to use dictionary as list (`invalidset`)
85
+     *
86
+     * @param string $key Item name
87
+     * @param string $value Item value
88
+     */
89
+    public function offsetSet($key, $value) {
90
+        if ($key === null) {
91
+            throw new Requests_Exception('Object is a dictionary, not a list', 'invalidset');
92
+        }
93
+
94
+        $this->cookies[$key] = $value;
95
+    }
96
+
97
+    /**
98
+     * Unset the given header
99
+     *
100
+     * @param string $key
101
+     */
102
+    public function offsetUnset($key) {
103
+        unset($this->cookies[$key]);
104
+    }
105
+
106
+    /**
107
+     * Get an iterator for the data
108
+     *
109
+     * @return ArrayIterator
110
+     */
111
+    public function getIterator() {
112
+        return new ArrayIterator($this->cookies);
113
+    }
114
+
115
+    /**
116
+     * Register the cookie handler with the request's hooking system
117
+     *
118
+     * @param Requests_Hooker $hooks Hooking system
119
+     */
120
+    public function register(Requests_Hooker $hooks) {
121
+        $hooks->register('requests.before_request', array($this, 'before_request'));
122
+        $hooks->register('requests.before_redirect_check', array($this, 'before_redirect_check'));
123
+    }
124
+
125
+    /**
126
+     * Add Cookie header to a request if we have any
127
+     *
128
+     * As per RFC 6265, cookies are separated by '; '
129
+     *
130
+     * @param string $url
131
+     * @param array $headers
132
+     * @param array $data
133
+     * @param string $type
134
+     * @param array $options
135
+     */
136
+    public function before_request($url, &$headers, &$data, &$type, &$options) {
137
+        if (!$url instanceof Requests_IRI) {
138
+            $url = new Requests_IRI($url);
139
+        }
140
+
141
+        if (!empty($this->cookies)) {
142
+            $cookies = array();
143
+            foreach ($this->cookies as $key => $cookie) {
144
+                $cookie = $this->normalize_cookie($cookie, $key);
145
+
146
+                // Skip expired cookies
147
+                if ($cookie->is_expired()) {
148
+                    continue;
149
+                }
150
+
151
+                if ($cookie->domain_matches($url->host)) {
152
+                    $cookies[] = $cookie->format_for_header();
153
+                }
154
+            }
155
+
156
+            $headers['Cookie'] = implode('; ', $cookies);
157
+        }
158
+    }
159
+
160
+    /**
161
+     * Parse all cookies from a response and attach them to the response
162
+     *
163
+     * @var Requests_Response $response
164
+     */
165
+    public function before_redirect_check(Requests_Response &$return) {
166
+        $url = $return->url;
167
+        if (!$url instanceof Requests_IRI) {
168
+            $url = new Requests_IRI($url);
169
+        }
170
+
171
+        $cookies = Requests_Cookie::parse_from_headers($return->headers, $url);
172
+        $this->cookies = array_merge($this->cookies, $cookies);
173
+        $return->cookies = $this;
174
+    }
175 175
 }
176 176
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -162,7 +162,7 @@
 block discarded – undo
162 162
 	 *
163 163
 	 * @var Requests_Response $response
164 164
 	 */
165
-	public function before_redirect_check(Requests_Response &$return) {
165
+	public function before_redirect_check(Requests_Response & $return) {
166 166
 		$url = $return->url;
167 167
 		if (!$url instanceof Requests_IRI) {
168 168
 			$url = new Requests_IRI($url);
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/Transport/cURL.php 3 patches
Indentation   +526 added lines, -526 removed lines patch added patch discarded remove patch
@@ -13,530 +13,530 @@
 block discarded – undo
13 13
  * @subpackage Transport
14 14
  */
15 15
 class Requests_Transport_cURL implements Requests_Transport {
16
-	const CURL_7_10_5 = 0x070A05;
17
-	const CURL_7_16_2 = 0x071002;
18
-
19
-	/**
20
-	 * Raw HTTP data
21
-	 *
22
-	 * @var string
23
-	 */
24
-	public $headers = '';
25
-
26
-	/**
27
-	 * Raw body data
28
-	 *
29
-	 * @var string
30
-	 */
31
-	public $response_data = '';
32
-
33
-	/**
34
-	 * Information on the current request
35
-	 *
36
-	 * @var array cURL information array, see {@see https://secure.php.net/curl_getinfo}
37
-	 */
38
-	public $info;
39
-
40
-	/**
41
-	 * Version string
42
-	 *
43
-	 * @var long
44
-	 */
45
-	public $version;
46
-
47
-	/**
48
-	 * cURL handle
49
-	 *
50
-	 * @var resource
51
-	 */
52
-	protected $handle;
53
-
54
-	/**
55
-	 * Hook dispatcher instance
56
-	 *
57
-	 * @var Requests_Hooks
58
-	 */
59
-	protected $hooks;
60
-
61
-	/**
62
-	 * Have we finished the headers yet?
63
-	 *
64
-	 * @var boolean
65
-	 */
66
-	protected $done_headers = false;
67
-
68
-	/**
69
-	 * If streaming to a file, keep the file pointer
70
-	 *
71
-	 * @var resource
72
-	 */
73
-	protected $stream_handle;
74
-
75
-	/**
76
-	 * How many bytes are in the response body?
77
-	 *
78
-	 * @var int
79
-	 */
80
-	protected $response_bytes;
81
-
82
-	/**
83
-	 * What's the maximum number of bytes we should keep?
84
-	 *
85
-	 * @var int|bool Byte count, or false if no limit.
86
-	 */
87
-	protected $response_byte_limit;
88
-
89
-	/**
90
-	 * Constructor
91
-	 */
92
-	public function __construct() {
93
-		$curl = curl_version();
94
-		$this->version = $curl['version_number'];
95
-		$this->handle = curl_init();
96
-
97
-		curl_setopt($this->handle, CURLOPT_HEADER, false);
98
-		curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, 1);
99
-		if ($this->version >= self::CURL_7_10_5) {
100
-			curl_setopt($this->handle, CURLOPT_ENCODING, '');
101
-		}
102
-		if (defined('CURLOPT_PROTOCOLS')) {
103
-			curl_setopt($this->handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
104
-		}
105
-		if (defined('CURLOPT_REDIR_PROTOCOLS')) {
106
-			curl_setopt($this->handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
107
-		}
108
-	}
109
-
110
-	/**
111
-	 * Destructor
112
-	 */
113
-	public function __destruct() {
114
-		if (is_resource($this->handle)) {
115
-			curl_close($this->handle);
116
-		}
117
-	}
118
-
119
-	/**
120
-	 * Perform a request
121
-	 *
122
-	 * @throws Requests_Exception On a cURL error (`curlerror`)
123
-	 *
124
-	 * @param string $url URL to request
125
-	 * @param array $headers Associative array of request headers
126
-	 * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
127
-	 * @param array $options Request options, see {@see Requests::response()} for documentation
128
-	 * @return string Raw HTTP result
129
-	 */
130
-	public function request($url, $headers = array(), $data = array(), $options = array()) {
131
-		$this->hooks = $options['hooks'];
132
-
133
-		$this->setup_handle($url, $headers, $data, $options);
134
-
135
-		$options['hooks']->dispatch('curl.before_send', array(&$this->handle));
136
-
137
-		if ($options['filename'] !== false) {
138
-			$this->stream_handle = fopen($options['filename'], 'wb');
139
-		}
140
-
141
-		$this->response_data = '';
142
-		$this->response_bytes = 0;
143
-		$this->response_byte_limit = false;
144
-		if ($options['max_bytes'] !== false) {
145
-			$this->response_byte_limit = $options['max_bytes'];
146
-		}
147
-
148
-		if (isset($options['verify'])) {
149
-			if ($options['verify'] === false) {
150
-				curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
151
-				curl_setopt($this->handle, CURLOPT_SSL_VERIFYPEER, 0);
152
-			}
153
-			elseif (is_string($options['verify'])) {
154
-				curl_setopt($this->handle, CURLOPT_CAINFO, $options['verify']);
155
-			}
156
-		}
157
-
158
-		if (isset($options['verifyname']) && $options['verifyname'] === false) {
159
-			curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
160
-		}
161
-
162
-		curl_exec($this->handle);
163
-		$response = $this->response_data;
164
-
165
-		$options['hooks']->dispatch('curl.after_send', array());
166
-
167
-		if (curl_errno($this->handle) === 23 || curl_errno($this->handle) === 61) {
168
-			// Reset encoding and try again
169
-			curl_setopt($this->handle, CURLOPT_ENCODING, 'none');
170
-
171
-			$this->response_data = '';
172
-			$this->response_bytes = 0;
173
-			curl_exec($this->handle);
174
-			$response = $this->response_data;
175
-		}
176
-
177
-		$this->process_response($response, $options);
178
-
179
-		// Need to remove the $this reference from the curl handle.
180
-		// Otherwise Requests_Transport_cURL wont be garbage collected and the curl_close() will never be called.
181
-		curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, null);
182
-		curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, null);
183
-
184
-		return $this->headers;
185
-	}
186
-
187
-	/**
188
-	 * Send multiple requests simultaneously
189
-	 *
190
-	 * @param array $requests Request data
191
-	 * @param array $options Global options
192
-	 * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
193
-	 */
194
-	public function request_multiple($requests, $options) {
195
-		// If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
196
-		if (empty($requests)) {
197
-			return array();
198
-		}
199
-
200
-		$multihandle = curl_multi_init();
201
-		$subrequests = array();
202
-		$subhandles = array();
203
-
204
-		$class = get_class($this);
205
-		foreach ($requests as $id => $request) {
206
-			$subrequests[$id] = new $class();
207
-			$subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
208
-			$request['options']['hooks']->dispatch('curl.before_multi_add', array(&$subhandles[$id]));
209
-			curl_multi_add_handle($multihandle, $subhandles[$id]);
210
-		}
211
-
212
-		$completed = 0;
213
-		$responses = array();
214
-
215
-		$request['options']['hooks']->dispatch('curl.before_multi_exec', array(&$multihandle));
216
-
217
-		do {
218
-			$active = false;
219
-
220
-			do {
221
-				$status = curl_multi_exec($multihandle, $active);
222
-			}
223
-			while ($status === CURLM_CALL_MULTI_PERFORM);
224
-
225
-			$to_process = array();
226
-
227
-			// Read the information as needed
228
-			while ($done = curl_multi_info_read($multihandle)) {
229
-				$key = array_search($done['handle'], $subhandles, true);
230
-				if (!isset($to_process[$key])) {
231
-					$to_process[$key] = $done;
232
-				}
233
-			}
234
-
235
-			// Parse the finished requests before we start getting the new ones
236
-			foreach ($to_process as $key => $done) {
237
-				$options = $requests[$key]['options'];
238
-				if (CURLE_OK !== $done['result']) {
239
-					//get error string for handle.
240
-					$reason = curl_error($done['handle']);
241
-					$exception = new Requests_Exception_Transport_cURL(
242
-									$reason,
243
-									Requests_Exception_Transport_cURL::EASY,
244
-									$done['handle'],
245
-									$done['result']
246
-								);
247
-					$responses[$key] = $exception;
248
-					$options['hooks']->dispatch('transport.internal.parse_error', array(&$responses[$key], $requests[$key]));
249
-				}
250
-				else {
251
-					$responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options);
252
-
253
-					$options['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$key], $requests[$key]));
254
-				}
255
-
256
-				curl_multi_remove_handle($multihandle, $done['handle']);
257
-				curl_close($done['handle']);
258
-
259
-				if (!is_string($responses[$key])) {
260
-					$options['hooks']->dispatch('multiple.request.complete', array(&$responses[$key], $key));
261
-				}
262
-				$completed++;
263
-			}
264
-		}
265
-		while ($active || $completed < count($subrequests));
266
-
267
-		$request['options']['hooks']->dispatch('curl.after_multi_exec', array(&$multihandle));
268
-
269
-		curl_multi_close($multihandle);
270
-
271
-		return $responses;
272
-	}
273
-
274
-	/**
275
-	 * Get the cURL handle for use in a multi-request
276
-	 *
277
-	 * @param string $url URL to request
278
-	 * @param array $headers Associative array of request headers
279
-	 * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
280
-	 * @param array $options Request options, see {@see Requests::response()} for documentation
281
-	 * @return resource Subrequest's cURL handle
282
-	 */
283
-	public function &get_subrequest_handle($url, $headers, $data, $options) {
284
-		$this->setup_handle($url, $headers, $data, $options);
285
-
286
-		if ($options['filename'] !== false) {
287
-			$this->stream_handle = fopen($options['filename'], 'wb');
288
-		}
289
-
290
-		$this->response_data = '';
291
-		$this->response_bytes = 0;
292
-		$this->response_byte_limit = false;
293
-		if ($options['max_bytes'] !== false) {
294
-			$this->response_byte_limit = $options['max_bytes'];
295
-		}
296
-		$this->hooks = $options['hooks'];
297
-
298
-		return $this->handle;
299
-	}
300
-
301
-	/**
302
-	 * Setup the cURL handle for the given data
303
-	 *
304
-	 * @param string $url URL to request
305
-	 * @param array $headers Associative array of request headers
306
-	 * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
307
-	 * @param array $options Request options, see {@see Requests::response()} for documentation
308
-	 */
309
-	protected function setup_handle($url, $headers, $data, $options) {
310
-		$options['hooks']->dispatch('curl.before_request', array(&$this->handle));
311
-
312
-		// Force closing the connection for old versions of cURL (<7.22).
313
-		if ( ! isset( $headers['Connection'] ) ) {
314
-			$headers['Connection'] = 'close';
315
-		}
316
-
317
-		$headers = Requests::flatten($headers);
318
-
319
-		if (!empty($data)) {
320
-			$data_format = $options['data_format'];
321
-
322
-			if ($data_format === 'query') {
323
-				$url = self::format_get($url, $data);
324
-				$data = '';
325
-			}
326
-			elseif (!is_string($data)) {
327
-				$data = http_build_query($data, null, '&');
328
-			}
329
-		}
330
-
331
-		switch ($options['type']) {
332
-			case Requests::POST:
333
-				curl_setopt($this->handle, CURLOPT_POST, true);
334
-				curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
335
-				break;
336
-			case Requests::HEAD:
337
-				curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
338
-				curl_setopt($this->handle, CURLOPT_NOBODY, true);
339
-				break;
340
-			case Requests::TRACE:
341
-				curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
342
-				break;
343
-			case Requests::PATCH:
344
-			case Requests::PUT:
345
-			case Requests::DELETE:
346
-			case Requests::OPTIONS:
347
-			default:
348
-				curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
349
-				if (!empty($data)) {
350
-					curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
351
-				}
352
-		}
353
-
354
-		// cURL requires a minimum timeout of 1 second when using the system
355
-		// DNS resolver, as it uses `alarm()`, which is second resolution only.
356
-		// There's no way to detect which DNS resolver is being used from our
357
-		// end, so we need to round up regardless of the supplied timeout.
358
-		//
359
-		// https://github.com/curl/curl/blob/4f45240bc84a9aa648c8f7243be7b79e9f9323a5/lib/hostip.c#L606-L609
360
-		$timeout = max($options['timeout'], 1);
361
-
362
-		if (is_int($timeout) || $this->version < self::CURL_7_16_2) {
363
-			curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
364
-		}
365
-		else {
366
-			curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
367
-		}
368
-
369
-		if (is_int($options['connect_timeout']) || $this->version < self::CURL_7_16_2) {
370
-			curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
371
-		}
372
-		else {
373
-			curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
374
-		}
375
-		curl_setopt($this->handle, CURLOPT_URL, $url);
376
-		curl_setopt($this->handle, CURLOPT_REFERER, $url);
377
-		curl_setopt($this->handle, CURLOPT_USERAGENT, $options['useragent']);
378
-		if (!empty($headers)) {
379
-			curl_setopt($this->handle, CURLOPT_HTTPHEADER, $headers);
380
-		}
381
-		if ($options['protocol_version'] === 1.1) {
382
-			curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
383
-		}
384
-		else {
385
-			curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
386
-		}
387
-
388
-		if (true === $options['blocking']) {
389
-			curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, array(&$this, 'stream_headers'));
390
-			curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, array(&$this, 'stream_body'));
391
-			curl_setopt($this->handle, CURLOPT_BUFFERSIZE, Requests::BUFFER_SIZE);
392
-		}
393
-	}
394
-
395
-	/**
396
-	 * Process a response
397
-	 *
398
-	 * @param string $response Response data from the body
399
-	 * @param array $options Request options
400
-	 * @return string HTTP response data including headers
401
-	 */
402
-	public function process_response($response, $options) {
403
-		if ($options['blocking'] === false) {
404
-			$fake_headers = '';
405
-			$options['hooks']->dispatch('curl.after_request', array(&$fake_headers));
406
-			return false;
407
-		}
408
-		if ($options['filename'] !== false) {
409
-			fclose($this->stream_handle);
410
-			$this->headers = trim($this->headers);
411
-		}
412
-		else {
413
-			$this->headers .= $response;
414
-		}
415
-
416
-		if (curl_errno($this->handle)) {
417
-			$error = sprintf(
418
-				'cURL error %s: %s',
419
-				curl_errno($this->handle),
420
-				curl_error($this->handle)
421
-			);
422
-			throw new Requests_Exception($error, 'curlerror', $this->handle);
423
-		}
424
-		$this->info = curl_getinfo($this->handle);
425
-
426
-		$options['hooks']->dispatch('curl.after_request', array(&$this->headers, &$this->info));
427
-		return $this->headers;
428
-	}
429
-
430
-	/**
431
-	 * Collect the headers as they are received
432
-	 *
433
-	 * @param resource $handle cURL resource
434
-	 * @param string $headers Header string
435
-	 * @return integer Length of provided header
436
-	 */
437
-	public function stream_headers($handle, $headers) {
438
-		// Why do we do this? cURL will send both the final response and any
439
-		// interim responses, such as a 100 Continue. We don't need that.
440
-		// (We may want to keep this somewhere just in case)
441
-		if ($this->done_headers) {
442
-			$this->headers = '';
443
-			$this->done_headers = false;
444
-		}
445
-		$this->headers .= $headers;
446
-
447
-		if ($headers === "\r\n") {
448
-			$this->done_headers = true;
449
-		}
450
-		return strlen($headers);
451
-	}
452
-
453
-	/**
454
-	 * Collect data as it's received
455
-	 *
456
-	 * @since 1.6.1
457
-	 *
458
-	 * @param resource $handle cURL resource
459
-	 * @param string $data Body data
460
-	 * @return integer Length of provided data
461
-	 */
462
-	public function stream_body($handle, $data) {
463
-		$this->hooks->dispatch('request.progress', array($data, $this->response_bytes, $this->response_byte_limit));
464
-		$data_length = strlen($data);
465
-
466
-		// Are we limiting the response size?
467
-		if ($this->response_byte_limit) {
468
-			if ($this->response_bytes === $this->response_byte_limit) {
469
-				// Already at maximum, move on
470
-				return $data_length;
471
-			}
472
-
473
-			if (($this->response_bytes + $data_length) > $this->response_byte_limit) {
474
-				// Limit the length
475
-				$limited_length = ($this->response_byte_limit - $this->response_bytes);
476
-				$data = substr($data, 0, $limited_length);
477
-			}
478
-		}
479
-
480
-		if ($this->stream_handle) {
481
-			fwrite($this->stream_handle, $data);
482
-		}
483
-		else {
484
-			$this->response_data .= $data;
485
-		}
486
-
487
-		$this->response_bytes += strlen($data);
488
-		return $data_length;
489
-	}
490
-
491
-	/**
492
-	 * Format a URL given GET data
493
-	 *
494
-	 * @param string $url
495
-	 * @param array|object $data Data to build query using, see {@see https://secure.php.net/http_build_query}
496
-	 * @return string URL with data
497
-	 */
498
-	protected static function format_get($url, $data) {
499
-		if (!empty($data)) {
500
-			$url_parts = parse_url($url);
501
-			if (empty($url_parts['query'])) {
502
-				$query = $url_parts['query'] = '';
503
-			}
504
-			else {
505
-				$query = $url_parts['query'];
506
-			}
507
-
508
-			$query .= '&' . http_build_query($data, null, '&');
509
-			$query = trim($query, '&');
510
-
511
-			if (empty($url_parts['query'])) {
512
-				$url .= '?' . $query;
513
-			}
514
-			else {
515
-				$url = str_replace($url_parts['query'], $query, $url);
516
-			}
517
-		}
518
-		return $url;
519
-	}
520
-
521
-	/**
522
-	 * Whether this transport is valid
523
-	 *
524
-	 * @codeCoverageIgnore
525
-	 * @return boolean True if the transport is valid, false otherwise.
526
-	 */
527
-	public static function test($capabilities = array()) {
528
-		if (!function_exists('curl_init') || !function_exists('curl_exec')) {
529
-			return false;
530
-		}
531
-
532
-		// If needed, check that our installed curl version supports SSL
533
-		if (isset($capabilities['ssl']) && $capabilities['ssl']) {
534
-			$curl_version = curl_version();
535
-			if (!(CURL_VERSION_SSL & $curl_version['features'])) {
536
-				return false;
537
-			}
538
-		}
539
-
540
-		return true;
541
-	}
16
+    const CURL_7_10_5 = 0x070A05;
17
+    const CURL_7_16_2 = 0x071002;
18
+
19
+    /**
20
+     * Raw HTTP data
21
+     *
22
+     * @var string
23
+     */
24
+    public $headers = '';
25
+
26
+    /**
27
+     * Raw body data
28
+     *
29
+     * @var string
30
+     */
31
+    public $response_data = '';
32
+
33
+    /**
34
+     * Information on the current request
35
+     *
36
+     * @var array cURL information array, see {@see https://secure.php.net/curl_getinfo}
37
+     */
38
+    public $info;
39
+
40
+    /**
41
+     * Version string
42
+     *
43
+     * @var long
44
+     */
45
+    public $version;
46
+
47
+    /**
48
+     * cURL handle
49
+     *
50
+     * @var resource
51
+     */
52
+    protected $handle;
53
+
54
+    /**
55
+     * Hook dispatcher instance
56
+     *
57
+     * @var Requests_Hooks
58
+     */
59
+    protected $hooks;
60
+
61
+    /**
62
+     * Have we finished the headers yet?
63
+     *
64
+     * @var boolean
65
+     */
66
+    protected $done_headers = false;
67
+
68
+    /**
69
+     * If streaming to a file, keep the file pointer
70
+     *
71
+     * @var resource
72
+     */
73
+    protected $stream_handle;
74
+
75
+    /**
76
+     * How many bytes are in the response body?
77
+     *
78
+     * @var int
79
+     */
80
+    protected $response_bytes;
81
+
82
+    /**
83
+     * What's the maximum number of bytes we should keep?
84
+     *
85
+     * @var int|bool Byte count, or false if no limit.
86
+     */
87
+    protected $response_byte_limit;
88
+
89
+    /**
90
+     * Constructor
91
+     */
92
+    public function __construct() {
93
+        $curl = curl_version();
94
+        $this->version = $curl['version_number'];
95
+        $this->handle = curl_init();
96
+
97
+        curl_setopt($this->handle, CURLOPT_HEADER, false);
98
+        curl_setopt($this->handle, CURLOPT_RETURNTRANSFER, 1);
99
+        if ($this->version >= self::CURL_7_10_5) {
100
+            curl_setopt($this->handle, CURLOPT_ENCODING, '');
101
+        }
102
+        if (defined('CURLOPT_PROTOCOLS')) {
103
+            curl_setopt($this->handle, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
104
+        }
105
+        if (defined('CURLOPT_REDIR_PROTOCOLS')) {
106
+            curl_setopt($this->handle, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
107
+        }
108
+    }
109
+
110
+    /**
111
+     * Destructor
112
+     */
113
+    public function __destruct() {
114
+        if (is_resource($this->handle)) {
115
+            curl_close($this->handle);
116
+        }
117
+    }
118
+
119
+    /**
120
+     * Perform a request
121
+     *
122
+     * @throws Requests_Exception On a cURL error (`curlerror`)
123
+     *
124
+     * @param string $url URL to request
125
+     * @param array $headers Associative array of request headers
126
+     * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
127
+     * @param array $options Request options, see {@see Requests::response()} for documentation
128
+     * @return string Raw HTTP result
129
+     */
130
+    public function request($url, $headers = array(), $data = array(), $options = array()) {
131
+        $this->hooks = $options['hooks'];
132
+
133
+        $this->setup_handle($url, $headers, $data, $options);
134
+
135
+        $options['hooks']->dispatch('curl.before_send', array(&$this->handle));
136
+
137
+        if ($options['filename'] !== false) {
138
+            $this->stream_handle = fopen($options['filename'], 'wb');
139
+        }
140
+
141
+        $this->response_data = '';
142
+        $this->response_bytes = 0;
143
+        $this->response_byte_limit = false;
144
+        if ($options['max_bytes'] !== false) {
145
+            $this->response_byte_limit = $options['max_bytes'];
146
+        }
147
+
148
+        if (isset($options['verify'])) {
149
+            if ($options['verify'] === false) {
150
+                curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
151
+                curl_setopt($this->handle, CURLOPT_SSL_VERIFYPEER, 0);
152
+            }
153
+            elseif (is_string($options['verify'])) {
154
+                curl_setopt($this->handle, CURLOPT_CAINFO, $options['verify']);
155
+            }
156
+        }
157
+
158
+        if (isset($options['verifyname']) && $options['verifyname'] === false) {
159
+            curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
160
+        }
161
+
162
+        curl_exec($this->handle);
163
+        $response = $this->response_data;
164
+
165
+        $options['hooks']->dispatch('curl.after_send', array());
166
+
167
+        if (curl_errno($this->handle) === 23 || curl_errno($this->handle) === 61) {
168
+            // Reset encoding and try again
169
+            curl_setopt($this->handle, CURLOPT_ENCODING, 'none');
170
+
171
+            $this->response_data = '';
172
+            $this->response_bytes = 0;
173
+            curl_exec($this->handle);
174
+            $response = $this->response_data;
175
+        }
176
+
177
+        $this->process_response($response, $options);
178
+
179
+        // Need to remove the $this reference from the curl handle.
180
+        // Otherwise Requests_Transport_cURL wont be garbage collected and the curl_close() will never be called.
181
+        curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, null);
182
+        curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, null);
183
+
184
+        return $this->headers;
185
+    }
186
+
187
+    /**
188
+     * Send multiple requests simultaneously
189
+     *
190
+     * @param array $requests Request data
191
+     * @param array $options Global options
192
+     * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
193
+     */
194
+    public function request_multiple($requests, $options) {
195
+        // If you're not requesting, we can't get any responses ¯\_(ツ)_/¯
196
+        if (empty($requests)) {
197
+            return array();
198
+        }
199
+
200
+        $multihandle = curl_multi_init();
201
+        $subrequests = array();
202
+        $subhandles = array();
203
+
204
+        $class = get_class($this);
205
+        foreach ($requests as $id => $request) {
206
+            $subrequests[$id] = new $class();
207
+            $subhandles[$id] = $subrequests[$id]->get_subrequest_handle($request['url'], $request['headers'], $request['data'], $request['options']);
208
+            $request['options']['hooks']->dispatch('curl.before_multi_add', array(&$subhandles[$id]));
209
+            curl_multi_add_handle($multihandle, $subhandles[$id]);
210
+        }
211
+
212
+        $completed = 0;
213
+        $responses = array();
214
+
215
+        $request['options']['hooks']->dispatch('curl.before_multi_exec', array(&$multihandle));
216
+
217
+        do {
218
+            $active = false;
219
+
220
+            do {
221
+                $status = curl_multi_exec($multihandle, $active);
222
+            }
223
+            while ($status === CURLM_CALL_MULTI_PERFORM);
224
+
225
+            $to_process = array();
226
+
227
+            // Read the information as needed
228
+            while ($done = curl_multi_info_read($multihandle)) {
229
+                $key = array_search($done['handle'], $subhandles, true);
230
+                if (!isset($to_process[$key])) {
231
+                    $to_process[$key] = $done;
232
+                }
233
+            }
234
+
235
+            // Parse the finished requests before we start getting the new ones
236
+            foreach ($to_process as $key => $done) {
237
+                $options = $requests[$key]['options'];
238
+                if (CURLE_OK !== $done['result']) {
239
+                    //get error string for handle.
240
+                    $reason = curl_error($done['handle']);
241
+                    $exception = new Requests_Exception_Transport_cURL(
242
+                                    $reason,
243
+                                    Requests_Exception_Transport_cURL::EASY,
244
+                                    $done['handle'],
245
+                                    $done['result']
246
+                                );
247
+                    $responses[$key] = $exception;
248
+                    $options['hooks']->dispatch('transport.internal.parse_error', array(&$responses[$key], $requests[$key]));
249
+                }
250
+                else {
251
+                    $responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options);
252
+
253
+                    $options['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$key], $requests[$key]));
254
+                }
255
+
256
+                curl_multi_remove_handle($multihandle, $done['handle']);
257
+                curl_close($done['handle']);
258
+
259
+                if (!is_string($responses[$key])) {
260
+                    $options['hooks']->dispatch('multiple.request.complete', array(&$responses[$key], $key));
261
+                }
262
+                $completed++;
263
+            }
264
+        }
265
+        while ($active || $completed < count($subrequests));
266
+
267
+        $request['options']['hooks']->dispatch('curl.after_multi_exec', array(&$multihandle));
268
+
269
+        curl_multi_close($multihandle);
270
+
271
+        return $responses;
272
+    }
273
+
274
+    /**
275
+     * Get the cURL handle for use in a multi-request
276
+     *
277
+     * @param string $url URL to request
278
+     * @param array $headers Associative array of request headers
279
+     * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
280
+     * @param array $options Request options, see {@see Requests::response()} for documentation
281
+     * @return resource Subrequest's cURL handle
282
+     */
283
+    public function &get_subrequest_handle($url, $headers, $data, $options) {
284
+        $this->setup_handle($url, $headers, $data, $options);
285
+
286
+        if ($options['filename'] !== false) {
287
+            $this->stream_handle = fopen($options['filename'], 'wb');
288
+        }
289
+
290
+        $this->response_data = '';
291
+        $this->response_bytes = 0;
292
+        $this->response_byte_limit = false;
293
+        if ($options['max_bytes'] !== false) {
294
+            $this->response_byte_limit = $options['max_bytes'];
295
+        }
296
+        $this->hooks = $options['hooks'];
297
+
298
+        return $this->handle;
299
+    }
300
+
301
+    /**
302
+     * Setup the cURL handle for the given data
303
+     *
304
+     * @param string $url URL to request
305
+     * @param array $headers Associative array of request headers
306
+     * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
307
+     * @param array $options Request options, see {@see Requests::response()} for documentation
308
+     */
309
+    protected function setup_handle($url, $headers, $data, $options) {
310
+        $options['hooks']->dispatch('curl.before_request', array(&$this->handle));
311
+
312
+        // Force closing the connection for old versions of cURL (<7.22).
313
+        if ( ! isset( $headers['Connection'] ) ) {
314
+            $headers['Connection'] = 'close';
315
+        }
316
+
317
+        $headers = Requests::flatten($headers);
318
+
319
+        if (!empty($data)) {
320
+            $data_format = $options['data_format'];
321
+
322
+            if ($data_format === 'query') {
323
+                $url = self::format_get($url, $data);
324
+                $data = '';
325
+            }
326
+            elseif (!is_string($data)) {
327
+                $data = http_build_query($data, null, '&');
328
+            }
329
+        }
330
+
331
+        switch ($options['type']) {
332
+            case Requests::POST:
333
+                curl_setopt($this->handle, CURLOPT_POST, true);
334
+                curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
335
+                break;
336
+            case Requests::HEAD:
337
+                curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
338
+                curl_setopt($this->handle, CURLOPT_NOBODY, true);
339
+                break;
340
+            case Requests::TRACE:
341
+                curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
342
+                break;
343
+            case Requests::PATCH:
344
+            case Requests::PUT:
345
+            case Requests::DELETE:
346
+            case Requests::OPTIONS:
347
+            default:
348
+                curl_setopt($this->handle, CURLOPT_CUSTOMREQUEST, $options['type']);
349
+                if (!empty($data)) {
350
+                    curl_setopt($this->handle, CURLOPT_POSTFIELDS, $data);
351
+                }
352
+        }
353
+
354
+        // cURL requires a minimum timeout of 1 second when using the system
355
+        // DNS resolver, as it uses `alarm()`, which is second resolution only.
356
+        // There's no way to detect which DNS resolver is being used from our
357
+        // end, so we need to round up regardless of the supplied timeout.
358
+        //
359
+        // https://github.com/curl/curl/blob/4f45240bc84a9aa648c8f7243be7b79e9f9323a5/lib/hostip.c#L606-L609
360
+        $timeout = max($options['timeout'], 1);
361
+
362
+        if (is_int($timeout) || $this->version < self::CURL_7_16_2) {
363
+            curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
364
+        }
365
+        else {
366
+            curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
367
+        }
368
+
369
+        if (is_int($options['connect_timeout']) || $this->version < self::CURL_7_16_2) {
370
+            curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
371
+        }
372
+        else {
373
+            curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
374
+        }
375
+        curl_setopt($this->handle, CURLOPT_URL, $url);
376
+        curl_setopt($this->handle, CURLOPT_REFERER, $url);
377
+        curl_setopt($this->handle, CURLOPT_USERAGENT, $options['useragent']);
378
+        if (!empty($headers)) {
379
+            curl_setopt($this->handle, CURLOPT_HTTPHEADER, $headers);
380
+        }
381
+        if ($options['protocol_version'] === 1.1) {
382
+            curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
383
+        }
384
+        else {
385
+            curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
386
+        }
387
+
388
+        if (true === $options['blocking']) {
389
+            curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, array(&$this, 'stream_headers'));
390
+            curl_setopt($this->handle, CURLOPT_WRITEFUNCTION, array(&$this, 'stream_body'));
391
+            curl_setopt($this->handle, CURLOPT_BUFFERSIZE, Requests::BUFFER_SIZE);
392
+        }
393
+    }
394
+
395
+    /**
396
+     * Process a response
397
+     *
398
+     * @param string $response Response data from the body
399
+     * @param array $options Request options
400
+     * @return string HTTP response data including headers
401
+     */
402
+    public function process_response($response, $options) {
403
+        if ($options['blocking'] === false) {
404
+            $fake_headers = '';
405
+            $options['hooks']->dispatch('curl.after_request', array(&$fake_headers));
406
+            return false;
407
+        }
408
+        if ($options['filename'] !== false) {
409
+            fclose($this->stream_handle);
410
+            $this->headers = trim($this->headers);
411
+        }
412
+        else {
413
+            $this->headers .= $response;
414
+        }
415
+
416
+        if (curl_errno($this->handle)) {
417
+            $error = sprintf(
418
+                'cURL error %s: %s',
419
+                curl_errno($this->handle),
420
+                curl_error($this->handle)
421
+            );
422
+            throw new Requests_Exception($error, 'curlerror', $this->handle);
423
+        }
424
+        $this->info = curl_getinfo($this->handle);
425
+
426
+        $options['hooks']->dispatch('curl.after_request', array(&$this->headers, &$this->info));
427
+        return $this->headers;
428
+    }
429
+
430
+    /**
431
+     * Collect the headers as they are received
432
+     *
433
+     * @param resource $handle cURL resource
434
+     * @param string $headers Header string
435
+     * @return integer Length of provided header
436
+     */
437
+    public function stream_headers($handle, $headers) {
438
+        // Why do we do this? cURL will send both the final response and any
439
+        // interim responses, such as a 100 Continue. We don't need that.
440
+        // (We may want to keep this somewhere just in case)
441
+        if ($this->done_headers) {
442
+            $this->headers = '';
443
+            $this->done_headers = false;
444
+        }
445
+        $this->headers .= $headers;
446
+
447
+        if ($headers === "\r\n") {
448
+            $this->done_headers = true;
449
+        }
450
+        return strlen($headers);
451
+    }
452
+
453
+    /**
454
+     * Collect data as it's received
455
+     *
456
+     * @since 1.6.1
457
+     *
458
+     * @param resource $handle cURL resource
459
+     * @param string $data Body data
460
+     * @return integer Length of provided data
461
+     */
462
+    public function stream_body($handle, $data) {
463
+        $this->hooks->dispatch('request.progress', array($data, $this->response_bytes, $this->response_byte_limit));
464
+        $data_length = strlen($data);
465
+
466
+        // Are we limiting the response size?
467
+        if ($this->response_byte_limit) {
468
+            if ($this->response_bytes === $this->response_byte_limit) {
469
+                // Already at maximum, move on
470
+                return $data_length;
471
+            }
472
+
473
+            if (($this->response_bytes + $data_length) > $this->response_byte_limit) {
474
+                // Limit the length
475
+                $limited_length = ($this->response_byte_limit - $this->response_bytes);
476
+                $data = substr($data, 0, $limited_length);
477
+            }
478
+        }
479
+
480
+        if ($this->stream_handle) {
481
+            fwrite($this->stream_handle, $data);
482
+        }
483
+        else {
484
+            $this->response_data .= $data;
485
+        }
486
+
487
+        $this->response_bytes += strlen($data);
488
+        return $data_length;
489
+    }
490
+
491
+    /**
492
+     * Format a URL given GET data
493
+     *
494
+     * @param string $url
495
+     * @param array|object $data Data to build query using, see {@see https://secure.php.net/http_build_query}
496
+     * @return string URL with data
497
+     */
498
+    protected static function format_get($url, $data) {
499
+        if (!empty($data)) {
500
+            $url_parts = parse_url($url);
501
+            if (empty($url_parts['query'])) {
502
+                $query = $url_parts['query'] = '';
503
+            }
504
+            else {
505
+                $query = $url_parts['query'];
506
+            }
507
+
508
+            $query .= '&' . http_build_query($data, null, '&');
509
+            $query = trim($query, '&');
510
+
511
+            if (empty($url_parts['query'])) {
512
+                $url .= '?' . $query;
513
+            }
514
+            else {
515
+                $url = str_replace($url_parts['query'], $query, $url);
516
+            }
517
+        }
518
+        return $url;
519
+    }
520
+
521
+    /**
522
+     * Whether this transport is valid
523
+     *
524
+     * @codeCoverageIgnore
525
+     * @return boolean True if the transport is valid, false otherwise.
526
+     */
527
+    public static function test($capabilities = array()) {
528
+        if (!function_exists('curl_init') || !function_exists('curl_exec')) {
529
+            return false;
530
+        }
531
+
532
+        // If needed, check that our installed curl version supports SSL
533
+        if (isset($capabilities['ssl']) && $capabilities['ssl']) {
534
+            $curl_version = curl_version();
535
+            if (!(CURL_VERSION_SSL & $curl_version['features'])) {
536
+                return false;
537
+            }
538
+        }
539
+
540
+        return true;
541
+    }
542 542
 }
Please login to merge, or discard this patch.
Spacing   +3 added lines, -3 removed lines patch added patch discarded remove patch
@@ -310,7 +310,7 @@  discard block
 block discarded – undo
310 310
 		$options['hooks']->dispatch('curl.before_request', array(&$this->handle));
311 311
 
312 312
 		// Force closing the connection for old versions of cURL (<7.22).
313
-		if ( ! isset( $headers['Connection'] ) ) {
313
+		if (!isset($headers['Connection'])) {
314 314
 			$headers['Connection'] = 'close';
315 315
 		}
316 316
 
@@ -505,11 +505,11 @@  discard block
 block discarded – undo
505 505
 				$query = $url_parts['query'];
506 506
 			}
507 507
 
508
-			$query .= '&' . http_build_query($data, null, '&');
508
+			$query .= '&'.http_build_query($data, null, '&');
509 509
 			$query = trim($query, '&');
510 510
 
511 511
 			if (empty($url_parts['query'])) {
512
-				$url .= '?' . $query;
512
+				$url .= '?'.$query;
513 513
 			}
514 514
 			else {
515 515
 				$url = str_replace($url_parts['query'], $query, $url);
Please login to merge, or discard this patch.
Braces   +10 added lines, -20 removed lines patch added patch discarded remove patch
@@ -149,8 +149,7 @@  discard block
 block discarded – undo
149 149
 			if ($options['verify'] === false) {
150 150
 				curl_setopt($this->handle, CURLOPT_SSL_VERIFYHOST, 0);
151 151
 				curl_setopt($this->handle, CURLOPT_SSL_VERIFYPEER, 0);
152
-			}
153
-			elseif (is_string($options['verify'])) {
152
+			} elseif (is_string($options['verify'])) {
154 153
 				curl_setopt($this->handle, CURLOPT_CAINFO, $options['verify']);
155 154
 			}
156 155
 		}
@@ -246,8 +245,7 @@  discard block
 block discarded – undo
246 245
 								);
247 246
 					$responses[$key] = $exception;
248 247
 					$options['hooks']->dispatch('transport.internal.parse_error', array(&$responses[$key], $requests[$key]));
249
-				}
250
-				else {
248
+				} else {
251 249
 					$responses[$key] = $subrequests[$key]->process_response($subrequests[$key]->response_data, $options);
252 250
 
253 251
 					$options['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$key], $requests[$key]));
@@ -322,8 +320,7 @@  discard block
 block discarded – undo
322 320
 			if ($data_format === 'query') {
323 321
 				$url = self::format_get($url, $data);
324 322
 				$data = '';
325
-			}
326
-			elseif (!is_string($data)) {
323
+			} elseif (!is_string($data)) {
327 324
 				$data = http_build_query($data, null, '&');
328 325
 			}
329 326
 		}
@@ -361,15 +358,13 @@  discard block
 block discarded – undo
361 358
 
362 359
 		if (is_int($timeout) || $this->version < self::CURL_7_16_2) {
363 360
 			curl_setopt($this->handle, CURLOPT_TIMEOUT, ceil($timeout));
364
-		}
365
-		else {
361
+		} else {
366 362
 			curl_setopt($this->handle, CURLOPT_TIMEOUT_MS, round($timeout * 1000));
367 363
 		}
368 364
 
369 365
 		if (is_int($options['connect_timeout']) || $this->version < self::CURL_7_16_2) {
370 366
 			curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT, ceil($options['connect_timeout']));
371
-		}
372
-		else {
367
+		} else {
373 368
 			curl_setopt($this->handle, CURLOPT_CONNECTTIMEOUT_MS, round($options['connect_timeout'] * 1000));
374 369
 		}
375 370
 		curl_setopt($this->handle, CURLOPT_URL, $url);
@@ -380,8 +375,7 @@  discard block
 block discarded – undo
380 375
 		}
381 376
 		if ($options['protocol_version'] === 1.1) {
382 377
 			curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
383
-		}
384
-		else {
378
+		} else {
385 379
 			curl_setopt($this->handle, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
386 380
 		}
387 381
 
@@ -408,8 +402,7 @@  discard block
 block discarded – undo
408 402
 		if ($options['filename'] !== false) {
409 403
 			fclose($this->stream_handle);
410 404
 			$this->headers = trim($this->headers);
411
-		}
412
-		else {
405
+		} else {
413 406
 			$this->headers .= $response;
414 407
 		}
415 408
 
@@ -479,8 +472,7 @@  discard block
 block discarded – undo
479 472
 
480 473
 		if ($this->stream_handle) {
481 474
 			fwrite($this->stream_handle, $data);
482
-		}
483
-		else {
475
+		} else {
484 476
 			$this->response_data .= $data;
485 477
 		}
486 478
 
@@ -500,8 +492,7 @@  discard block
 block discarded – undo
500 492
 			$url_parts = parse_url($url);
501 493
 			if (empty($url_parts['query'])) {
502 494
 				$query = $url_parts['query'] = '';
503
-			}
504
-			else {
495
+			} else {
505 496
 				$query = $url_parts['query'];
506 497
 			}
507 498
 
@@ -510,8 +501,7 @@  discard block
 block discarded – undo
510 501
 
511 502
 			if (empty($url_parts['query'])) {
512 503
 				$url .= '?' . $query;
513
-			}
514
-			else {
504
+			} else {
515 505
 				$url = str_replace($url_parts['query'], $query, $url);
516 506
 			}
517 507
 		}
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/Transport/fsockopen.php 3 patches
Indentation   +428 added lines, -428 removed lines patch added patch discarded remove patch
@@ -13,432 +13,432 @@
 block discarded – undo
13 13
  * @subpackage Transport
14 14
  */
15 15
 class Requests_Transport_fsockopen implements Requests_Transport {
16
-	/**
17
-	 * Second to microsecond conversion
18
-	 *
19
-	 * @var integer
20
-	 */
21
-	const SECOND_IN_MICROSECONDS = 1000000;
22
-
23
-	/**
24
-	 * Raw HTTP data
25
-	 *
26
-	 * @var string
27
-	 */
28
-	public $headers = '';
29
-
30
-	/**
31
-	 * Stream metadata
32
-	 *
33
-	 * @var array Associative array of properties, see {@see https://secure.php.net/stream_get_meta_data}
34
-	 */
35
-	public $info;
36
-
37
-	/**
38
-	 * What's the maximum number of bytes we should keep?
39
-	 *
40
-	 * @var int|bool Byte count, or false if no limit.
41
-	 */
42
-	protected $max_bytes = false;
43
-
44
-	protected $connect_error = '';
45
-
46
-	/**
47
-	 * Perform a request
48
-	 *
49
-	 * @throws Requests_Exception On failure to connect to socket (`fsockopenerror`)
50
-	 * @throws Requests_Exception On socket timeout (`timeout`)
51
-	 *
52
-	 * @param string $url URL to request
53
-	 * @param array $headers Associative array of request headers
54
-	 * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
55
-	 * @param array $options Request options, see {@see Requests::response()} for documentation
56
-	 * @return string Raw HTTP result
57
-	 */
58
-	public function request($url, $headers = array(), $data = array(), $options = array()) {
59
-		$options['hooks']->dispatch('fsockopen.before_request');
60
-
61
-		$url_parts = parse_url($url);
62
-		if (empty($url_parts)) {
63
-			throw new Requests_Exception('Invalid URL.', 'invalidurl', $url);
64
-		}
65
-		$host = $url_parts['host'];
66
-		$context = stream_context_create();
67
-		$verifyname = false;
68
-		$case_insensitive_headers = new Requests_Utility_CaseInsensitiveDictionary($headers);
69
-
70
-		// HTTPS support
71
-		if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
72
-			$remote_socket = 'ssl://' . $host;
73
-			if (!isset($url_parts['port'])) {
74
-				$url_parts['port'] = 443;
75
-			}
76
-
77
-			$context_options = array(
78
-				'verify_peer' => true,
79
-				// 'CN_match' => $host,
80
-				'capture_peer_cert' => true
81
-			);
82
-			$verifyname = true;
83
-
84
-			// SNI, if enabled (OpenSSL >=0.9.8j)
85
-			if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
86
-				$context_options['SNI_enabled'] = true;
87
-				if (isset($options['verifyname']) && $options['verifyname'] === false) {
88
-					$context_options['SNI_enabled'] = false;
89
-				}
90
-			}
91
-
92
-			if (isset($options['verify'])) {
93
-				if ($options['verify'] === false) {
94
-					$context_options['verify_peer'] = false;
95
-				}
96
-				elseif (is_string($options['verify'])) {
97
-					$context_options['cafile'] = $options['verify'];
98
-				}
99
-			}
100
-
101
-			if (isset($options['verifyname']) && $options['verifyname'] === false) {
102
-				$context_options['verify_peer_name'] = false;
103
-				$verifyname = false;
104
-			}
105
-
106
-			stream_context_set_option($context, array('ssl' => $context_options));
107
-		}
108
-		else {
109
-			$remote_socket = 'tcp://' . $host;
110
-		}
111
-
112
-		$this->max_bytes = $options['max_bytes'];
113
-
114
-		if (!isset($url_parts['port'])) {
115
-			$url_parts['port'] = 80;
116
-		}
117
-		$remote_socket .= ':' . $url_parts['port'];
118
-
119
-		set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE);
120
-
121
-		$options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket));
122
-
123
-		$socket = stream_socket_client($remote_socket, $errno, $errstr, ceil($options['connect_timeout']), STREAM_CLIENT_CONNECT, $context);
124
-
125
-		restore_error_handler();
126
-
127
-		if ($verifyname && !$this->verify_certificate_from_context($host, $context)) {
128
-			throw new Requests_Exception('SSL certificate did not match the requested domain name', 'ssl.no_match');
129
-		}
130
-
131
-		if (!$socket) {
132
-			if ($errno === 0) {
133
-				// Connection issue
134
-				throw new Requests_Exception(rtrim($this->connect_error), 'fsockopen.connect_error');
135
-			}
136
-
137
-			throw new Requests_Exception($errstr, 'fsockopenerror', null, $errno);
138
-		}
139
-
140
-		$data_format = $options['data_format'];
141
-
142
-		if ($data_format === 'query') {
143
-			$path = self::format_get($url_parts, $data);
144
-			$data = '';
145
-		}
146
-		else {
147
-			$path = self::format_get($url_parts, array());
148
-		}
149
-
150
-		$options['hooks']->dispatch('fsockopen.remote_host_path', array(&$path, $url));
151
-
152
-		$request_body = '';
153
-		$out = sprintf("%s %s HTTP/%.1f\r\n", $options['type'], $path, $options['protocol_version']);
154
-
155
-		if ($options['type'] !== Requests::TRACE) {
156
-			if (is_array($data)) {
157
-				$request_body = http_build_query($data, null, '&');
158
-			}
159
-			else {
160
-				$request_body = $data;
161
-			}
162
-
163
-			if (!empty($data)) {
164
-				if (!isset($case_insensitive_headers['Content-Length'])) {
165
-					$headers['Content-Length'] = strlen($request_body);
166
-				}
167
-
168
-				if (!isset($case_insensitive_headers['Content-Type'])) {
169
-					$headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
170
-				}
171
-			}
172
-		}
173
-
174
-		if (!isset($case_insensitive_headers['Host'])) {
175
-			$out .= sprintf('Host: %s', $url_parts['host']);
176
-
177
-			if (( 'http' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 80 ) || ( 'https' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 443 )) {
178
-				$out .= ':' . $url_parts['port'];
179
-			}
180
-			$out .= "\r\n";
181
-		}
182
-
183
-		if (!isset($case_insensitive_headers['User-Agent'])) {
184
-			$out .= sprintf("User-Agent: %s\r\n", $options['useragent']);
185
-		}
186
-
187
-		$accept_encoding = $this->accept_encoding();
188
-		if (!isset($case_insensitive_headers['Accept-Encoding']) && !empty($accept_encoding)) {
189
-			$out .= sprintf("Accept-Encoding: %s\r\n", $accept_encoding);
190
-		}
191
-
192
-		$headers = Requests::flatten($headers);
193
-
194
-		if (!empty($headers)) {
195
-			$out .= implode($headers, "\r\n") . "\r\n";
196
-		}
197
-
198
-		$options['hooks']->dispatch('fsockopen.after_headers', array(&$out));
199
-
200
-		if (substr($out, -2) !== "\r\n") {
201
-			$out .= "\r\n";
202
-		}
203
-
204
-		if (!isset($case_insensitive_headers['Connection'])) {
205
-			$out .= "Connection: Close\r\n";
206
-		}
207
-
208
-		$out .= "\r\n" . $request_body;
209
-
210
-		$options['hooks']->dispatch('fsockopen.before_send', array(&$out));
211
-
212
-		fwrite($socket, $out);
213
-		$options['hooks']->dispatch('fsockopen.after_send', array($out));
214
-
215
-		if (!$options['blocking']) {
216
-			fclose($socket);
217
-			$fake_headers = '';
218
-			$options['hooks']->dispatch('fsockopen.after_request', array(&$fake_headers));
219
-			return '';
220
-		}
221
-
222
-		$timeout_sec = (int) floor($options['timeout']);
223
-		if ($timeout_sec == $options['timeout']) {
224
-			$timeout_msec = 0;
225
-		}
226
-		else {
227
-			$timeout_msec = self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
228
-		}
229
-		stream_set_timeout($socket, $timeout_sec, $timeout_msec);
230
-
231
-		$response = $body = $headers = '';
232
-		$this->info = stream_get_meta_data($socket);
233
-		$size = 0;
234
-		$doingbody = false;
235
-		$download = false;
236
-		if ($options['filename']) {
237
-			$download = fopen($options['filename'], 'wb');
238
-		}
239
-
240
-		while (!feof($socket)) {
241
-			$this->info = stream_get_meta_data($socket);
242
-			if ($this->info['timed_out']) {
243
-				throw new Requests_Exception('fsocket timed out', 'timeout');
244
-			}
245
-
246
-			$block = fread($socket, Requests::BUFFER_SIZE);
247
-			if (!$doingbody) {
248
-				$response .= $block;
249
-				if (strpos($response, "\r\n\r\n")) {
250
-					list($headers, $block) = explode("\r\n\r\n", $response, 2);
251
-					$doingbody = true;
252
-				}
253
-			}
254
-
255
-			// Are we in body mode now?
256
-			if ($doingbody) {
257
-				$options['hooks']->dispatch('request.progress', array($block, $size, $this->max_bytes));
258
-				$data_length = strlen($block);
259
-				if ($this->max_bytes) {
260
-					// Have we already hit a limit?
261
-					if ($size === $this->max_bytes) {
262
-						continue;
263
-					}
264
-					if (($size + $data_length) > $this->max_bytes) {
265
-						// Limit the length
266
-						$limited_length = ($this->max_bytes - $size);
267
-						$block = substr($block, 0, $limited_length);
268
-					}
269
-				}
270
-
271
-				$size += strlen($block);
272
-				if ($download) {
273
-					fwrite($download, $block);
274
-				}
275
-				else {
276
-					$body .= $block;
277
-				}
278
-			}
279
-		}
280
-		$this->headers = $headers;
281
-
282
-		if ($download) {
283
-			fclose($download);
284
-		}
285
-		else {
286
-			$this->headers .= "\r\n\r\n" . $body;
287
-		}
288
-		fclose($socket);
289
-
290
-		$options['hooks']->dispatch('fsockopen.after_request', array(&$this->headers, &$this->info));
291
-		return $this->headers;
292
-	}
293
-
294
-	/**
295
-	 * Send multiple requests simultaneously
296
-	 *
297
-	 * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
298
-	 * @param array $options Global options, see {@see Requests::response()} for documentation
299
-	 * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
300
-	 */
301
-	public function request_multiple($requests, $options) {
302
-		$responses = array();
303
-		$class = get_class($this);
304
-		foreach ($requests as $id => $request) {
305
-			try {
306
-				$handler = new $class();
307
-				$responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
308
-
309
-				$request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
310
-			}
311
-			catch (Requests_Exception $e) {
312
-				$responses[$id] = $e;
313
-			}
314
-
315
-			if (!is_string($responses[$id])) {
316
-				$request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id));
317
-			}
318
-		}
319
-
320
-		return $responses;
321
-	}
322
-
323
-	/**
324
-	 * Retrieve the encodings we can accept
325
-	 *
326
-	 * @return string Accept-Encoding header value
327
-	 */
328
-	protected static function accept_encoding() {
329
-		$type = array();
330
-		if (function_exists('gzinflate')) {
331
-			$type[] = 'deflate;q=1.0';
332
-		}
333
-
334
-		if (function_exists('gzuncompress')) {
335
-			$type[] = 'compress;q=0.5';
336
-		}
337
-
338
-		$type[] = 'gzip;q=0.5';
339
-
340
-		return implode(', ', $type);
341
-	}
342
-
343
-	/**
344
-	 * Format a URL given GET data
345
-	 *
346
-	 * @param array $url_parts
347
-	 * @param array|object $data Data to build query using, see {@see https://secure.php.net/http_build_query}
348
-	 * @return string URL with data
349
-	 */
350
-	protected static function format_get($url_parts, $data) {
351
-		if (!empty($data)) {
352
-			if (empty($url_parts['query'])) {
353
-				$url_parts['query'] = '';
354
-			}
355
-
356
-			$url_parts['query'] .= '&' . http_build_query($data, null, '&');
357
-			$url_parts['query'] = trim($url_parts['query'], '&');
358
-		}
359
-		if (isset($url_parts['path'])) {
360
-			if (isset($url_parts['query'])) {
361
-				$get = $url_parts['path'] . '?' . $url_parts['query'];
362
-			}
363
-			else {
364
-				$get = $url_parts['path'];
365
-			}
366
-		}
367
-		else {
368
-			$get = '/';
369
-		}
370
-		return $get;
371
-	}
372
-
373
-	/**
374
-	 * Error handler for stream_socket_client()
375
-	 *
376
-	 * @param int $errno Error number (e.g. E_WARNING)
377
-	 * @param string $errstr Error message
378
-	 */
379
-	public function connect_error_handler($errno, $errstr) {
380
-		// Double-check we can handle it
381
-		if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
382
-			// Return false to indicate the default error handler should engage
383
-			return false;
384
-		}
385
-
386
-		$this->connect_error .= $errstr . "\n";
387
-		return true;
388
-	}
389
-
390
-	/**
391
-	 * Verify the certificate against common name and subject alternative names
392
-	 *
393
-	 * Unfortunately, PHP doesn't check the certificate against the alternative
394
-	 * names, leading things like 'https://www.github.com/' to be invalid.
395
-	 * Instead
396
-	 *
397
-	 * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
398
-	 *
399
-	 * @throws Requests_Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`)
400
-	 * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
401
-	 * @param string $host Host name to verify against
402
-	 * @param resource $context Stream context
403
-	 * @return bool
404
-	 */
405
-	public function verify_certificate_from_context($host, $context) {
406
-		$meta = stream_context_get_options($context);
407
-
408
-		// If we don't have SSL options, then we couldn't make the connection at
409
-		// all
410
-		if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) {
411
-			throw new Requests_Exception(rtrim($this->connect_error), 'ssl.connect_error');
412
-		}
413
-
414
-		$cert = openssl_x509_parse($meta['ssl']['peer_certificate']);
415
-
416
-		return Requests_SSL::verify_certificate($host, $cert);
417
-	}
418
-
419
-	/**
420
-	 * Whether this transport is valid
421
-	 *
422
-	 * @codeCoverageIgnore
423
-	 * @return boolean True if the transport is valid, false otherwise.
424
-	 */
425
-	public static function test($capabilities = array()) {
426
-		if (!function_exists('fsockopen')) {
427
-			return false;
428
-		}
429
-
430
-		// If needed, check that streams support SSL
431
-		if (isset($capabilities['ssl']) && $capabilities['ssl']) {
432
-			if (!extension_loaded('openssl') || !function_exists('openssl_x509_parse')) {
433
-				return false;
434
-			}
435
-
436
-			// Currently broken, thanks to https://github.com/facebook/hhvm/issues/2156
437
-			if (defined('HHVM_VERSION')) {
438
-				return false;
439
-			}
440
-		}
441
-
442
-		return true;
443
-	}
16
+    /**
17
+     * Second to microsecond conversion
18
+     *
19
+     * @var integer
20
+     */
21
+    const SECOND_IN_MICROSECONDS = 1000000;
22
+
23
+    /**
24
+     * Raw HTTP data
25
+     *
26
+     * @var string
27
+     */
28
+    public $headers = '';
29
+
30
+    /**
31
+     * Stream metadata
32
+     *
33
+     * @var array Associative array of properties, see {@see https://secure.php.net/stream_get_meta_data}
34
+     */
35
+    public $info;
36
+
37
+    /**
38
+     * What's the maximum number of bytes we should keep?
39
+     *
40
+     * @var int|bool Byte count, or false if no limit.
41
+     */
42
+    protected $max_bytes = false;
43
+
44
+    protected $connect_error = '';
45
+
46
+    /**
47
+     * Perform a request
48
+     *
49
+     * @throws Requests_Exception On failure to connect to socket (`fsockopenerror`)
50
+     * @throws Requests_Exception On socket timeout (`timeout`)
51
+     *
52
+     * @param string $url URL to request
53
+     * @param array $headers Associative array of request headers
54
+     * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
55
+     * @param array $options Request options, see {@see Requests::response()} for documentation
56
+     * @return string Raw HTTP result
57
+     */
58
+    public function request($url, $headers = array(), $data = array(), $options = array()) {
59
+        $options['hooks']->dispatch('fsockopen.before_request');
60
+
61
+        $url_parts = parse_url($url);
62
+        if (empty($url_parts)) {
63
+            throw new Requests_Exception('Invalid URL.', 'invalidurl', $url);
64
+        }
65
+        $host = $url_parts['host'];
66
+        $context = stream_context_create();
67
+        $verifyname = false;
68
+        $case_insensitive_headers = new Requests_Utility_CaseInsensitiveDictionary($headers);
69
+
70
+        // HTTPS support
71
+        if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
72
+            $remote_socket = 'ssl://' . $host;
73
+            if (!isset($url_parts['port'])) {
74
+                $url_parts['port'] = 443;
75
+            }
76
+
77
+            $context_options = array(
78
+                'verify_peer' => true,
79
+                // 'CN_match' => $host,
80
+                'capture_peer_cert' => true
81
+            );
82
+            $verifyname = true;
83
+
84
+            // SNI, if enabled (OpenSSL >=0.9.8j)
85
+            if (defined('OPENSSL_TLSEXT_SERVER_NAME') && OPENSSL_TLSEXT_SERVER_NAME) {
86
+                $context_options['SNI_enabled'] = true;
87
+                if (isset($options['verifyname']) && $options['verifyname'] === false) {
88
+                    $context_options['SNI_enabled'] = false;
89
+                }
90
+            }
91
+
92
+            if (isset($options['verify'])) {
93
+                if ($options['verify'] === false) {
94
+                    $context_options['verify_peer'] = false;
95
+                }
96
+                elseif (is_string($options['verify'])) {
97
+                    $context_options['cafile'] = $options['verify'];
98
+                }
99
+            }
100
+
101
+            if (isset($options['verifyname']) && $options['verifyname'] === false) {
102
+                $context_options['verify_peer_name'] = false;
103
+                $verifyname = false;
104
+            }
105
+
106
+            stream_context_set_option($context, array('ssl' => $context_options));
107
+        }
108
+        else {
109
+            $remote_socket = 'tcp://' . $host;
110
+        }
111
+
112
+        $this->max_bytes = $options['max_bytes'];
113
+
114
+        if (!isset($url_parts['port'])) {
115
+            $url_parts['port'] = 80;
116
+        }
117
+        $remote_socket .= ':' . $url_parts['port'];
118
+
119
+        set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE);
120
+
121
+        $options['hooks']->dispatch('fsockopen.remote_socket', array(&$remote_socket));
122
+
123
+        $socket = stream_socket_client($remote_socket, $errno, $errstr, ceil($options['connect_timeout']), STREAM_CLIENT_CONNECT, $context);
124
+
125
+        restore_error_handler();
126
+
127
+        if ($verifyname && !$this->verify_certificate_from_context($host, $context)) {
128
+            throw new Requests_Exception('SSL certificate did not match the requested domain name', 'ssl.no_match');
129
+        }
130
+
131
+        if (!$socket) {
132
+            if ($errno === 0) {
133
+                // Connection issue
134
+                throw new Requests_Exception(rtrim($this->connect_error), 'fsockopen.connect_error');
135
+            }
136
+
137
+            throw new Requests_Exception($errstr, 'fsockopenerror', null, $errno);
138
+        }
139
+
140
+        $data_format = $options['data_format'];
141
+
142
+        if ($data_format === 'query') {
143
+            $path = self::format_get($url_parts, $data);
144
+            $data = '';
145
+        }
146
+        else {
147
+            $path = self::format_get($url_parts, array());
148
+        }
149
+
150
+        $options['hooks']->dispatch('fsockopen.remote_host_path', array(&$path, $url));
151
+
152
+        $request_body = '';
153
+        $out = sprintf("%s %s HTTP/%.1f\r\n", $options['type'], $path, $options['protocol_version']);
154
+
155
+        if ($options['type'] !== Requests::TRACE) {
156
+            if (is_array($data)) {
157
+                $request_body = http_build_query($data, null, '&');
158
+            }
159
+            else {
160
+                $request_body = $data;
161
+            }
162
+
163
+            if (!empty($data)) {
164
+                if (!isset($case_insensitive_headers['Content-Length'])) {
165
+                    $headers['Content-Length'] = strlen($request_body);
166
+                }
167
+
168
+                if (!isset($case_insensitive_headers['Content-Type'])) {
169
+                    $headers['Content-Type'] = 'application/x-www-form-urlencoded; charset=UTF-8';
170
+                }
171
+            }
172
+        }
173
+
174
+        if (!isset($case_insensitive_headers['Host'])) {
175
+            $out .= sprintf('Host: %s', $url_parts['host']);
176
+
177
+            if (( 'http' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 80 ) || ( 'https' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 443 )) {
178
+                $out .= ':' . $url_parts['port'];
179
+            }
180
+            $out .= "\r\n";
181
+        }
182
+
183
+        if (!isset($case_insensitive_headers['User-Agent'])) {
184
+            $out .= sprintf("User-Agent: %s\r\n", $options['useragent']);
185
+        }
186
+
187
+        $accept_encoding = $this->accept_encoding();
188
+        if (!isset($case_insensitive_headers['Accept-Encoding']) && !empty($accept_encoding)) {
189
+            $out .= sprintf("Accept-Encoding: %s\r\n", $accept_encoding);
190
+        }
191
+
192
+        $headers = Requests::flatten($headers);
193
+
194
+        if (!empty($headers)) {
195
+            $out .= implode($headers, "\r\n") . "\r\n";
196
+        }
197
+
198
+        $options['hooks']->dispatch('fsockopen.after_headers', array(&$out));
199
+
200
+        if (substr($out, -2) !== "\r\n") {
201
+            $out .= "\r\n";
202
+        }
203
+
204
+        if (!isset($case_insensitive_headers['Connection'])) {
205
+            $out .= "Connection: Close\r\n";
206
+        }
207
+
208
+        $out .= "\r\n" . $request_body;
209
+
210
+        $options['hooks']->dispatch('fsockopen.before_send', array(&$out));
211
+
212
+        fwrite($socket, $out);
213
+        $options['hooks']->dispatch('fsockopen.after_send', array($out));
214
+
215
+        if (!$options['blocking']) {
216
+            fclose($socket);
217
+            $fake_headers = '';
218
+            $options['hooks']->dispatch('fsockopen.after_request', array(&$fake_headers));
219
+            return '';
220
+        }
221
+
222
+        $timeout_sec = (int) floor($options['timeout']);
223
+        if ($timeout_sec == $options['timeout']) {
224
+            $timeout_msec = 0;
225
+        }
226
+        else {
227
+            $timeout_msec = self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
228
+        }
229
+        stream_set_timeout($socket, $timeout_sec, $timeout_msec);
230
+
231
+        $response = $body = $headers = '';
232
+        $this->info = stream_get_meta_data($socket);
233
+        $size = 0;
234
+        $doingbody = false;
235
+        $download = false;
236
+        if ($options['filename']) {
237
+            $download = fopen($options['filename'], 'wb');
238
+        }
239
+
240
+        while (!feof($socket)) {
241
+            $this->info = stream_get_meta_data($socket);
242
+            if ($this->info['timed_out']) {
243
+                throw new Requests_Exception('fsocket timed out', 'timeout');
244
+            }
245
+
246
+            $block = fread($socket, Requests::BUFFER_SIZE);
247
+            if (!$doingbody) {
248
+                $response .= $block;
249
+                if (strpos($response, "\r\n\r\n")) {
250
+                    list($headers, $block) = explode("\r\n\r\n", $response, 2);
251
+                    $doingbody = true;
252
+                }
253
+            }
254
+
255
+            // Are we in body mode now?
256
+            if ($doingbody) {
257
+                $options['hooks']->dispatch('request.progress', array($block, $size, $this->max_bytes));
258
+                $data_length = strlen($block);
259
+                if ($this->max_bytes) {
260
+                    // Have we already hit a limit?
261
+                    if ($size === $this->max_bytes) {
262
+                        continue;
263
+                    }
264
+                    if (($size + $data_length) > $this->max_bytes) {
265
+                        // Limit the length
266
+                        $limited_length = ($this->max_bytes - $size);
267
+                        $block = substr($block, 0, $limited_length);
268
+                    }
269
+                }
270
+
271
+                $size += strlen($block);
272
+                if ($download) {
273
+                    fwrite($download, $block);
274
+                }
275
+                else {
276
+                    $body .= $block;
277
+                }
278
+            }
279
+        }
280
+        $this->headers = $headers;
281
+
282
+        if ($download) {
283
+            fclose($download);
284
+        }
285
+        else {
286
+            $this->headers .= "\r\n\r\n" . $body;
287
+        }
288
+        fclose($socket);
289
+
290
+        $options['hooks']->dispatch('fsockopen.after_request', array(&$this->headers, &$this->info));
291
+        return $this->headers;
292
+    }
293
+
294
+    /**
295
+     * Send multiple requests simultaneously
296
+     *
297
+     * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
298
+     * @param array $options Global options, see {@see Requests::response()} for documentation
299
+     * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
300
+     */
301
+    public function request_multiple($requests, $options) {
302
+        $responses = array();
303
+        $class = get_class($this);
304
+        foreach ($requests as $id => $request) {
305
+            try {
306
+                $handler = new $class();
307
+                $responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
308
+
309
+                $request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
310
+            }
311
+            catch (Requests_Exception $e) {
312
+                $responses[$id] = $e;
313
+            }
314
+
315
+            if (!is_string($responses[$id])) {
316
+                $request['options']['hooks']->dispatch('multiple.request.complete', array(&$responses[$id], $id));
317
+            }
318
+        }
319
+
320
+        return $responses;
321
+    }
322
+
323
+    /**
324
+     * Retrieve the encodings we can accept
325
+     *
326
+     * @return string Accept-Encoding header value
327
+     */
328
+    protected static function accept_encoding() {
329
+        $type = array();
330
+        if (function_exists('gzinflate')) {
331
+            $type[] = 'deflate;q=1.0';
332
+        }
333
+
334
+        if (function_exists('gzuncompress')) {
335
+            $type[] = 'compress;q=0.5';
336
+        }
337
+
338
+        $type[] = 'gzip;q=0.5';
339
+
340
+        return implode(', ', $type);
341
+    }
342
+
343
+    /**
344
+     * Format a URL given GET data
345
+     *
346
+     * @param array $url_parts
347
+     * @param array|object $data Data to build query using, see {@see https://secure.php.net/http_build_query}
348
+     * @return string URL with data
349
+     */
350
+    protected static function format_get($url_parts, $data) {
351
+        if (!empty($data)) {
352
+            if (empty($url_parts['query'])) {
353
+                $url_parts['query'] = '';
354
+            }
355
+
356
+            $url_parts['query'] .= '&' . http_build_query($data, null, '&');
357
+            $url_parts['query'] = trim($url_parts['query'], '&');
358
+        }
359
+        if (isset($url_parts['path'])) {
360
+            if (isset($url_parts['query'])) {
361
+                $get = $url_parts['path'] . '?' . $url_parts['query'];
362
+            }
363
+            else {
364
+                $get = $url_parts['path'];
365
+            }
366
+        }
367
+        else {
368
+            $get = '/';
369
+        }
370
+        return $get;
371
+    }
372
+
373
+    /**
374
+     * Error handler for stream_socket_client()
375
+     *
376
+     * @param int $errno Error number (e.g. E_WARNING)
377
+     * @param string $errstr Error message
378
+     */
379
+    public function connect_error_handler($errno, $errstr) {
380
+        // Double-check we can handle it
381
+        if (($errno & E_WARNING) === 0 && ($errno & E_NOTICE) === 0) {
382
+            // Return false to indicate the default error handler should engage
383
+            return false;
384
+        }
385
+
386
+        $this->connect_error .= $errstr . "\n";
387
+        return true;
388
+    }
389
+
390
+    /**
391
+     * Verify the certificate against common name and subject alternative names
392
+     *
393
+     * Unfortunately, PHP doesn't check the certificate against the alternative
394
+     * names, leading things like 'https://www.github.com/' to be invalid.
395
+     * Instead
396
+     *
397
+     * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
398
+     *
399
+     * @throws Requests_Exception On failure to connect via TLS (`fsockopen.ssl.connect_error`)
400
+     * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
401
+     * @param string $host Host name to verify against
402
+     * @param resource $context Stream context
403
+     * @return bool
404
+     */
405
+    public function verify_certificate_from_context($host, $context) {
406
+        $meta = stream_context_get_options($context);
407
+
408
+        // If we don't have SSL options, then we couldn't make the connection at
409
+        // all
410
+        if (empty($meta) || empty($meta['ssl']) || empty($meta['ssl']['peer_certificate'])) {
411
+            throw new Requests_Exception(rtrim($this->connect_error), 'ssl.connect_error');
412
+        }
413
+
414
+        $cert = openssl_x509_parse($meta['ssl']['peer_certificate']);
415
+
416
+        return Requests_SSL::verify_certificate($host, $cert);
417
+    }
418
+
419
+    /**
420
+     * Whether this transport is valid
421
+     *
422
+     * @codeCoverageIgnore
423
+     * @return boolean True if the transport is valid, false otherwise.
424
+     */
425
+    public static function test($capabilities = array()) {
426
+        if (!function_exists('fsockopen')) {
427
+            return false;
428
+        }
429
+
430
+        // If needed, check that streams support SSL
431
+        if (isset($capabilities['ssl']) && $capabilities['ssl']) {
432
+            if (!extension_loaded('openssl') || !function_exists('openssl_x509_parse')) {
433
+                return false;
434
+            }
435
+
436
+            // Currently broken, thanks to https://github.com/facebook/hhvm/issues/2156
437
+            if (defined('HHVM_VERSION')) {
438
+                return false;
439
+            }
440
+        }
441
+
442
+        return true;
443
+    }
444 444
 }
Please login to merge, or discard this patch.
Spacing   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -69,7 +69,7 @@  discard block
 block discarded – undo
69 69
 
70 70
 		// HTTPS support
71 71
 		if (isset($url_parts['scheme']) && strtolower($url_parts['scheme']) === 'https') {
72
-			$remote_socket = 'ssl://' . $host;
72
+			$remote_socket = 'ssl://'.$host;
73 73
 			if (!isset($url_parts['port'])) {
74 74
 				$url_parts['port'] = 443;
75 75
 			}
@@ -106,7 +106,7 @@  discard block
 block discarded – undo
106 106
 			stream_context_set_option($context, array('ssl' => $context_options));
107 107
 		}
108 108
 		else {
109
-			$remote_socket = 'tcp://' . $host;
109
+			$remote_socket = 'tcp://'.$host;
110 110
 		}
111 111
 
112 112
 		$this->max_bytes = $options['max_bytes'];
@@ -114,7 +114,7 @@  discard block
 block discarded – undo
114 114
 		if (!isset($url_parts['port'])) {
115 115
 			$url_parts['port'] = 80;
116 116
 		}
117
-		$remote_socket .= ':' . $url_parts['port'];
117
+		$remote_socket .= ':'.$url_parts['port'];
118 118
 
119 119
 		set_error_handler(array($this, 'connect_error_handler'), E_WARNING | E_NOTICE);
120 120
 
@@ -174,8 +174,8 @@  discard block
 block discarded – undo
174 174
 		if (!isset($case_insensitive_headers['Host'])) {
175 175
 			$out .= sprintf('Host: %s', $url_parts['host']);
176 176
 
177
-			if (( 'http' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 80 ) || ( 'https' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 443 )) {
178
-				$out .= ':' . $url_parts['port'];
177
+			if (('http' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 80) || ('https' === strtolower($url_parts['scheme']) && $url_parts['port'] !== 443)) {
178
+				$out .= ':'.$url_parts['port'];
179 179
 			}
180 180
 			$out .= "\r\n";
181 181
 		}
@@ -192,7 +192,7 @@  discard block
 block discarded – undo
192 192
 		$headers = Requests::flatten($headers);
193 193
 
194 194
 		if (!empty($headers)) {
195
-			$out .= implode($headers, "\r\n") . "\r\n";
195
+			$out .= implode($headers, "\r\n")."\r\n";
196 196
 		}
197 197
 
198 198
 		$options['hooks']->dispatch('fsockopen.after_headers', array(&$out));
@@ -205,7 +205,7 @@  discard block
 block discarded – undo
205 205
 			$out .= "Connection: Close\r\n";
206 206
 		}
207 207
 
208
-		$out .= "\r\n" . $request_body;
208
+		$out .= "\r\n".$request_body;
209 209
 
210 210
 		$options['hooks']->dispatch('fsockopen.before_send', array(&$out));
211 211
 
@@ -283,7 +283,7 @@  discard block
 block discarded – undo
283 283
 			fclose($download);
284 284
 		}
285 285
 		else {
286
-			$this->headers .= "\r\n\r\n" . $body;
286
+			$this->headers .= "\r\n\r\n".$body;
287 287
 		}
288 288
 		fclose($socket);
289 289
 
@@ -353,12 +353,12 @@  discard block
 block discarded – undo
353 353
 				$url_parts['query'] = '';
354 354
 			}
355 355
 
356
-			$url_parts['query'] .= '&' . http_build_query($data, null, '&');
356
+			$url_parts['query'] .= '&'.http_build_query($data, null, '&');
357 357
 			$url_parts['query'] = trim($url_parts['query'], '&');
358 358
 		}
359 359
 		if (isset($url_parts['path'])) {
360 360
 			if (isset($url_parts['query'])) {
361
-				$get = $url_parts['path'] . '?' . $url_parts['query'];
361
+				$get = $url_parts['path'].'?'.$url_parts['query'];
362 362
 			}
363 363
 			else {
364 364
 				$get = $url_parts['path'];
@@ -383,7 +383,7 @@  discard block
 block discarded – undo
383 383
 			return false;
384 384
 		}
385 385
 
386
-		$this->connect_error .= $errstr . "\n";
386
+		$this->connect_error .= $errstr."\n";
387 387
 		return true;
388 388
 	}
389 389
 
Please login to merge, or discard this patch.
Braces   +10 added lines, -20 removed lines patch added patch discarded remove patch
@@ -92,8 +92,7 @@  discard block
 block discarded – undo
92 92
 			if (isset($options['verify'])) {
93 93
 				if ($options['verify'] === false) {
94 94
 					$context_options['verify_peer'] = false;
95
-				}
96
-				elseif (is_string($options['verify'])) {
95
+				} elseif (is_string($options['verify'])) {
97 96
 					$context_options['cafile'] = $options['verify'];
98 97
 				}
99 98
 			}
@@ -104,8 +103,7 @@  discard block
 block discarded – undo
104 103
 			}
105 104
 
106 105
 			stream_context_set_option($context, array('ssl' => $context_options));
107
-		}
108
-		else {
106
+		} else {
109 107
 			$remote_socket = 'tcp://' . $host;
110 108
 		}
111 109
 
@@ -142,8 +140,7 @@  discard block
 block discarded – undo
142 140
 		if ($data_format === 'query') {
143 141
 			$path = self::format_get($url_parts, $data);
144 142
 			$data = '';
145
-		}
146
-		else {
143
+		} else {
147 144
 			$path = self::format_get($url_parts, array());
148 145
 		}
149 146
 
@@ -155,8 +152,7 @@  discard block
 block discarded – undo
155 152
 		if ($options['type'] !== Requests::TRACE) {
156 153
 			if (is_array($data)) {
157 154
 				$request_body = http_build_query($data, null, '&');
158
-			}
159
-			else {
155
+			} else {
160 156
 				$request_body = $data;
161 157
 			}
162 158
 
@@ -222,8 +218,7 @@  discard block
 block discarded – undo
222 218
 		$timeout_sec = (int) floor($options['timeout']);
223 219
 		if ($timeout_sec == $options['timeout']) {
224 220
 			$timeout_msec = 0;
225
-		}
226
-		else {
221
+		} else {
227 222
 			$timeout_msec = self::SECOND_IN_MICROSECONDS * $options['timeout'] % self::SECOND_IN_MICROSECONDS;
228 223
 		}
229 224
 		stream_set_timeout($socket, $timeout_sec, $timeout_msec);
@@ -271,8 +266,7 @@  discard block
 block discarded – undo
271 266
 				$size += strlen($block);
272 267
 				if ($download) {
273 268
 					fwrite($download, $block);
274
-				}
275
-				else {
269
+				} else {
276 270
 					$body .= $block;
277 271
 				}
278 272
 			}
@@ -281,8 +275,7 @@  discard block
 block discarded – undo
281 275
 
282 276
 		if ($download) {
283 277
 			fclose($download);
284
-		}
285
-		else {
278
+		} else {
286 279
 			$this->headers .= "\r\n\r\n" . $body;
287 280
 		}
288 281
 		fclose($socket);
@@ -307,8 +300,7 @@  discard block
 block discarded – undo
307 300
 				$responses[$id] = $handler->request($request['url'], $request['headers'], $request['data'], $request['options']);
308 301
 
309 302
 				$request['options']['hooks']->dispatch('transport.internal.parse_response', array(&$responses[$id], $request));
310
-			}
311
-			catch (Requests_Exception $e) {
303
+			} catch (Requests_Exception $e) {
312 304
 				$responses[$id] = $e;
313 305
 			}
314 306
 
@@ -359,12 +351,10 @@  discard block
 block discarded – undo
359 351
 		if (isset($url_parts['path'])) {
360 352
 			if (isset($url_parts['query'])) {
361 353
 				$get = $url_parts['path'] . '?' . $url_parts['query'];
362
-			}
363
-			else {
354
+			} else {
364 355
 				$get = $url_parts['path'];
365 356
 			}
366
-		}
367
-		else {
357
+		} else {
368 358
 			$get = '/';
369 359
 		}
370 360
 		return $get;
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/SSL.php 1 patch
Indentation   +134 added lines, -134 removed lines patch added patch discarded remove patch
@@ -15,138 +15,138 @@
 block discarded – undo
15 15
  * @subpackage Utilities
16 16
  */
17 17
 class Requests_SSL {
18
-	/**
19
-	 * Verify the certificate against common name and subject alternative names
20
-	 *
21
-	 * Unfortunately, PHP doesn't check the certificate against the alternative
22
-	 * names, leading things like 'https://www.github.com/' to be invalid.
23
-	 * Instead
24
-	 *
25
-	 * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
26
-	 *
27
-	 * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
28
-	 * @param string $host Host name to verify against
29
-	 * @param array $cert Certificate data from openssl_x509_parse()
30
-	 * @return bool
31
-	 */
32
-	public static function verify_certificate($host, $cert) {
33
-		// Calculate the valid wildcard match if the host is not an IP address
34
-		$parts = explode('.', $host);
35
-		if (ip2long($host) === false) {
36
-			$parts[0] = '*';
37
-		}
38
-		$wildcard = implode('.', $parts);
39
-
40
-		$has_dns_alt = false;
41
-
42
-		// Check the subjectAltName
43
-		if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
44
-			$altnames = explode(',', $cert['extensions']['subjectAltName']);
45
-			foreach ($altnames as $altname) {
46
-				$altname = trim($altname);
47
-				if (strpos($altname, 'DNS:') !== 0) {
48
-					continue;
49
-				}
50
-
51
-				$has_dns_alt = true;
52
-
53
-				// Strip the 'DNS:' prefix and trim whitespace
54
-				$altname = trim(substr($altname, 4));
55
-
56
-				// Check for a match
57
-				if (self::match_domain($host, $altname) === true) {
58
-					return true;
59
-				}
60
-			}
61
-		}
62
-
63
-		// Fall back to checking the common name if we didn't get any dNSName
64
-		// alt names, as per RFC2818
65
-		if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
66
-			// Check for a match
67
-			if (self::match_domain($host, $cert['subject']['CN']) === true) {
68
-				return true;
69
-			}
70
-		}
71
-
72
-		return false;
73
-	}
74
-
75
-	/**
76
-	 * Verify that a reference name is valid
77
-	 *
78
-	 * Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
79
-	 * - Wildcards can only occur in a name with more than 3 components
80
-	 * - Wildcards can only occur as the last character in the first
81
-	 *   component
82
-	 * - Wildcards may be preceded by additional characters
83
-	 *
84
-	 * We modify these rules to be a bit stricter and only allow the wildcard
85
-	 * character to be the full first component; that is, with the exclusion of
86
-	 * the third rule.
87
-	 *
88
-	 * @param string $reference Reference dNSName
89
-	 * @return boolean Is the name valid?
90
-	 */
91
-	public static function verify_reference_name($reference) {
92
-		$parts = explode('.', $reference);
93
-
94
-		// Check the first part of the name
95
-		$first = array_shift($parts);
96
-
97
-		if (strpos($first, '*') !== false) {
98
-			// Check that the wildcard is the full part
99
-			if ($first !== '*') {
100
-				return false;
101
-			}
102
-
103
-			// Check that we have at least 3 components (including first)
104
-			if (count($parts) < 2) {
105
-				return false;
106
-			}
107
-		}
108
-
109
-		// Check the remaining parts
110
-		foreach ($parts as $part) {
111
-			if (strpos($part, '*') !== false) {
112
-				return false;
113
-			}
114
-		}
115
-
116
-		// Nothing found, verified!
117
-		return true;
118
-	}
119
-
120
-	/**
121
-	 * Match a hostname against a dNSName reference
122
-	 *
123
-	 * @param string $host Requested host
124
-	 * @param string $reference dNSName to match against
125
-	 * @return boolean Does the domain match?
126
-	 */
127
-	public static function match_domain($host, $reference) {
128
-		// Check if the reference is blacklisted first
129
-		if (self::verify_reference_name($reference) !== true) {
130
-			return false;
131
-		}
132
-
133
-		// Check for a direct match
134
-		if ($host === $reference) {
135
-			return true;
136
-		}
137
-
138
-		// Calculate the valid wildcard match if the host is not an IP address
139
-		// Also validates that the host has 3 parts or more, as per Firefox's
140
-		// ruleset.
141
-		if (ip2long($host) === false) {
142
-			$parts = explode('.', $host);
143
-			$parts[0] = '*';
144
-			$wildcard = implode('.', $parts);
145
-			if ($wildcard === $reference) {
146
-				return true;
147
-			}
148
-		}
149
-
150
-		return false;
151
-	}
18
+    /**
19
+     * Verify the certificate against common name and subject alternative names
20
+     *
21
+     * Unfortunately, PHP doesn't check the certificate against the alternative
22
+     * names, leading things like 'https://www.github.com/' to be invalid.
23
+     * Instead
24
+     *
25
+     * @see https://tools.ietf.org/html/rfc2818#section-3.1 RFC2818, Section 3.1
26
+     *
27
+     * @throws Requests_Exception On not obtaining a match for the host (`fsockopen.ssl.no_match`)
28
+     * @param string $host Host name to verify against
29
+     * @param array $cert Certificate data from openssl_x509_parse()
30
+     * @return bool
31
+     */
32
+    public static function verify_certificate($host, $cert) {
33
+        // Calculate the valid wildcard match if the host is not an IP address
34
+        $parts = explode('.', $host);
35
+        if (ip2long($host) === false) {
36
+            $parts[0] = '*';
37
+        }
38
+        $wildcard = implode('.', $parts);
39
+
40
+        $has_dns_alt = false;
41
+
42
+        // Check the subjectAltName
43
+        if (!empty($cert['extensions']) && !empty($cert['extensions']['subjectAltName'])) {
44
+            $altnames = explode(',', $cert['extensions']['subjectAltName']);
45
+            foreach ($altnames as $altname) {
46
+                $altname = trim($altname);
47
+                if (strpos($altname, 'DNS:') !== 0) {
48
+                    continue;
49
+                }
50
+
51
+                $has_dns_alt = true;
52
+
53
+                // Strip the 'DNS:' prefix and trim whitespace
54
+                $altname = trim(substr($altname, 4));
55
+
56
+                // Check for a match
57
+                if (self::match_domain($host, $altname) === true) {
58
+                    return true;
59
+                }
60
+            }
61
+        }
62
+
63
+        // Fall back to checking the common name if we didn't get any dNSName
64
+        // alt names, as per RFC2818
65
+        if (!$has_dns_alt && !empty($cert['subject']['CN'])) {
66
+            // Check for a match
67
+            if (self::match_domain($host, $cert['subject']['CN']) === true) {
68
+                return true;
69
+            }
70
+        }
71
+
72
+        return false;
73
+    }
74
+
75
+    /**
76
+     * Verify that a reference name is valid
77
+     *
78
+     * Verifies a dNSName for HTTPS usage, (almost) as per Firefox's rules:
79
+     * - Wildcards can only occur in a name with more than 3 components
80
+     * - Wildcards can only occur as the last character in the first
81
+     *   component
82
+     * - Wildcards may be preceded by additional characters
83
+     *
84
+     * We modify these rules to be a bit stricter and only allow the wildcard
85
+     * character to be the full first component; that is, with the exclusion of
86
+     * the third rule.
87
+     *
88
+     * @param string $reference Reference dNSName
89
+     * @return boolean Is the name valid?
90
+     */
91
+    public static function verify_reference_name($reference) {
92
+        $parts = explode('.', $reference);
93
+
94
+        // Check the first part of the name
95
+        $first = array_shift($parts);
96
+
97
+        if (strpos($first, '*') !== false) {
98
+            // Check that the wildcard is the full part
99
+            if ($first !== '*') {
100
+                return false;
101
+            }
102
+
103
+            // Check that we have at least 3 components (including first)
104
+            if (count($parts) < 2) {
105
+                return false;
106
+            }
107
+        }
108
+
109
+        // Check the remaining parts
110
+        foreach ($parts as $part) {
111
+            if (strpos($part, '*') !== false) {
112
+                return false;
113
+            }
114
+        }
115
+
116
+        // Nothing found, verified!
117
+        return true;
118
+    }
119
+
120
+    /**
121
+     * Match a hostname against a dNSName reference
122
+     *
123
+     * @param string $host Requested host
124
+     * @param string $reference dNSName to match against
125
+     * @return boolean Does the domain match?
126
+     */
127
+    public static function match_domain($host, $reference) {
128
+        // Check if the reference is blacklisted first
129
+        if (self::verify_reference_name($reference) !== true) {
130
+            return false;
131
+        }
132
+
133
+        // Check for a direct match
134
+        if ($host === $reference) {
135
+            return true;
136
+        }
137
+
138
+        // Calculate the valid wildcard match if the host is not an IP address
139
+        // Also validates that the host has 3 parts or more, as per Firefox's
140
+        // ruleset.
141
+        if (ip2long($host) === false) {
142
+            $parts = explode('.', $host);
143
+            $parts[0] = '*';
144
+            $wildcard = implode('.', $parts);
145
+            if ($wildcard === $reference) {
146
+                return true;
147
+            }
148
+        }
149
+
150
+        return false;
151
+    }
152 152
 }
153 153
\ No newline at end of file
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/Hooks.php 1 patch
Indentation   +46 added lines, -46 removed lines patch added patch discarded remove patch
@@ -13,56 +13,56 @@
 block discarded – undo
13 13
  * @subpackage Utilities
14 14
  */
15 15
 class Requests_Hooks implements Requests_Hooker {
16
-	/**
17
-	 * Registered callbacks for each hook
18
-	 *
19
-	 * @var array
20
-	 */
21
-	protected $hooks = array();
16
+    /**
17
+     * Registered callbacks for each hook
18
+     *
19
+     * @var array
20
+     */
21
+    protected $hooks = array();
22 22
 
23
-	/**
24
-	 * Constructor
25
-	 */
26
-	public function __construct() {
27
-		// pass
28
-	}
23
+    /**
24
+     * Constructor
25
+     */
26
+    public function __construct() {
27
+        // pass
28
+    }
29 29
 
30
-	/**
31
-	 * Register a callback for a hook
32
-	 *
33
-	 * @param string $hook Hook name
34
-	 * @param callback $callback Function/method to call on event
35
-	 * @param int $priority Priority number. <0 is executed earlier, >0 is executed later
36
-	 */
37
-	public function register($hook, $callback, $priority = 0) {
38
-		if (!isset($this->hooks[$hook])) {
39
-			$this->hooks[$hook] = array();
40
-		}
41
-		if (!isset($this->hooks[$hook][$priority])) {
42
-			$this->hooks[$hook][$priority] = array();
43
-		}
30
+    /**
31
+     * Register a callback for a hook
32
+     *
33
+     * @param string $hook Hook name
34
+     * @param callback $callback Function/method to call on event
35
+     * @param int $priority Priority number. <0 is executed earlier, >0 is executed later
36
+     */
37
+    public function register($hook, $callback, $priority = 0) {
38
+        if (!isset($this->hooks[$hook])) {
39
+            $this->hooks[$hook] = array();
40
+        }
41
+        if (!isset($this->hooks[$hook][$priority])) {
42
+            $this->hooks[$hook][$priority] = array();
43
+        }
44 44
 
45
-		$this->hooks[$hook][$priority][] = $callback;
46
-	}
45
+        $this->hooks[$hook][$priority][] = $callback;
46
+    }
47 47
 
48
-	/**
49
-	 * Dispatch a message
50
-	 *
51
-	 * @param string $hook Hook name
52
-	 * @param array $parameters Parameters to pass to callbacks
53
-	 * @return boolean Successfulness
54
-	 */
55
-	public function dispatch($hook, $parameters = array()) {
56
-		if (empty($this->hooks[$hook])) {
57
-			return false;
58
-		}
48
+    /**
49
+     * Dispatch a message
50
+     *
51
+     * @param string $hook Hook name
52
+     * @param array $parameters Parameters to pass to callbacks
53
+     * @return boolean Successfulness
54
+     */
55
+    public function dispatch($hook, $parameters = array()) {
56
+        if (empty($this->hooks[$hook])) {
57
+            return false;
58
+        }
59 59
 
60
-		foreach ($this->hooks[$hook] as $priority => $hooked) {
61
-			foreach ($hooked as $callback) {
62
-				call_user_func_array($callback, $parameters);
63
-			}
64
-		}
60
+        foreach ($this->hooks[$hook] as $priority => $hooked) {
61
+            foreach ($hooked as $callback) {
62
+                call_user_func_array($callback, $parameters);
63
+            }
64
+        }
65 65
 
66
-		return true;
67
-	}
66
+        return true;
67
+    }
68 68
 }
69 69
\ No newline at end of file
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/Transport.php 1 patch
Indentation   +23 added lines, -23 removed lines patch added patch discarded remove patch
@@ -13,29 +13,29 @@
 block discarded – undo
13 13
  * @subpackage Transport
14 14
  */
15 15
 interface Requests_Transport {
16
-	/**
17
-	 * Perform a request
18
-	 *
19
-	 * @param string $url URL to request
20
-	 * @param array $headers Associative array of request headers
21
-	 * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
22
-	 * @param array $options Request options, see {@see Requests::response()} for documentation
23
-	 * @return string Raw HTTP result
24
-	 */
25
-	public function request($url, $headers = array(), $data = array(), $options = array());
16
+    /**
17
+     * Perform a request
18
+     *
19
+     * @param string $url URL to request
20
+     * @param array $headers Associative array of request headers
21
+     * @param string|array $data Data to send either as the POST body, or as parameters in the URL for a GET/HEAD
22
+     * @param array $options Request options, see {@see Requests::response()} for documentation
23
+     * @return string Raw HTTP result
24
+     */
25
+    public function request($url, $headers = array(), $data = array(), $options = array());
26 26
 
27
-	/**
28
-	 * Send multiple requests simultaneously
29
-	 *
30
-	 * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
31
-	 * @param array $options Global options, see {@see Requests::response()} for documentation
32
-	 * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
33
-	 */
34
-	public function request_multiple($requests, $options);
27
+    /**
28
+     * Send multiple requests simultaneously
29
+     *
30
+     * @param array $requests Request data (array of 'url', 'headers', 'data', 'options') as per {@see Requests_Transport::request}
31
+     * @param array $options Global options, see {@see Requests::response()} for documentation
32
+     * @return array Array of Requests_Response objects (may contain Requests_Exception or string responses as well)
33
+     */
34
+    public function request_multiple($requests, $options);
35 35
 
36
-	/**
37
-	 * Self-test whether the transport can be used
38
-	 * @return bool
39
-	 */
40
-	public static function test();
36
+    /**
37
+     * Self-test whether the transport can be used
38
+     * @return bool
39
+     */
40
+    public static function test();
41 41
 }
42 42
\ No newline at end of file
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/IPv6.php 3 patches
Indentation   +159 added lines, -159 removed lines patch added patch discarded remove patch
@@ -16,175 +16,175 @@
 block discarded – undo
16 16
  * @subpackage Utilities
17 17
  */
18 18
 class Requests_IPv6 {
19
-	/**
20
-	 * Uncompresses an IPv6 address
21
-	 *
22
-	 * RFC 4291 allows you to compress consecutive zero pieces in an address to
23
-	 * '::'. This method expects a valid IPv6 address and expands the '::' to
24
-	 * the required number of zero pieces.
25
-	 *
26
-	 * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
27
-	 *           ::1         ->  0:0:0:0:0:0:0:1
28
-	 *
29
-	 * @author Alexander Merz <[email protected]>
30
-	 * @author elfrink at introweb dot nl
31
-	 * @author Josh Peck <jmp at joshpeck dot org>
32
-	 * @copyright 2003-2005 The PHP Group
33
-	 * @license http://www.opensource.org/licenses/bsd-license.php
34
-	 * @param string $ip An IPv6 address
35
-	 * @return string The uncompressed IPv6 address
36
-	 */
37
-	public static function uncompress($ip) {
38
-		if (substr_count($ip, '::') !== 1) {
39
-			return $ip;
40
-		}
19
+    /**
20
+     * Uncompresses an IPv6 address
21
+     *
22
+     * RFC 4291 allows you to compress consecutive zero pieces in an address to
23
+     * '::'. This method expects a valid IPv6 address and expands the '::' to
24
+     * the required number of zero pieces.
25
+     *
26
+     * Example:  FF01::101   ->  FF01:0:0:0:0:0:0:101
27
+     *           ::1         ->  0:0:0:0:0:0:0:1
28
+     *
29
+     * @author Alexander Merz <[email protected]>
30
+     * @author elfrink at introweb dot nl
31
+     * @author Josh Peck <jmp at joshpeck dot org>
32
+     * @copyright 2003-2005 The PHP Group
33
+     * @license http://www.opensource.org/licenses/bsd-license.php
34
+     * @param string $ip An IPv6 address
35
+     * @return string The uncompressed IPv6 address
36
+     */
37
+    public static function uncompress($ip) {
38
+        if (substr_count($ip, '::') !== 1) {
39
+            return $ip;
40
+        }
41 41
 
42
-		list($ip1, $ip2) = explode('::', $ip);
43
-		$c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
44
-		$c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
42
+        list($ip1, $ip2) = explode('::', $ip);
43
+        $c1 = ($ip1 === '') ? -1 : substr_count($ip1, ':');
44
+        $c2 = ($ip2 === '') ? -1 : substr_count($ip2, ':');
45 45
 
46
-		if (strpos($ip2, '.') !== false) {
47
-			$c2++;
48
-		}
49
-		// ::
50
-		if ($c1 === -1 && $c2 === -1) {
51
-			$ip = '0:0:0:0:0:0:0:0';
52
-		}
53
-		// ::xxx
54
-		else if ($c1 === -1) {
55
-			$fill = str_repeat('0:', 7 - $c2);
56
-			$ip = str_replace('::', $fill, $ip);
57
-		}
58
-		// xxx::
59
-		else if ($c2 === -1) {
60
-			$fill = str_repeat(':0', 7 - $c1);
61
-			$ip = str_replace('::', $fill, $ip);
62
-		}
63
-		// xxx::xxx
64
-		else {
65
-			$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
66
-			$ip = str_replace('::', $fill, $ip);
67
-		}
68
-		return $ip;
69
-	}
46
+        if (strpos($ip2, '.') !== false) {
47
+            $c2++;
48
+        }
49
+        // ::
50
+        if ($c1 === -1 && $c2 === -1) {
51
+            $ip = '0:0:0:0:0:0:0:0';
52
+        }
53
+        // ::xxx
54
+        else if ($c1 === -1) {
55
+            $fill = str_repeat('0:', 7 - $c2);
56
+            $ip = str_replace('::', $fill, $ip);
57
+        }
58
+        // xxx::
59
+        else if ($c2 === -1) {
60
+            $fill = str_repeat(':0', 7 - $c1);
61
+            $ip = str_replace('::', $fill, $ip);
62
+        }
63
+        // xxx::xxx
64
+        else {
65
+            $fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
66
+            $ip = str_replace('::', $fill, $ip);
67
+        }
68
+        return $ip;
69
+    }
70 70
 
71
-	/**
72
-	 * Compresses an IPv6 address
73
-	 *
74
-	 * RFC 4291 allows you to compress consecutive zero pieces in an address to
75
-	 * '::'. This method expects a valid IPv6 address and compresses consecutive
76
-	 * zero pieces to '::'.
77
-	 *
78
-	 * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
79
-	 *           0:0:0:0:0:0:0:1        ->  ::1
80
-	 *
81
-	 * @see uncompress()
82
-	 * @param string $ip An IPv6 address
83
-	 * @return string The compressed IPv6 address
84
-	 */
85
-	public static function compress($ip) {
86
-		// Prepare the IP to be compressed
87
-		$ip = self::uncompress($ip);
88
-		$ip_parts = self::split_v6_v4($ip);
71
+    /**
72
+     * Compresses an IPv6 address
73
+     *
74
+     * RFC 4291 allows you to compress consecutive zero pieces in an address to
75
+     * '::'. This method expects a valid IPv6 address and compresses consecutive
76
+     * zero pieces to '::'.
77
+     *
78
+     * Example:  FF01:0:0:0:0:0:0:101   ->  FF01::101
79
+     *           0:0:0:0:0:0:0:1        ->  ::1
80
+     *
81
+     * @see uncompress()
82
+     * @param string $ip An IPv6 address
83
+     * @return string The compressed IPv6 address
84
+     */
85
+    public static function compress($ip) {
86
+        // Prepare the IP to be compressed
87
+        $ip = self::uncompress($ip);
88
+        $ip_parts = self::split_v6_v4($ip);
89 89
 
90
-		// Replace all leading zeros
91
-		$ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
90
+        // Replace all leading zeros
91
+        $ip_parts[0] = preg_replace('/(^|:)0+([0-9])/', '\1\2', $ip_parts[0]);
92 92
 
93
-		// Find bunches of zeros
94
-		if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) {
95
-			$max = 0;
96
-			$pos = null;
97
-			foreach ($matches[0] as $match) {
98
-				if (strlen($match[0]) > $max) {
99
-					$max = strlen($match[0]);
100
-					$pos = $match[1];
101
-				}
102
-			}
93
+        // Find bunches of zeros
94
+        if (preg_match_all('/(?:^|:)(?:0(?::|$))+/', $ip_parts[0], $matches, PREG_OFFSET_CAPTURE)) {
95
+            $max = 0;
96
+            $pos = null;
97
+            foreach ($matches[0] as $match) {
98
+                if (strlen($match[0]) > $max) {
99
+                    $max = strlen($match[0]);
100
+                    $pos = $match[1];
101
+                }
102
+            }
103 103
 
104
-			$ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
105
-		}
104
+            $ip_parts[0] = substr_replace($ip_parts[0], '::', $pos, $max);
105
+        }
106 106
 
107
-		if ($ip_parts[1] !== '') {
108
-			return implode(':', $ip_parts);
109
-		}
110
-		else {
111
-			return $ip_parts[0];
112
-		}
113
-	}
107
+        if ($ip_parts[1] !== '') {
108
+            return implode(':', $ip_parts);
109
+        }
110
+        else {
111
+            return $ip_parts[0];
112
+        }
113
+    }
114 114
 
115
-	/**
116
-	 * Splits an IPv6 address into the IPv6 and IPv4 representation parts
117
-	 *
118
-	 * RFC 4291 allows you to represent the last two parts of an IPv6 address
119
-	 * using the standard IPv4 representation
120
-	 *
121
-	 * Example:  0:0:0:0:0:0:13.1.68.3
122
-	 *           0:0:0:0:0:FFFF:129.144.52.38
123
-	 *
124
-	 * @param string $ip An IPv6 address
125
-	 * @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part
126
-	 */
127
-	protected static function split_v6_v4($ip) {
128
-		if (strpos($ip, '.') !== false) {
129
-			$pos = strrpos($ip, ':');
130
-			$ipv6_part = substr($ip, 0, $pos);
131
-			$ipv4_part = substr($ip, $pos + 1);
132
-			return array($ipv6_part, $ipv4_part);
133
-		}
134
-		else {
135
-			return array($ip, '');
136
-		}
137
-	}
115
+    /**
116
+     * Splits an IPv6 address into the IPv6 and IPv4 representation parts
117
+     *
118
+     * RFC 4291 allows you to represent the last two parts of an IPv6 address
119
+     * using the standard IPv4 representation
120
+     *
121
+     * Example:  0:0:0:0:0:0:13.1.68.3
122
+     *           0:0:0:0:0:FFFF:129.144.52.38
123
+     *
124
+     * @param string $ip An IPv6 address
125
+     * @return string[] [0] contains the IPv6 represented part, and [1] the IPv4 represented part
126
+     */
127
+    protected static function split_v6_v4($ip) {
128
+        if (strpos($ip, '.') !== false) {
129
+            $pos = strrpos($ip, ':');
130
+            $ipv6_part = substr($ip, 0, $pos);
131
+            $ipv4_part = substr($ip, $pos + 1);
132
+            return array($ipv6_part, $ipv4_part);
133
+        }
134
+        else {
135
+            return array($ip, '');
136
+        }
137
+    }
138 138
 
139
-	/**
140
-	 * Checks an IPv6 address
141
-	 *
142
-	 * Checks if the given IP is a valid IPv6 address
143
-	 *
144
-	 * @param string $ip An IPv6 address
145
-	 * @return bool true if $ip is a valid IPv6 address
146
-	 */
147
-	public static function check_ipv6($ip) {
148
-		$ip = self::uncompress($ip);
149
-		list($ipv6, $ipv4) = self::split_v6_v4($ip);
150
-		$ipv6 = explode(':', $ipv6);
151
-		$ipv4 = explode('.', $ipv4);
152
-		if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
153
-			foreach ($ipv6 as $ipv6_part) {
154
-				// The section can't be empty
155
-				if ($ipv6_part === '') {
156
-					return false;
157
-				}
139
+    /**
140
+     * Checks an IPv6 address
141
+     *
142
+     * Checks if the given IP is a valid IPv6 address
143
+     *
144
+     * @param string $ip An IPv6 address
145
+     * @return bool true if $ip is a valid IPv6 address
146
+     */
147
+    public static function check_ipv6($ip) {
148
+        $ip = self::uncompress($ip);
149
+        list($ipv6, $ipv4) = self::split_v6_v4($ip);
150
+        $ipv6 = explode(':', $ipv6);
151
+        $ipv4 = explode('.', $ipv4);
152
+        if (count($ipv6) === 8 && count($ipv4) === 1 || count($ipv6) === 6 && count($ipv4) === 4) {
153
+            foreach ($ipv6 as $ipv6_part) {
154
+                // The section can't be empty
155
+                if ($ipv6_part === '') {
156
+                    return false;
157
+                }
158 158
 
159
-				// Nor can it be over four characters
160
-				if (strlen($ipv6_part) > 4) {
161
-					return false;
162
-				}
159
+                // Nor can it be over four characters
160
+                if (strlen($ipv6_part) > 4) {
161
+                    return false;
162
+                }
163 163
 
164
-				// Remove leading zeros (this is safe because of the above)
165
-				$ipv6_part = ltrim($ipv6_part, '0');
166
-				if ($ipv6_part === '') {
167
-					$ipv6_part = '0';
168
-				}
164
+                // Remove leading zeros (this is safe because of the above)
165
+                $ipv6_part = ltrim($ipv6_part, '0');
166
+                if ($ipv6_part === '') {
167
+                    $ipv6_part = '0';
168
+                }
169 169
 
170
-				// Check the value is valid
171
-				$value = hexdec($ipv6_part);
172
-				if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) {
173
-					return false;
174
-				}
175
-			}
176
-			if (count($ipv4) === 4) {
177
-				foreach ($ipv4 as $ipv4_part) {
178
-					$value = (int) $ipv4_part;
179
-					if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) {
180
-						return false;
181
-					}
182
-				}
183
-			}
184
-			return true;
185
-		}
186
-		else {
187
-			return false;
188
-		}
189
-	}
170
+                // Check the value is valid
171
+                $value = hexdec($ipv6_part);
172
+                if (dechex($value) !== strtolower($ipv6_part) || $value < 0 || $value > 0xFFFF) {
173
+                    return false;
174
+                }
175
+            }
176
+            if (count($ipv4) === 4) {
177
+                foreach ($ipv4 as $ipv4_part) {
178
+                    $value = (int) $ipv4_part;
179
+                    if ((string) $value !== $ipv4_part || $value < 0 || $value > 0xFF) {
180
+                        return false;
181
+                    }
182
+                }
183
+            }
184
+            return true;
185
+        }
186
+        else {
187
+            return false;
188
+        }
189
+    }
190 190
 }
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -62,7 +62,7 @@
 block discarded – undo
62 62
 		}
63 63
 		// xxx::xxx
64 64
 		else {
65
-			$fill = ':' . str_repeat('0:', 6 - $c2 - $c1);
65
+			$fill = ':'.str_repeat('0:', 6 - $c2 - $c1);
66 66
 			$ip = str_replace('::', $fill, $ip);
67 67
 		}
68 68
 		return $ip;
Please login to merge, or discard this patch.
Braces   +3 added lines, -6 removed lines patch added patch discarded remove patch
@@ -106,8 +106,7 @@  discard block
 block discarded – undo
106 106
 
107 107
 		if ($ip_parts[1] !== '') {
108 108
 			return implode(':', $ip_parts);
109
-		}
110
-		else {
109
+		} else {
111 110
 			return $ip_parts[0];
112 111
 		}
113 112
 	}
@@ -130,8 +129,7 @@  discard block
 block discarded – undo
130 129
 			$ipv6_part = substr($ip, 0, $pos);
131 130
 			$ipv4_part = substr($ip, $pos + 1);
132 131
 			return array($ipv6_part, $ipv4_part);
133
-		}
134
-		else {
132
+		} else {
135 133
 			return array($ip, '');
136 134
 		}
137 135
 	}
@@ -182,8 +180,7 @@  discard block
 block discarded – undo
182 180
 				}
183 181
 			}
184 182
 			return true;
185
-		}
186
-		else {
183
+		} else {
187 184
 			return false;
188 185
 		}
189 186
 	}
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/Proxy.php 2 patches
Indentation   +11 added lines, -11 removed lines patch added patch discarded remove patch
@@ -21,15 +21,15 @@
 block discarded – undo
21 21
  * @since 1.6
22 22
  */
23 23
 interface Requests_Proxy {
24
-	/**
25
-	 * Register hooks as needed
26
-	 *
27
-	 * This method is called in {@see Requests::request} when the user has set
28
-	 * an instance as the 'auth' option. Use this callback to register all the
29
-	 * hooks you'll need.
30
-	 *
31
-	 * @see Requests_Hooks::register
32
-	 * @param Requests_Hooks $hooks Hook system
33
-	 */
34
-	public function register(Requests_Hooks &$hooks);
24
+    /**
25
+     * Register hooks as needed
26
+     *
27
+     * This method is called in {@see Requests::request} when the user has set
28
+     * an instance as the 'auth' option. Use this callback to register all the
29
+     * hooks you'll need.
30
+     *
31
+     * @see Requests_Hooks::register
32
+     * @param Requests_Hooks $hooks Hook system
33
+     */
34
+    public function register(Requests_Hooks &$hooks);
35 35
 }
36 36
\ No newline at end of file
Please login to merge, or discard this patch.
Spacing   +1 added lines, -1 removed lines patch added patch discarded remove patch
@@ -31,5 +31,5 @@
 block discarded – undo
31 31
 	 * @see Requests_Hooks::register
32 32
 	 * @param Requests_Hooks $hooks Hook system
33 33
 	 */
34
-	public function register(Requests_Hooks &$hooks);
34
+	public function register(Requests_Hooks & $hooks);
35 35
 }
36 36
\ No newline at end of file
Please login to merge, or discard this patch.
plugin/buycourses/src/Requests/Exception.php 1 patch
Indentation   +43 added lines, -43 removed lines patch added patch discarded remove patch
@@ -11,52 +11,52 @@
 block discarded – undo
11 11
  * @package Requests
12 12
  */
13 13
 class Requests_Exception extends Exception {
14
-	/**
15
-	 * Type of exception
16
-	 *
17
-	 * @var string
18
-	 */
19
-	protected $type;
14
+    /**
15
+     * Type of exception
16
+     *
17
+     * @var string
18
+     */
19
+    protected $type;
20 20
 
21
-	/**
22
-	 * Data associated with the exception
23
-	 *
24
-	 * @var mixed
25
-	 */
26
-	protected $data;
21
+    /**
22
+     * Data associated with the exception
23
+     *
24
+     * @var mixed
25
+     */
26
+    protected $data;
27 27
 
28
-	/**
29
-	 * Create a new exception
30
-	 *
31
-	 * @param string $message Exception message
32
-	 * @param string $type Exception type
33
-	 * @param mixed $data Associated data
34
-	 * @param integer $code Exception numerical code, if applicable
35
-	 */
36
-	public function __construct($message, $type, $data = null, $code = 0) {
37
-		parent::__construct($message, $code);
28
+    /**
29
+     * Create a new exception
30
+     *
31
+     * @param string $message Exception message
32
+     * @param string $type Exception type
33
+     * @param mixed $data Associated data
34
+     * @param integer $code Exception numerical code, if applicable
35
+     */
36
+    public function __construct($message, $type, $data = null, $code = 0) {
37
+        parent::__construct($message, $code);
38 38
 
39
-		$this->type = $type;
40
-		$this->data = $data;
41
-	}
39
+        $this->type = $type;
40
+        $this->data = $data;
41
+    }
42 42
 
43
-	/**
44
-	 * Like {@see getCode()}, but a string code.
45
-	 *
46
-	 * @codeCoverageIgnore
47
-	 * @return string
48
-	 */
49
-	public function getType() {
50
-		return $this->type;
51
-	}
43
+    /**
44
+     * Like {@see getCode()}, but a string code.
45
+     *
46
+     * @codeCoverageIgnore
47
+     * @return string
48
+     */
49
+    public function getType() {
50
+        return $this->type;
51
+    }
52 52
 
53
-	/**
54
-	 * Gives any relevant data
55
-	 *
56
-	 * @codeCoverageIgnore
57
-	 * @return mixed
58
-	 */
59
-	public function getData() {
60
-		return $this->data;
61
-	}
53
+    /**
54
+     * Gives any relevant data
55
+     *
56
+     * @codeCoverageIgnore
57
+     * @return mixed
58
+     */
59
+    public function getData() {
60
+        return $this->data;
61
+    }
62 62
 }
63 63
\ No newline at end of file
Please login to merge, or discard this patch.