1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
require_once KS3_API_PATH.DIRECTORY_SEPARATOR."encryption".DIRECTORY_SEPARATOR."EncryptionCallBack.php"; |
4
|
|
|
/** |
5
|
|
|
* Handles all HTTP requests using cURL and manages the responses. |
6
|
|
|
* |
7
|
|
|
* @version 2011.06.07 |
8
|
|
|
* @copyright 2006-2011 Ryan Parman |
9
|
|
|
* @copyright 2006-2010 Foleeo Inc. |
10
|
|
|
* @copyright 2010-2011 Amazon.com, Inc. or its affiliates. |
11
|
|
|
* @copyright 2008-2011 Contributors |
12
|
|
|
* @license http://opensource.org/licenses/bsd-license.php Simplified BSD License |
13
|
|
|
*/ |
14
|
|
|
class RequestCore |
15
|
|
|
{ |
16
|
|
|
/** |
17
|
|
|
* The URL being requested. |
18
|
|
|
*/ |
19
|
|
|
public $request_url; |
20
|
|
|
|
21
|
|
|
/** |
22
|
|
|
* The headers being sent in the request. |
23
|
|
|
*/ |
24
|
|
|
public $request_headers; |
25
|
|
|
|
26
|
|
|
/** |
27
|
|
|
* The body being sent in the request. |
28
|
|
|
*/ |
29
|
|
|
public $request_body; |
30
|
|
|
|
31
|
|
|
/** |
32
|
|
|
* The response returned by the request. |
33
|
|
|
*/ |
34
|
|
|
public $response; |
35
|
|
|
|
36
|
|
|
/** |
37
|
|
|
* The headers returned by the request. |
38
|
|
|
*/ |
39
|
|
|
public $response_headers; |
40
|
|
|
|
41
|
|
|
/** |
42
|
|
|
* The body returned by the request. |
43
|
|
|
*/ |
44
|
|
|
public $response_body; |
45
|
|
|
|
46
|
|
|
/** |
47
|
|
|
* The HTTP status code returned by the request. |
48
|
|
|
*/ |
49
|
|
|
public $response_code; |
50
|
|
|
|
51
|
|
|
/** |
52
|
|
|
* Additional response data. |
53
|
|
|
*/ |
54
|
|
|
public $response_info; |
55
|
|
|
|
56
|
|
|
/** |
57
|
|
|
* The handle for the cURL object. |
58
|
|
|
*/ |
59
|
|
|
public $curl_handle; |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* The method by which the request is being made. |
63
|
|
|
*/ |
64
|
|
|
public $method; |
65
|
|
|
|
66
|
|
|
/** |
67
|
|
|
* Stores the proxy settings to use for the request. |
68
|
|
|
*/ |
69
|
|
|
public $proxy = null; |
70
|
|
|
|
71
|
|
|
/** |
72
|
|
|
* The username to use for the request. |
73
|
|
|
*/ |
74
|
|
|
public $username = null; |
75
|
|
|
|
76
|
|
|
/** |
77
|
|
|
* The password to use for the request. |
78
|
|
|
*/ |
79
|
|
|
public $password = null; |
80
|
|
|
|
81
|
|
|
/** |
82
|
|
|
* Custom CURLOPT settings. |
83
|
|
|
*/ |
84
|
|
|
public $curlopts = null; |
85
|
|
|
|
86
|
|
|
/** |
87
|
|
|
* The state of debug mode. |
88
|
|
|
*/ |
89
|
|
|
public $debug_mode = false; |
90
|
|
|
|
91
|
|
|
/** |
92
|
|
|
* The default class to use for HTTP Requests (defaults to <RequestCore>). |
93
|
|
|
*/ |
94
|
|
|
public $request_class = 'RequestCore'; |
95
|
|
|
|
96
|
|
|
/** |
97
|
|
|
* The default class to use for HTTP Responses (defaults to <ResponseCore>). |
98
|
|
|
*/ |
99
|
|
|
public $response_class = 'ResponseCore'; |
100
|
|
|
|
101
|
|
|
/** |
102
|
|
|
* Default useragent string to use. |
103
|
|
|
*/ |
104
|
|
|
public $useragent = 'RequestCore/1.4.3'; |
105
|
|
|
|
106
|
|
|
/** |
107
|
|
|
* File to read from while streaming up. |
108
|
|
|
*/ |
109
|
|
|
public $read_file = null; |
110
|
|
|
|
111
|
|
|
/** |
112
|
|
|
* The resource to read from while streaming up. |
113
|
|
|
*/ |
114
|
|
|
public $read_stream = null; |
115
|
|
|
|
116
|
|
|
/** |
117
|
|
|
* The size of the stream to read from. |
118
|
|
|
*/ |
119
|
|
|
public $read_stream_size = null; |
120
|
|
|
|
121
|
|
|
/** |
122
|
|
|
* The length already read from the stream. |
123
|
|
|
*/ |
124
|
|
|
public $read_stream_read = 0; |
125
|
|
|
|
126
|
|
|
/** |
127
|
|
|
* File to write to while streaming down. |
128
|
|
|
*/ |
129
|
|
|
public $write_file = null; |
130
|
|
|
|
131
|
|
|
/** |
132
|
|
|
* The resource to write to while streaming down. |
133
|
|
|
*/ |
134
|
|
|
public $write_stream = null; |
135
|
|
|
|
136
|
|
|
/** |
137
|
|
|
* Stores the intended starting seek position. |
138
|
|
|
*/ |
139
|
|
|
public $seek_position = null; |
140
|
|
|
|
141
|
|
|
/** |
142
|
|
|
* The location of the cacert.pem file to use. |
143
|
|
|
*/ |
144
|
|
|
public $cacert_location = false; |
145
|
|
|
|
146
|
|
|
/** |
147
|
|
|
* The state of SSL certificate verification. |
148
|
|
|
*/ |
149
|
|
|
public $ssl_verification = true; |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* The user-defined callback function to call when a stream is read from. |
153
|
|
|
*/ |
154
|
|
|
public $registered_streaming_read_callback = null; |
155
|
|
|
|
156
|
|
|
/** |
157
|
|
|
* The user-defined callback function to call when a stream is written to. |
158
|
|
|
*/ |
159
|
|
|
public $registered_streaming_write_callback = null; |
160
|
|
|
|
161
|
|
|
/*%******************************************************************************************%*/ |
162
|
|
|
// CONSTANTS |
163
|
|
|
|
164
|
|
|
/** |
165
|
|
|
* GET HTTP Method |
166
|
|
|
*/ |
167
|
|
|
const HTTP_GET = 'GET'; |
168
|
|
|
|
169
|
|
|
/** |
170
|
|
|
* POST HTTP Method |
171
|
|
|
*/ |
172
|
|
|
const HTTP_POST = 'POST'; |
173
|
|
|
|
174
|
|
|
/** |
175
|
|
|
* PUT HTTP Method |
176
|
|
|
*/ |
177
|
|
|
const HTTP_PUT = 'PUT'; |
178
|
|
|
|
179
|
|
|
/** |
180
|
|
|
* DELETE HTTP Method |
181
|
|
|
*/ |
182
|
|
|
const HTTP_DELETE = 'DELETE'; |
183
|
|
|
|
184
|
|
|
/** |
185
|
|
|
* HEAD HTTP Method |
186
|
|
|
*/ |
187
|
|
|
const HTTP_HEAD = 'HEAD'; |
188
|
|
|
|
189
|
|
|
|
190
|
|
|
/*%******************************************************************************************%*/ |
191
|
|
|
// CONSTRUCTOR/DESTRUCTOR |
192
|
|
|
|
193
|
|
|
/** |
194
|
|
|
* Constructs a new instance of this class. |
195
|
|
|
* |
196
|
|
|
* @param string $url (Optional) The URL to request or service endpoint to query. |
197
|
|
|
* @param string $proxy (Optional) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` |
198
|
|
|
* @param array $helpers (Optional) An associative array of classnames to use for request, and response functionality. Gets passed in automatically by the calling class. |
199
|
|
|
* @return $this A reference to the current instance. |
200
|
|
|
*/ |
201
|
|
|
public function __construct($url = null, $proxy = null, $helpers = null) |
202
|
|
|
{ |
203
|
|
|
// Set some default values. |
204
|
|
|
$this->request_url = $url; |
205
|
|
|
$this->method = self::HTTP_GET; |
206
|
|
|
$this->request_headers = array(); |
207
|
|
|
$this->request_body = ''; |
208
|
|
|
|
209
|
|
|
// Set a new Request class if one was set. |
210
|
|
|
if (isset($helpers['request']) && !empty($helpers['request'])) |
211
|
|
|
{ |
212
|
|
|
$this->request_class = $helpers['request']; |
213
|
|
|
} |
214
|
|
|
|
215
|
|
|
// Set a new Request class if one was set. |
216
|
|
|
if (isset($helpers['response']) && !empty($helpers['response'])) |
217
|
|
|
{ |
218
|
|
|
$this->response_class = $helpers['response']; |
219
|
|
|
} |
220
|
|
|
|
221
|
|
|
if ($proxy) |
222
|
|
|
{ |
223
|
|
|
$this->set_proxy($proxy); |
224
|
|
|
} |
225
|
|
|
|
226
|
|
|
return $this; |
227
|
|
|
} |
228
|
|
|
|
229
|
|
|
/** |
230
|
|
|
* Destructs the instance. Closes opened file handles. |
231
|
|
|
* |
232
|
|
|
* @return $this A reference to the current instance. |
233
|
|
|
*/ |
234
|
|
|
public function __destruct() |
235
|
|
|
{ |
236
|
|
|
if (isset($this->read_file) && isset($this->read_stream)) |
237
|
|
|
{ |
238
|
|
|
fclose($this->read_stream); |
239
|
|
|
} |
240
|
|
|
|
241
|
|
|
if (isset($this->write_file) && isset($this->write_stream)) |
242
|
|
|
{ |
243
|
|
|
fclose($this->write_stream); |
244
|
|
|
} |
245
|
|
|
|
246
|
|
|
return $this; |
247
|
|
|
} |
248
|
|
|
|
249
|
|
|
|
250
|
|
|
/*%******************************************************************************************%*/ |
251
|
|
|
// REQUEST METHODS |
252
|
|
|
|
253
|
|
|
/** |
254
|
|
|
* Sets the credentials to use for authentication. |
255
|
|
|
* |
256
|
|
|
* @param string $user (Required) The username to authenticate with. |
257
|
|
|
* @param string $pass (Required) The password to authenticate with. |
258
|
|
|
* @return $this A reference to the current instance. |
259
|
|
|
*/ |
260
|
|
|
public function set_credentials($user, $pass) |
261
|
|
|
{ |
262
|
|
|
$this->username = $user; |
263
|
|
|
$this->password = $pass; |
264
|
|
|
return $this; |
265
|
|
|
} |
266
|
|
|
|
267
|
|
|
/** |
268
|
|
|
* Adds a custom HTTP header to the cURL request. |
269
|
|
|
* |
270
|
|
|
* @param string $key (Required) The custom HTTP header to set. |
271
|
|
|
* @param mixed $value (Required) The value to assign to the custom HTTP header. |
272
|
|
|
* @return $this A reference to the current instance. |
273
|
|
|
*/ |
274
|
|
|
public function add_header($key, $value) |
275
|
|
|
{ |
276
|
|
|
$this->request_headers[$key] = $value; |
277
|
|
|
return $this; |
278
|
|
|
} |
279
|
|
|
|
280
|
|
|
/** |
281
|
|
|
* Removes an HTTP header from the cURL request. |
282
|
|
|
* |
283
|
|
|
* @param string $key (Required) The custom HTTP header to set. |
284
|
|
|
* @return $this A reference to the current instance. |
285
|
|
|
*/ |
286
|
|
|
public function remove_header($key) |
287
|
|
|
{ |
288
|
|
|
if (isset($this->request_headers[$key])) |
289
|
|
|
{ |
290
|
|
|
unset($this->request_headers[$key]); |
291
|
|
|
} |
292
|
|
|
return $this; |
293
|
|
|
} |
294
|
|
|
|
295
|
|
|
/** |
296
|
|
|
* Set the method type for the request. |
297
|
|
|
* |
298
|
|
|
* @param string $method (Required) One of the following constants: <HTTP_GET>, <HTTP_POST>, <HTTP_PUT>, <HTTP_HEAD>, <HTTP_DELETE>. |
299
|
|
|
* @return $this A reference to the current instance. |
300
|
|
|
*/ |
301
|
|
|
public function set_method($method) |
302
|
|
|
{ |
303
|
|
|
$this->method = strtoupper($method); |
304
|
|
|
return $this; |
305
|
|
|
} |
306
|
|
|
|
307
|
|
|
/** |
308
|
|
|
* Sets a custom useragent string for the class. |
309
|
|
|
* |
310
|
|
|
* @param string $ua (Required) The useragent string to use. |
311
|
|
|
* @return $this A reference to the current instance. |
312
|
|
|
*/ |
313
|
|
|
public function set_useragent($ua) |
314
|
|
|
{ |
315
|
|
|
$this->useragent = $ua; |
316
|
|
|
return $this; |
317
|
|
|
} |
318
|
|
|
|
319
|
|
|
/** |
320
|
|
|
* Set the body to send in the request. |
321
|
|
|
* |
322
|
|
|
* @param string $body (Required) The textual content to send along in the body of the request. |
323
|
|
|
* @return $this A reference to the current instance. |
324
|
|
|
*/ |
325
|
|
|
public function set_body($body) |
326
|
|
|
{ |
327
|
|
|
$this->request_body = $body; |
328
|
|
|
return $this; |
329
|
|
|
} |
330
|
|
|
|
331
|
|
|
/** |
332
|
|
|
* Set the URL to make the request to. |
333
|
|
|
* |
334
|
|
|
* @param string $url (Required) The URL to make the request to. |
335
|
|
|
* @return $this A reference to the current instance. |
336
|
|
|
*/ |
337
|
|
|
public function set_request_url($url) |
338
|
|
|
{ |
339
|
|
|
$this->request_url = $url; |
340
|
|
|
return $this; |
341
|
|
|
} |
342
|
|
|
|
343
|
|
|
/** |
344
|
|
|
* Set additional CURLOPT settings. These will merge with the default settings, and override if |
345
|
|
|
* there is a duplicate. |
346
|
|
|
* |
347
|
|
|
* @param array $curlopts (Optional) A set of key-value pairs that set `CURLOPT` options. These will merge with the existing CURLOPTs, and ones passed here will override the defaults. Keys should be the `CURLOPT_*` constants, not strings. |
348
|
|
|
* @return $this A reference to the current instance. |
349
|
|
|
*/ |
350
|
|
|
public function set_curlopts($curlopts) |
351
|
|
|
{ |
352
|
|
|
$this->curlopts = $curlopts; |
353
|
|
|
return $this; |
354
|
|
|
} |
355
|
|
|
|
356
|
|
|
/** |
357
|
|
|
* Sets the length in bytes to read from the stream while streaming up. |
358
|
|
|
* |
359
|
|
|
* @param integer $size (Required) The length in bytes to read from the stream. |
360
|
|
|
* @return $this A reference to the current instance. |
361
|
|
|
*/ |
362
|
|
|
public function set_read_stream_size($size) |
363
|
|
|
{ |
364
|
|
|
$this->read_stream_size = $size; |
365
|
|
|
|
366
|
|
|
return $this; |
367
|
|
|
} |
368
|
|
|
|
369
|
|
|
/** |
370
|
|
|
* Sets the resource to read from while streaming up. Reads the stream from its current position until |
371
|
|
|
* EOF or `$size` bytes have been read. If `$size` is not given it will be determined by <php:fstat()> and |
372
|
|
|
* <php:ftell()>. |
373
|
|
|
* |
374
|
|
|
* @param resource $resource (Required) The readable resource to read from. |
375
|
|
|
* @param integer $size (Optional) The size of the stream to read. |
376
|
|
|
* @return $this A reference to the current instance. |
377
|
|
|
*/ |
378
|
|
|
public function set_read_stream($resource, $size = null) |
379
|
|
|
{ |
380
|
|
|
if (!isset($size) || $size < 0) |
381
|
|
|
{ |
382
|
|
|
$stats = fstat($resource); |
383
|
|
|
|
384
|
|
|
if ($stats && $stats['size'] >= 0) |
|
|
|
|
385
|
|
|
{ |
386
|
|
|
$position = ftell($resource); |
387
|
|
|
|
388
|
|
|
if ($position !== false && $position >= 0) |
389
|
|
|
{ |
390
|
|
|
$size = $stats['size'] - $position; |
391
|
|
|
} |
392
|
|
|
} |
393
|
|
|
} |
394
|
|
|
|
395
|
|
|
$this->read_stream = $resource; |
396
|
|
|
|
397
|
|
|
return $this->set_read_stream_size($size); |
398
|
|
|
} |
399
|
|
|
|
400
|
|
|
/** |
401
|
|
|
* Sets the file to read from while streaming up. |
402
|
|
|
* |
403
|
|
|
* @param string $location (Required) The readable location to read from. |
404
|
|
|
* @return $this A reference to the current instance. |
405
|
|
|
*/ |
406
|
|
|
public function set_read_file($location) |
407
|
|
|
{ |
408
|
|
|
$this->read_file = $location; |
409
|
|
|
$read_file_handle = fopen($location, 'r'); |
410
|
|
|
|
411
|
|
|
return $this->set_read_stream($read_file_handle); |
412
|
|
|
} |
413
|
|
|
|
414
|
|
|
/** |
415
|
|
|
* Sets the resource to write to while streaming down. |
416
|
|
|
* |
417
|
|
|
* @param resource $resource (Required) The writeable resource to write to. |
418
|
|
|
* @return $this A reference to the current instance. |
419
|
|
|
*/ |
420
|
|
|
public function set_write_stream($resource) |
421
|
|
|
{ |
422
|
|
|
$this->write_stream = $resource; |
423
|
|
|
|
424
|
|
|
return $this; |
425
|
|
|
} |
426
|
|
|
|
427
|
|
|
/** |
428
|
|
|
* Sets the file to write to while streaming down. |
429
|
|
|
* |
430
|
|
|
* @param string $location (Required) The writeable location to write to. |
431
|
|
|
* @return $this A reference to the current instance. |
432
|
|
|
*/ |
433
|
|
|
public function set_write_file($location) |
434
|
|
|
{ |
435
|
|
|
$this->write_file = $location; |
436
|
|
|
$write_file_handle = fopen($location, 'w'); |
437
|
|
|
|
438
|
|
|
return $this->set_write_stream($write_file_handle); |
439
|
|
|
} |
440
|
|
|
|
441
|
|
|
/** |
442
|
|
|
* Set the proxy to use for making requests. |
443
|
|
|
* |
444
|
|
|
* @param string $proxy (Required) The faux-url to use for proxy settings. Takes the following format: `proxy://user:pass@hostname:port` |
445
|
|
|
* @return $this A reference to the current instance. |
446
|
|
|
*/ |
447
|
|
|
public function set_proxy($proxy) |
448
|
|
|
{ |
449
|
|
|
$proxy = parse_url($proxy); |
450
|
|
|
$proxy['user'] = isset($proxy['user']) ? $proxy['user'] : null; |
451
|
|
|
$proxy['pass'] = isset($proxy['pass']) ? $proxy['pass'] : null; |
452
|
|
|
$proxy['port'] = isset($proxy['port']) ? $proxy['port'] : null; |
453
|
|
|
$this->proxy = $proxy; |
454
|
|
|
return $this; |
455
|
|
|
} |
456
|
|
|
|
457
|
|
|
/** |
458
|
|
|
* Set the intended starting seek position. |
459
|
|
|
* |
460
|
|
|
* @param integer $position (Required) The byte-position of the stream to begin reading from. |
461
|
|
|
* @return $this A reference to the current instance. |
462
|
|
|
*/ |
463
|
|
|
public function set_seek_position($position) |
464
|
|
|
{ |
465
|
|
|
$this->seek_position = isset($position) ? (integer) $position : null; |
466
|
|
|
|
467
|
|
|
return $this; |
468
|
|
|
} |
469
|
|
|
|
470
|
|
|
/** |
471
|
|
|
* Register a callback function to execute whenever a data stream is read from using |
472
|
|
|
* <CFRequest::streaming_read_callback()>. |
473
|
|
|
* |
474
|
|
|
* The user-defined callback function should accept three arguments: |
475
|
|
|
* |
476
|
|
|
* <ul> |
477
|
|
|
* <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li> |
478
|
|
|
* <li><code>$file_handle</code> - <code>resource</code> - Required - The file handle resource that represents the file on the local file system.</li> |
479
|
|
|
* <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li> |
480
|
|
|
* </ul> |
481
|
|
|
* |
482
|
|
|
* @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul> |
|
|
|
|
483
|
|
|
* <li>The name of a global function to execute, passed as a string.</li> |
484
|
|
|
* <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li> |
485
|
|
|
* <li>An anonymous function (PHP 5.3+).</li></ul> |
486
|
|
|
* @return $this A reference to the current instance. |
487
|
|
|
*/ |
488
|
|
|
public function register_streaming_read_callback($callback) |
489
|
|
|
{ |
490
|
|
|
$this->registered_streaming_read_callback = $callback; |
491
|
|
|
|
492
|
|
|
return $this; |
493
|
|
|
} |
494
|
|
|
|
495
|
|
|
/** |
496
|
|
|
* Register a callback function to execute whenever a data stream is written to using |
497
|
|
|
* <CFRequest::streaming_write_callback()>. |
498
|
|
|
* |
499
|
|
|
* The user-defined callback function should accept two arguments: |
500
|
|
|
* |
501
|
|
|
* <ul> |
502
|
|
|
* <li><code>$curl_handle</code> - <code>resource</code> - Required - The cURL handle resource that represents the in-progress transfer.</li> |
503
|
|
|
* <li><code>$length</code> - <code>integer</code> - Required - The length in kilobytes of the data chunk that was transferred.</li> |
504
|
|
|
* </ul> |
505
|
|
|
* |
506
|
|
|
* @param string|array|function $callback (Required) The callback function is called by <php:call_user_func()>, so you can pass the following values: <ul> |
507
|
|
|
* <li>The name of a global function to execute, passed as a string.</li> |
508
|
|
|
* <li>A method to execute, passed as <code>array('ClassName', 'MethodName')</code>.</li> |
509
|
|
|
* <li>An anonymous function (PHP 5.3+).</li></ul> |
510
|
|
|
* @return $this A reference to the current instance. |
511
|
|
|
*/ |
512
|
|
|
public function register_streaming_write_callback($callback) |
513
|
|
|
{ |
514
|
|
|
$this->registered_streaming_write_callback = $callback; |
515
|
|
|
|
516
|
|
|
return $this; |
517
|
|
|
} |
518
|
|
|
|
519
|
|
|
|
520
|
|
|
/*%******************************************************************************************%*/ |
521
|
|
|
// PREPARE, SEND, AND PROCESS REQUEST |
522
|
|
|
|
523
|
|
|
/** |
524
|
|
|
* A callback function that is invoked by cURL for streaming up. |
525
|
|
|
* |
526
|
|
|
* @param resource $curl_handle (Required) The cURL handle for the request. |
527
|
|
|
* @param resource $file_handle (Required) The open file handle resource. |
528
|
|
|
* @param integer $length (Required) The maximum number of bytes to read. |
529
|
|
|
* @return binary Binary data from a stream. |
|
|
|
|
530
|
|
|
*/ |
531
|
|
|
public function streaming_read_callback($curl_handle, $file_handle, $length) |
532
|
|
|
{ |
533
|
|
|
// Execute callback function |
534
|
|
|
if ($this->registered_streaming_read_callback) |
535
|
|
|
{ |
536
|
|
|
return $this->registered_streaming_read_callback->streaming_read_callback($curl_handle, $file_handle, $length,$this->read_stream,$this->seek_position); |
537
|
|
|
} |
538
|
|
|
// Once we've sent as much as we're supposed to send... |
539
|
|
|
if ($this->read_stream_read >= $this->read_stream_size) |
540
|
|
|
{ |
541
|
|
|
// Send EOF |
542
|
|
|
return ''; |
|
|
|
|
543
|
|
|
} |
544
|
|
|
|
545
|
|
|
// If we're at the beginning of an upload and need to seek... |
546
|
|
|
if ($this->read_stream_read == 0 && isset($this->seek_position) && $this->seek_position !== ftell($this->read_stream)) |
547
|
|
|
{ |
548
|
|
|
if (fseek($this->read_stream, $this->seek_position) !== 0) |
549
|
|
|
{ |
550
|
|
|
throw new RequestCore_Exception('The stream does not support seeking and is either not at the requested position or the position is unknown.'); |
551
|
|
|
} |
552
|
|
|
} |
553
|
|
|
|
554
|
|
|
$read = fread($this->read_stream, min($this->read_stream_size - $this->read_stream_read, $length)); // Remaining upload data or cURL's requested chunk size |
555
|
|
|
$this->read_stream_read += strlen($read); |
556
|
|
|
|
557
|
|
|
$out = $read === false ? '' : $read; |
558
|
|
|
|
559
|
|
|
return $out; |
|
|
|
|
560
|
|
|
} |
561
|
|
|
|
562
|
|
|
/** |
563
|
|
|
* A callback function that is invoked by cURL for streaming down. |
564
|
|
|
* |
565
|
|
|
* @param resource $curl_handle (Required) The cURL handle for the request. |
566
|
|
|
* @param binary $data (Required) The data to write. |
567
|
|
|
* @return integer The number of bytes written. |
568
|
|
|
*/ |
569
|
|
|
public function streaming_write_callback($curl_handle, $data) |
570
|
|
|
{ |
571
|
|
|
if ($this->registered_streaming_write_callback){ |
572
|
|
|
return $this->registered_streaming_write_callback->streaming_write_callback($curl_handle,$data,$this->write_stream); |
573
|
|
|
} |
574
|
|
|
$length = strlen($data); |
575
|
|
|
$written_total = 0; |
576
|
|
|
$written_last = 0; |
|
|
|
|
577
|
|
|
|
578
|
|
|
while ($written_total < $length) |
579
|
|
|
{ |
580
|
|
|
$written_last = fwrite($this->write_stream, substr($data, $written_total)); |
581
|
|
|
|
582
|
|
|
if ($written_last === false) |
583
|
|
|
{ |
584
|
|
|
return $written_total; |
585
|
|
|
} |
586
|
|
|
|
587
|
|
|
$written_total += $written_last; |
588
|
|
|
} |
589
|
|
|
|
590
|
|
|
return $written_total; |
591
|
|
|
} |
592
|
|
|
|
593
|
|
|
/** |
594
|
|
|
* Prepares and adds the details of the cURL request. This can be passed along to a <php:curl_multi_exec()> |
595
|
|
|
* function. |
596
|
|
|
* |
597
|
|
|
* @return resource The handle for the cURL object. |
598
|
|
|
*/ |
599
|
|
|
public function prep_request() |
600
|
|
|
{ |
601
|
|
|
$curl_handle = curl_init(); |
602
|
|
|
|
603
|
|
|
// Set default options. |
604
|
|
|
curl_setopt($curl_handle, CURLOPT_URL, $this->request_url); |
605
|
|
|
curl_setopt($curl_handle, CURLOPT_FILETIME, true); |
606
|
|
|
curl_setopt($curl_handle, CURLOPT_FRESH_CONNECT, false); |
607
|
|
|
//为了兼容PHP 5.6,PHP 5.6把 CURLOPT_CLOSEPOLICY 这个变量删除了 |
608
|
|
|
//curl_setopt($curl_handle, CURLOPT_CLOSEPOLICY, CURLCLOSEPOLICY_LEAST_RECENTLY_USED); |
609
|
|
|
curl_setopt($curl_handle, CURLOPT_MAXREDIRS, 5); |
610
|
|
|
curl_setopt($curl_handle, CURLOPT_HEADER, true); |
611
|
|
|
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, true); |
612
|
|
|
curl_setopt($curl_handle, CURLOPT_TIMEOUT, 5184000); |
613
|
|
|
curl_setopt($curl_handle, CURLOPT_CONNECTTIMEOUT, 120); |
614
|
|
|
curl_setopt($curl_handle, CURLOPT_NOSIGNAL, true); |
615
|
|
|
curl_setopt($curl_handle, CURLOPT_REFERER, $this->request_url); |
616
|
|
|
curl_setopt($curl_handle, CURLOPT_USERAGENT, $this->useragent); |
617
|
|
|
curl_setopt($curl_handle, CURLOPT_READFUNCTION, array($this, 'streaming_read_callback')); |
618
|
|
|
|
619
|
|
|
// Verification of the SSL cert |
620
|
|
|
if ($this->ssl_verification) |
621
|
|
|
{ |
622
|
|
|
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, true); |
623
|
|
|
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, 2); |
624
|
|
|
} |
625
|
|
|
else |
626
|
|
|
{ |
627
|
|
|
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYPEER, false); |
628
|
|
|
curl_setopt($curl_handle, CURLOPT_SSL_VERIFYHOST, false); |
629
|
|
|
} |
630
|
|
|
|
631
|
|
|
// chmod the file as 0755 |
632
|
|
|
if ($this->cacert_location === true) |
633
|
|
|
{ |
634
|
|
|
curl_setopt($curl_handle, CURLOPT_CAINFO, dirname(__FILE__) . '/cacert.pem'); |
635
|
|
|
} |
636
|
|
|
elseif (is_string($this->cacert_location)) |
|
|
|
|
637
|
|
|
{ |
638
|
|
|
curl_setopt($curl_handle, CURLOPT_CAINFO, $this->cacert_location); |
639
|
|
|
} |
640
|
|
|
|
641
|
|
|
// Debug mode |
642
|
|
|
if ($this->debug_mode) |
643
|
|
|
{ |
644
|
|
|
curl_setopt($curl_handle, CURLOPT_VERBOSE, true); |
645
|
|
|
} |
646
|
|
|
|
647
|
|
|
// Handle open_basedir & safe mode |
648
|
|
|
if (!ini_get('safe_mode') && !ini_get('open_basedir')) |
649
|
|
|
{ |
650
|
|
|
curl_setopt($curl_handle, CURLOPT_FOLLOWLOCATION, FALSE); |
651
|
|
|
} |
652
|
|
|
|
653
|
|
|
// Enable a proxy connection if requested. |
654
|
|
|
if ($this->proxy) |
655
|
|
|
{ |
656
|
|
|
curl_setopt($curl_handle, CURLOPT_HTTPPROXYTUNNEL, true); |
657
|
|
|
|
658
|
|
|
$host = $this->proxy['host']; |
659
|
|
|
$host .= ($this->proxy['port']) ? ':' . $this->proxy['port'] : ''; |
660
|
|
|
curl_setopt($curl_handle, CURLOPT_PROXY, $host); |
661
|
|
|
|
662
|
|
|
if (isset($this->proxy['user']) && isset($this->proxy['pass'])) |
663
|
|
|
{ |
664
|
|
|
curl_setopt($curl_handle, CURLOPT_PROXYUSERPWD, $this->proxy['user'] . ':' . $this->proxy['pass']); |
665
|
|
|
} |
666
|
|
|
} |
667
|
|
|
|
668
|
|
|
// Set credentials for HTTP Basic/Digest Authentication. |
669
|
|
|
if ($this->username && $this->password) |
670
|
|
|
{ |
671
|
|
|
curl_setopt($curl_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY); |
672
|
|
|
curl_setopt($curl_handle, CURLOPT_USERPWD, $this->username . ':' . $this->password); |
673
|
|
|
} |
674
|
|
|
|
675
|
|
|
// Handle the encoding if we can. |
676
|
|
|
if (extension_loaded('zlib')) |
677
|
|
|
{ |
678
|
|
|
curl_setopt($curl_handle, CURLOPT_ENCODING, ''); |
679
|
|
|
} |
680
|
|
|
|
681
|
|
|
// Process custom headers |
682
|
|
|
if (isset($this->request_headers) && count($this->request_headers)) |
683
|
|
|
{ |
684
|
|
|
$temp_headers = array(); |
685
|
|
|
|
686
|
|
|
foreach ($this->request_headers as $k => $v) |
687
|
|
|
{ |
688
|
|
|
$temp_headers[] = $k . ': ' . $v; |
689
|
|
|
} |
690
|
|
|
|
691
|
|
|
curl_setopt($curl_handle, CURLOPT_HTTPHEADER, $temp_headers); |
692
|
|
|
} |
693
|
|
|
|
694
|
|
|
switch ($this->method) |
695
|
|
|
{ |
696
|
|
|
case self::HTTP_PUT: |
697
|
|
|
//unset($this->read_stream); |
698
|
|
|
curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, 'PUT'); |
699
|
|
|
if (isset($this->read_stream)) |
700
|
|
|
{ |
701
|
|
|
if (!isset($this->read_stream_size) || $this->read_stream_size < 0) |
702
|
|
|
{ |
703
|
|
|
throw new RequestCore_Exception('The stream size for the streaming upload cannot be determined.'); |
704
|
|
|
} |
705
|
|
|
|
706
|
|
|
curl_setopt($curl_handle, CURLOPT_INFILESIZE, $this->read_stream_size); |
707
|
|
|
curl_setopt($curl_handle, CURLOPT_UPLOAD, true); |
708
|
|
|
} |
709
|
|
|
else |
710
|
|
|
{ |
711
|
|
|
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); |
712
|
|
|
} |
713
|
|
|
break; |
714
|
|
|
|
715
|
|
|
case self::HTTP_POST: |
716
|
|
|
curl_setopt($curl_handle, CURLOPT_POST, true); |
717
|
|
|
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); |
718
|
|
|
break; |
719
|
|
|
|
720
|
|
|
case self::HTTP_HEAD: |
721
|
|
|
curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, self::HTTP_HEAD); |
722
|
|
|
curl_setopt($curl_handle, CURLOPT_NOBODY, 1); |
723
|
|
|
break; |
724
|
|
|
|
725
|
|
|
default: // Assumed GET |
726
|
|
|
curl_setopt($curl_handle, CURLOPT_CUSTOMREQUEST, $this->method); |
727
|
|
|
if (isset($this->write_stream)) |
728
|
|
|
{ |
729
|
|
|
curl_setopt($curl_handle, CURLOPT_WRITEFUNCTION, array($this, 'streaming_write_callback')); |
730
|
|
|
curl_setopt($curl_handle, CURLOPT_HEADER, false); |
731
|
|
|
} |
732
|
|
|
else |
733
|
|
|
{ |
734
|
|
|
curl_setopt($curl_handle, CURLOPT_POSTFIELDS, $this->request_body); |
735
|
|
|
} |
736
|
|
|
break; |
737
|
|
|
} |
738
|
|
|
|
739
|
|
|
// Merge in the CURLOPTs |
740
|
|
|
if (isset($this->curlopts) && sizeof($this->curlopts) > 0) |
741
|
|
|
{ |
742
|
|
|
foreach ($this->curlopts as $k => $v) |
743
|
|
|
{ |
744
|
|
|
curl_setopt($curl_handle, $k, $v); |
745
|
|
|
} |
746
|
|
|
} |
747
|
|
|
|
748
|
|
|
return $curl_handle; |
|
|
|
|
749
|
|
|
} |
750
|
|
|
|
751
|
|
|
/** |
752
|
|
|
* Take the post-processed cURL data and break it down into useful header/body/info chunks. Uses the |
753
|
|
|
* data stored in the `curl_handle` and `response` properties unless replacement data is passed in via |
754
|
|
|
* parameters. |
755
|
|
|
* |
756
|
|
|
* @param resource $curl_handle (Optional) The reference to the already executed cURL request. |
757
|
|
|
* @param string $response (Optional) The actual response content itself that needs to be parsed. |
758
|
|
|
* @return ResponseCore A <ResponseCore> object containing a parsed HTTP response. |
759
|
|
|
*/ |
760
|
|
|
public function process_response($curl_handle = null, $response = null) |
761
|
|
|
{ |
762
|
|
|
// Accept a custom one if it's passed. |
763
|
|
|
if ($curl_handle && $response) |
|
|
|
|
764
|
|
|
{ |
765
|
|
|
$this->curl_handle = $curl_handle; |
766
|
|
|
$this->response = $response; |
767
|
|
|
} |
768
|
|
|
|
769
|
|
|
// As long as this came back as a valid resource... |
770
|
|
|
if (is_resource($this->curl_handle)) |
771
|
|
|
{ |
772
|
|
|
// Determine what's what. |
773
|
|
|
$header_size = curl_getinfo($this->curl_handle, CURLINFO_HEADER_SIZE); |
774
|
|
|
$this->response_headers = substr($this->response, 0, $header_size); |
775
|
|
|
$this->response_body = substr($this->response, $header_size); |
776
|
|
|
$this->response_code = curl_getinfo($this->curl_handle, CURLINFO_HTTP_CODE); |
777
|
|
|
$this->response_info = curl_getinfo($this->curl_handle); |
778
|
|
|
|
779
|
|
|
// Parse out the headers |
780
|
|
|
$this->response_headers = explode("\r\n\r\n", trim($this->response_headers)); |
781
|
|
|
$this->response_headers = array_pop($this->response_headers); |
782
|
|
|
$this->response_headers = explode("\r\n", $this->response_headers); |
783
|
|
|
array_shift($this->response_headers); |
784
|
|
|
|
785
|
|
|
// Loop through and split up the headers. |
786
|
|
|
$header_assoc = array(); |
787
|
|
|
foreach ($this->response_headers as $header) |
788
|
|
|
{ |
789
|
|
|
$kv = explode(': ', $header); |
790
|
|
|
$header_assoc[strtolower($kv[0])] = isset($kv[1])?$kv[1]:''; |
791
|
|
|
} |
792
|
|
|
|
793
|
|
|
// Reset the headers to the appropriate property. |
794
|
|
|
$this->response_headers = $header_assoc; |
795
|
|
|
$this->response_headers['_info'] = $this->response_info; |
796
|
|
|
$this->response_headers['_info']['method'] = $this->method; |
797
|
|
|
|
798
|
|
|
if ($curl_handle && $response) |
|
|
|
|
799
|
|
|
{ |
800
|
|
|
return new $this->response_class($this->response_headers, $this->response_body, $this->response_code, $this->curl_handle); |
801
|
|
|
} |
802
|
|
|
} |
803
|
|
|
|
804
|
|
|
// Return false |
805
|
|
|
return false; |
|
|
|
|
806
|
|
|
} |
807
|
|
|
|
808
|
|
|
/** |
809
|
|
|
* Sends the request, calling necessary utility functions to update built-in properties. |
810
|
|
|
* |
811
|
|
|
* @param boolean $parse (Optional) Whether to parse the response with ResponseCore or not. |
812
|
|
|
* @return string The resulting unparsed data from the request. |
813
|
|
|
*/ |
814
|
|
|
public function send_request($parse = false) |
815
|
|
|
{ |
816
|
|
|
set_time_limit(0); |
817
|
|
|
|
818
|
|
|
$curl_handle = $this->prep_request(); |
819
|
|
|
$this->response = curl_exec($curl_handle); |
820
|
|
|
|
821
|
|
|
if ($this->response === false) |
822
|
|
|
{ |
823
|
|
|
throw new RequestCore_Exception('cURL resource: ' . (string) $curl_handle . '; cURL error: ' . curl_error($curl_handle) . ' (' . curl_errno($curl_handle) . ')'); |
824
|
|
|
} |
825
|
|
|
|
826
|
|
|
$parsed_response = $this->process_response($curl_handle, $this->response); |
|
|
|
|
827
|
|
|
|
828
|
|
|
curl_close($curl_handle); |
829
|
|
|
|
830
|
|
|
if ($parse) |
831
|
|
|
{ |
832
|
|
|
return $parsed_response; |
|
|
|
|
833
|
|
|
} |
834
|
|
|
|
835
|
|
|
return $this->response; |
|
|
|
|
836
|
|
|
} |
837
|
|
|
|
838
|
|
|
/** |
839
|
|
|
* Sends the request using <php:curl_multi_exec()>, enabling parallel requests. Uses the "rolling" method. |
840
|
|
|
* |
841
|
|
|
* @param array $handles (Required) An indexed array of cURL handles to process simultaneously. |
842
|
|
|
* @param array $opt (Optional) An associative array of parameters that can have the following keys: <ul> |
843
|
|
|
* <li><code>callback</code> - <code>string|array</code> - Optional - The string name of a function to pass the response data to. If this is a method, pass an array where the <code>[0]</code> index is the class and the <code>[1]</code> index is the method name.</li> |
844
|
|
|
* <li><code>limit</code> - <code>integer</code> - Optional - The number of simultaneous requests to make. This can be useful for scaling around slow server responses. Defaults to trusting cURLs judgement as to how many to use.</li></ul> |
845
|
|
|
* @return array Post-processed cURL responses. |
846
|
|
|
*/ |
847
|
|
|
public function send_multi_request($handles, $opt = null) |
848
|
|
|
{ |
849
|
|
|
set_time_limit(0); |
850
|
|
|
|
851
|
|
|
// Skip everything if there are no handles to process. |
852
|
|
|
if (count($handles) === 0) return array(); |
853
|
|
|
|
854
|
|
|
if (!$opt) $opt = array(); |
855
|
|
|
|
856
|
|
|
// Initialize any missing options |
857
|
|
|
$limit = isset($opt['limit']) ? $opt['limit'] : -1; |
858
|
|
|
|
859
|
|
|
// Initialize |
860
|
|
|
$handle_list = $handles; |
861
|
|
|
$http = new $this->request_class(); |
862
|
|
|
$multi_handle = curl_multi_init(); |
863
|
|
|
$handles_post = array(); |
864
|
|
|
$added = count($handles); |
865
|
|
|
$last_handle = null; |
|
|
|
|
866
|
|
|
$count = 0; |
|
|
|
|
867
|
|
|
$i = 0; |
868
|
|
|
|
869
|
|
|
// Loop through the cURL handles and add as many as it set by the limit parameter. |
870
|
|
|
while ($i < $added) |
871
|
|
|
{ |
872
|
|
|
if ($limit > 0 && $i >= $limit) break; |
873
|
|
|
curl_multi_add_handle($multi_handle, array_shift($handles)); |
|
|
|
|
874
|
|
|
$i++; |
875
|
|
|
} |
876
|
|
|
|
877
|
|
|
do |
878
|
|
|
{ |
879
|
|
|
$active = false; |
880
|
|
|
|
881
|
|
|
// Start executing and wait for a response. |
882
|
|
|
while (($status = curl_multi_exec($multi_handle, $active)) === CURLM_CALL_MULTI_PERFORM) |
|
|
|
|
883
|
|
|
{ |
884
|
|
|
// Start looking for possible responses immediately when we have to add more handles |
885
|
|
|
if (count($handles) > 0) break; |
886
|
|
|
} |
887
|
|
|
|
888
|
|
|
// Figure out which requests finished. |
889
|
|
|
$to_process = array(); |
890
|
|
|
|
891
|
|
|
while ($done = curl_multi_info_read($multi_handle)) |
|
|
|
|
892
|
|
|
{ |
893
|
|
|
// Since curl_errno() isn't reliable for handles that were in multirequests, we check the 'result' of the info read, which contains the curl error number, (listed here http://curl.haxx.se/libcurl/c/libcurl-errors.html ) |
894
|
|
|
if ($done['result'] > 0) |
895
|
|
|
{ |
896
|
|
|
throw new RequestCore_Exception('cURL resource: ' . (string) $done['handle'] . '; cURL error: ' . curl_error($done['handle']) . ' (' . $done['result'] . ')'); |
897
|
|
|
} |
898
|
|
|
|
899
|
|
|
// Because curl_multi_info_read() might return more than one message about a request, we check to see if this request is already in our array of completed requests |
900
|
|
|
elseif (!isset($to_process[(int) $done['handle']])) |
901
|
|
|
{ |
902
|
|
|
$to_process[(int) $done['handle']] = $done; |
903
|
|
|
} |
904
|
|
|
} |
905
|
|
|
|
906
|
|
|
// Actually deal with the request |
907
|
|
|
foreach ($to_process as $pkey => $done) |
908
|
|
|
{ |
909
|
|
|
$response = $http->process_response($done['handle'], curl_multi_getcontent($done['handle'])); |
910
|
|
|
$key = array_search($done['handle'], $handle_list, true); |
911
|
|
|
$handles_post[$key] = $response; |
912
|
|
|
|
913
|
|
|
if (count($handles) > 0) |
914
|
|
|
{ |
915
|
|
|
curl_multi_add_handle($multi_handle, array_shift($handles)); |
916
|
|
|
} |
917
|
|
|
|
918
|
|
|
curl_multi_remove_handle($multi_handle, $done['handle']); |
|
|
|
|
919
|
|
|
curl_close($done['handle']); |
920
|
|
|
} |
921
|
|
|
} |
922
|
|
|
while ($active || count($handles_post) < $added); |
923
|
|
|
|
924
|
|
|
curl_multi_close($multi_handle); |
|
|
|
|
925
|
|
|
|
926
|
|
|
ksort($handles_post, SORT_NUMERIC); |
927
|
|
|
return $handles_post; |
928
|
|
|
} |
929
|
|
|
|
930
|
|
|
|
931
|
|
|
/*%******************************************************************************************%*/ |
932
|
|
|
// RESPONSE METHODS |
933
|
|
|
|
934
|
|
|
/** |
935
|
|
|
* Get the HTTP response headers from the request. |
936
|
|
|
* |
937
|
|
|
* @param string $header (Optional) A specific header value to return. Defaults to all headers. |
938
|
|
|
* @return string|array All or selected header values. |
939
|
|
|
*/ |
940
|
|
|
public function get_response_header($header = null) |
941
|
|
|
{ |
942
|
|
|
if ($header) |
943
|
|
|
{ |
944
|
|
|
return $this->response_headers[strtolower($header)]; |
945
|
|
|
} |
946
|
|
|
return $this->response_headers; |
947
|
|
|
} |
948
|
|
|
|
949
|
|
|
/** |
950
|
|
|
* Get the HTTP response body from the request. |
951
|
|
|
* |
952
|
|
|
* @return string The response body. |
953
|
|
|
*/ |
954
|
|
|
public function get_response_body() |
955
|
|
|
{ |
956
|
|
|
return $this->response_body; |
957
|
|
|
} |
958
|
|
|
|
959
|
|
|
/** |
960
|
|
|
* Get the HTTP response code from the request. |
961
|
|
|
* |
962
|
|
|
* @return string The HTTP response code. |
963
|
|
|
*/ |
964
|
|
|
public function get_response_code() |
965
|
|
|
{ |
966
|
|
|
return $this->response_code; |
967
|
|
|
} |
968
|
|
|
} |
969
|
|
|
|
970
|
|
|
|
971
|
|
|
/** |
972
|
|
|
* Container for all response-related methods. |
973
|
|
|
*/ |
974
|
|
|
class ResponseCore |
975
|
|
|
{ |
976
|
|
|
/** |
977
|
|
|
* Stores the HTTP header information. |
978
|
|
|
*/ |
979
|
|
|
public $header; |
980
|
|
|
|
981
|
|
|
/** |
982
|
|
|
* Stores the SimpleXML response. |
983
|
|
|
*/ |
984
|
|
|
public $body; |
985
|
|
|
|
986
|
|
|
/** |
987
|
|
|
* Stores the HTTP response code. |
988
|
|
|
*/ |
989
|
|
|
public $status; |
990
|
|
|
|
991
|
|
|
/** |
992
|
|
|
* Constructs a new instance of this class. |
993
|
|
|
* |
994
|
|
|
* @param array $header (Required) Associative array of HTTP headers (typically returned by <RequestCore::get_response_header()>). |
995
|
|
|
* @param string $body (Required) XML-formatted response from AWS. |
996
|
|
|
* @param integer $status (Optional) HTTP response status code from the request. |
997
|
|
|
* @return object Contains an <php:array> `header` property (HTTP headers as an associative array), a <php:SimpleXMLElement> or <php:string> `body` property, and an <php:integer> `status` code. |
998
|
|
|
*/ |
999
|
|
|
public function __construct($header, $body, $status = null) |
1000
|
|
|
{ |
1001
|
|
|
$this->header = $header; |
1002
|
|
|
$this->body = $body; |
1003
|
|
|
$this->status = $status; |
1004
|
|
|
|
1005
|
|
|
return $this; |
1006
|
|
|
} |
1007
|
|
|
|
1008
|
|
|
/** |
1009
|
|
|
* Did we receive the status code we expected? |
1010
|
|
|
* |
1011
|
|
|
* @param integer|array $codes (Optional) The status code(s) to expect. Pass an <php:integer> for a single acceptable value, or an <php:array> of integers for multiple acceptable values. |
1012
|
|
|
* @return boolean Whether we received the expected status code or not. |
1013
|
|
|
*/ |
1014
|
|
|
public function isOK($codes = array(200, 201, 204, 206)) |
1015
|
|
|
{ |
1016
|
|
|
if (is_array($codes)) |
1017
|
|
|
{ |
1018
|
|
|
return in_array($this->status, $codes); |
1019
|
|
|
} |
1020
|
|
|
|
1021
|
|
|
return $this->status === $codes; |
1022
|
|
|
} |
1023
|
|
|
} |
1024
|
|
|
|
1025
|
|
|
/** |
1026
|
|
|
* Default RequestCore Exception. |
1027
|
|
|
*/ |
1028
|
|
|
class RequestCore_Exception extends Exception {} |
1029
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.