GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.
Test Failed
Push — master ( 4703c4...b7eadc )
by sunsky
02:50
created

Request::serializeBody()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 4

Importance

Changes 0
Metric Value
dl 0
loc 13
ccs 10
cts 10
cp 1
rs 9.2
c 0
b 0
f 0
cc 4
eloc 8
nc 4
nop 0
crap 4
1
<?php
2
/**
3
 *
4
 * @author  [email protected] [email protected]
5
 * Date: 2017/6/16
6
 * Time: 10:02
7
 * @version $Id: $
8
 * @since 1.0
9
 * @copyright Sina Corp.
10
 */
11
12
namespace MultiHttp;
13
14
use MultiHttp\Exception\InvalidArgumentException;
15
use MultiHttp\Exception\InvalidOperationException;
16
17
/**
18
 * Class Request
19
 * @package MultiHttp
20
 */
21
class Request extends Http
22
{
23
    /**
24
     * you can implement more traits
25
     */
26
    use JsonTrait;
27
28
    protected static $curlAlias = array(
29
        'url' => 'CURLOPT_URL',
30
        'uri' => 'CURLOPT_URL',
31
        'debug' => 'CURLOPT_VERBOSE',//for debug verbose
32
        'method' => 'CURLOPT_CUSTOMREQUEST',
33
        'data' => 'CURLOPT_POSTFIELDS', // array or string , file begin with '@'
34
        'ua' => 'CURLOPT_USERAGENT',
35
        'timeout' => 'CURLOPT_TIMEOUT', // (secs) 0 means indefinitely
36
        'connect_timeout' => 'CURLOPT_CONNECTTIMEOUT',
37
        'referer' => 'CURLOPT_REFERER',
38
        'binary' => 'CURLOPT_BINARYTRANSFER',
39
        'port' => 'CURLOPT_PORT',
40
        'header' => 'CURLOPT_HEADER', // TRUE:include header
41
        'headers' => 'CURLOPT_HTTPHEADER', // array
42
        'download' => 'CURLOPT_FILE', // writing file stream (using fopen()), default is STDOUT
43
        'upload' => 'CURLOPT_INFILE', // reading file stream
44
        'transfer' => 'CURLOPT_RETURNTRANSFER', // TRUE:return string; FALSE:output directly (curl_exec)
45
        'follow_location' => 'CURLOPT_FOLLOWLOCATION',
46
        'timeout_ms' => 'CURLOPT_TIMEOUT_MS', // milliseconds,  libcurl version > 7.36.0 ,
47
        'expects_mime' => null, //expected mime
48
        'send_mime' => null, //send mime
49
        'ip' => null,//specify ip to send request
50
        'callback' => null,//callback on end
51
52
    );
53
    protected static $loggerHandler;
54
    public
55
        $curlHandle,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
Coding Style introduced by
The visibility should be declared for property $curlHandle.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
56
        $uri,
57
        $sendMime,
58
        $expectedMime,
59
        $timeout,
60
        $maxRedirects,
61
        $encoding,
62
        $payload,
63
        $retryTimes,
64
        /**
65
         * @var int seconds
66
         */
67
        $retryDuration,
68
        $followRedirects;
69
70
    protected
71
        $body,
0 ignored issues
show
Coding Style introduced by
It is generally advisable to only define one property per statement.

Only declaring a single property per statement allows you to later on add doc comments more easily.

It is also recommended by PSR2, so it is a common style that many people expect.

Loading history...
Coding Style introduced by
The visibility should be declared for property $body.

The PSR-2 coding standard requires that all properties in a class have their visibility explicitly declared. If you declare a property using

class A {
    var $property;
}

the property is implicitly global.

To learn more about the PSR-2, please see the PHP-FIG site on the PSR-2.

Loading history...
72
        $endCallback,
73
        $withURIQuery,
74
        $hasInitialized = false,
75
        /**
76
         * @var array
77
         */
78
        $options = array(
79
            'CURLOPT_MAXREDIRS' => 10,
80
            'CURLOPT_SSL_VERIFYPEER' => false,//for https
81
            'CURLOPT_SSL_VERIFYHOST' => 0,//for https
82
            'CURLOPT_IPRESOLVE' => CURL_IPRESOLVE_V4,//ipv4 first
83
//            'CURLOPT_SAFE_UPLOAD' => false,// compatible with PHP 5.6.0
84
            'header' => true,
85
            'method' => self::GET,
86
            'transfer' => true,
87
            'headers' => array(),
88
            'follow_location' => true,
89
            'timeout' => 0,
90
            //        'ip' => null, //host, in string, .e.g: 172.16.1.1:888
0 ignored issues
show
Unused Code Comprehensibility introduced by
38% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
91
            'retry_times' => 1,//redo task when failed
92
            'retry_duration' => 0,//in seconds
93
        );
94
95
96
    /**
97
     * Request constructor.
98
     */
99 6
    protected function __construct()
100
    {
101 6
    }
102
103
    /**
104
     * @return Request
105
     */
106 6
    public static function create()
107
    {
108 6
        return new self;
109
    }
110
111
    /**
112
     * @param callable $handler
113
     */
114 1
    public static function setLogHandler(callable $handler)
115
    {
116 1
        self::$loggerHandler = $handler;
117 1
    }
118
    /**
119
     * Specify   timeout
120
     * @param float|int $timeout seconds to timeout the HTTP call
121
     * @return Request
122
     */
123
    public function timeout($timeout)
124
    {
125
        $this->timeout = $timeout;
126
        return $this;
127
    }
128
129
    /**
130
     * @return Request
131
     */
132
    public function noFollow()
133
    {
134
        return $this->follow(0);
135
    }
136
137
    /**
138
     * If the response is a 301 or 302 redirect, automatically
139
     * send off another request to that location
140
     * @param int $follow follow or not to follow or maximal number of redirects
141
     * @return Request
142
     */
143
    public function follow($follow)
144
    {
145
        $this->maxRedirects = abs($follow);
146
        $this->followRedirects = $follow > 0;
147
        return $this;
148
    }
149
150
    /**
151
     * @param $parsedComponents
152
     * @return string
153
     */
154 6
    private static function combineUrl($parsedComponents)
155
    {
156 6
        $scheme = isset($parsedComponents['scheme']) ? $parsedComponents['scheme'] . '://' : '';
157 6
        $host = isset($parsedComponents['host']) ? $parsedComponents['host'] : '';
158 6
        $port = isset($parsedComponents['port']) ? ':' . $parsedComponents['port'] : '';
159 6
        $user = isset($parsedComponents['user']) ? $parsedComponents['user'] : '';
160 6
        $pass = isset($parsedComponents['pass']) ? ':' . $parsedComponents['pass'] : '';
161 6
        $pass = ($user || $pass) ? "$pass@" : '';
162 6
        $path = isset($parsedComponents['path']) ? $parsedComponents['path'] : '';
163 6
        $query = isset($parsedComponents['query']) ? '?' . $parsedComponents['query'] : '';
164 6
        $fragment = isset($parsedComponents['fragment']) ? '#' . $parsedComponents['fragment'] : '';
165 6
        return "$scheme$user$pass$host$port$path$query$fragment";
166
    }
167
168
    /**
169
     * @param string $mime
170
     * @return $this
171
     */
172 2
    public function expectsMime($mime = 'json')
173
    {
174 2
        $this->expectedMime = $mime;
175 2
        return $this;
176
    }
177
178
    /**
179
     * @param string $mime
180
     * @return Request
181
     */
182 2
    public function sendMime($mime = 'json')
183
    {
184 2
        $this->sendMime = $mime;
185
//        $this->addHeader('Content-type', Mime::getFullMime($mime));
0 ignored issues
show
Unused Code Comprehensibility introduced by
69% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
186 2
        return $this;
187
    }
188
189
    /**
190
     * @param $headerName
191
     * @param $value , can be rawurlencode
192
     * @return $this
193
     */
194 1
    public function addHeader($headerName, $value)
195
    {
196 1
        $this->options['headers'][] = $headerName . ': ' . $value;
197 1
        return $this;
198
    }
199
200
    /**
201
     * @param $uri
202
     * @return $this
203
     */
204
    public function uri($uri)
205
    {
206
        $this->uri = $uri;
207
        return $this;
208
    }
209
210
211
212
    /**
213
     * @param array $headers
214
     * @return $this
215
     */
216 1
    public function addHeaders(array $headers)
217
    {
218 1
        foreach ($headers as $header => $value) {
219 1
            $this->addHeader($header, $value);
220 1
        }
221 1
        return $this;
222
    }
223
    public function expectsType($mime)
224
    {
225
        return $this->expects($mime);
226
    }
227
    public function sendType($mime)
228
    {
229
        return $this->contentType = $mime;
0 ignored issues
show
Bug introduced by
The property contentType does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
230
    }
231
    public function expects($mime)
232
    {
233
        if (empty($mime)) return $this;
234
        $this->expected_type = Mime::getFullMime($mime);
0 ignored issues
show
Bug introduced by
The property expected_type does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
235
        return $this;
236
    }
237
238
    /**
239
     * @return mixed
240
     */
241
    public function endCallback()
242
    {
243
        return $this->endCallback;
244
    }
245
246
    /**
247
     * @return bool
248
     */
249 2
    public function hasEndCallback()
250
    {
251 2
        return isset($this->endCallback);
252
    }
253
254
    /**
255
     * @param $field alias or field name
256
     * @return bool|mixed
257
     */
258 3
    public function getIni($field = null)
259
    {
260 3
        if(!$field) return $this->options;
261 3
        $full = self::fullOption($field);
262 3
        return isset($this->options[$full]) ? $this->options[$full] : false;
263
    }
264
265
    /**
266
     * @param $key
267
     * @return mixed
268
     */
269 6
    protected static function fullOption($key)
270
    {
271 6
        $full = false;
272 6
        if (isset(self::$curlAlias[$key])) {
273 6
            $full = self::$curlAlias[$key];
274 6
        } elseif ((substr($key, 0, strlen('CURLOPT_')) == 'CURLOPT_') && defined($key)) {
275 6
            $full = $key;
276 6
        }
277 6
        return $full;
278
    }
279
280
    /**
281
     * @param $queryData
282
     * @return $this
283
     */
284 1
    public function addQuery($queryData)
285
    {
286 1
        if (!empty($queryData)) {
287 1
            if (is_array($queryData)) {
288 1
                $this->withURIQuery = http_build_query($queryData);
289 1
            } else if (is_string($queryData)) {
290 1
                $this->withURIQuery = $queryData;
291 1
            } else {
292
                throw new InvalidArgumentException('data must be array or string');
293
            }
294 1
        }
295 1
        return $this;
296
    }
297
    /**
298
     * @param $uri
299
     * @param null $payload
300
     * @param array $options
301
     * @return Request
302
     */
303 3
    public function post($uri, $payload = null, array $options = array())
304
    {
305 3
        return $this->ini(Http::POST, $uri, $payload, $options);
306
    }
307
308
    /**
309
     * @param $uri
310
     * @param null $payload
311
     * @param array $options
312
     * @param null $response
313
     * @return string
314
     */
315 2
    public function quickPost($uri, $payload = null, array $options = array(), &$response = null)
316
    {
317 2
        $response = $this->post($uri, $payload, $options)->send();
318 2
        return $response->body;
319
    }
320
321
322
    /**
323
     * @param $method
324
     * @param $url
325
     * @param $data
326
     * @param array $options
327
     * @return $this
328
     */
329 5 View Code Duplication
    protected function ini($method, $url, $data, array $options = array())
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
330
    {
331 5
        $options = array('url' => $url, 'method' => $method, 'data' => $data) + $options;
332 5
        $this->addOptions($options);
333
334 5
        return $this;
335
    }
336
337
    /**
338
     * @param array $options
339
     * @return $this
340
     */
341 6
    public function addOptions(array $options = array())
342
    {
343 6
        $this->options = $options + $this->options;
344 6
        $this->uri = $this->options['url'];
345 6
        return $this;
346
    }
347
348
    /**
349
     * @param $uri
350
     * @param null $payload
351
     * @param array $options
352
     * @return Request
353
     */
354 1
    function put($uri, $payload = null, array $options = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
355
    {
356 1
        return $this->ini(Http::PUT, $uri, $payload, $options);
357
    }
358
359
    /**
360
     * @param $uri
361
     * @param null $payload
362
     * @param array $options
363
     * @return Request
364
     */
365 1
    function patch($uri, $payload = null, array $options = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
366
    {
367 1
        return $this->ini(Http::PATCH, $uri, $payload, $options);
368
    }
369
370
    /**
371
     * @param $uri
372
     * @param array $options
373
     * @return Request
374
     */
375 3
    public function get($uri, array $options = array())
376
    {
377 3
        return $this->ini(Http::GET, $uri, array(), $options);
378
    }
379
380
381
    /**
382
     * @param $uri
383
     * @param array $options
384
     * @param null $response
385
     * @return string
386
     */
387 2
    public function quickGet($uri, array $options = array(), &$response = null)
388
    {
389 2
        $response = $this->get($uri, $options)->send();
390 2
        return $response->body;
391
    }
392
393
    /**
394
     * @param $uri
395
     * @param array $options
396
     * @return Request
397
     */
398 1
    function options($uri, array $options = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
399
    {
400 1
        return $this->ini(Http::OPTIONS, $uri, array(), $options);
401
    }
402
403
    /**
404
     * @param $uri
405
     * @param array $options
406
     * @return Request
407
     */
408 1
    function head($uri, array $options = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
409
    {
410 1
        return $this->ini(Http::HEAD, $uri, array('CURLOPT_NOBODY' => true), $options);
411
    }
412
413
    /**
414
     * @param $uri
415
     * @param array $options
416
     * @return Request
417
     */
418 1
    function delete($uri, array $options = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
419
    {
420 1
        return $this->ini(Http::DELETE, $uri, array(), $options);
421
    }
422
423
    /**
424
     * @param $uri
425
     * @param array $options
426
     * @return Request
427
     */
428 2
    function trace($uri, array $options = array())
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
429
    {
430 2
        return $this->ini(Http::TRACE, $uri, array(), $options);
431
    }
432
433
    /**
434
     * @param bool $isMultiCurl
435
     * @return Response
436
     */
437 6
    public function send($isMultiCurl = false)
438
    {
439
        try {
440 6
            if (!$this->hasInitialized)
441 6
                $this->applyOptions();
442 6
            $response = $this->makeResponse($isMultiCurl);
443 5
            $response->parse();
444 6
        } catch (\Exception $e) {
445 2
            if(!isset($response)) $response = Response::create($this, null, null, null, null);
446 2
            $response->error = $e->getMessage();
447 2
            $response->errorCode = 999;
448
        }
449
450 6
        if (self::$loggerHandler) {
451 2
            call_user_func(self::$loggerHandler, $response);
452 2
        }
453 6
        if ($this->endCallback) {
454 5
            call_user_func($this->endCallback, $response);
455 4
        }
456
457 5
        return $response;
458
    }
459
460
    /**
461
     * @return $this
462
     */
463 6
    public function applyOptions()
464
    {
465 6
        $curl = curl_init();
466 6
        $this->curlHandle = $curl;
467 6
        $this->prepare();
468 6
        $this->hasInitialized = true;
469 6
        return $this;
470
    }
471
472
    /**
473
     * @return $this
474
     */
475 6
    protected function prepare()
476
    {
477 6
        $this->options['url'] = trim($this->options['url']);
478 6
        if (empty($this->options['url'])) {
479
            throw new InvalidArgumentException('url can not empty');
480
        }
481
482 6
        if (isset($this->options['retry_times'])) {
483 6
            $this->retryTimes = abs($this->options['retry_times']);
484 6
        }
485
486 6
        if (isset($this->options['retry_duration'])) {
487 6
            $this->retryDuration = abs($this->options['retry_duration']);
488 6
        }
489
490 6
        if(isset($this->options['expects_mime'])){
491 1
            $this->expectsMime($this->options['expects_mime']);
492 1
        }
493
494 6
        if(isset($this->options['send_mime'])){
495 1
            $this->sendMime($this->options['send_mime']);
496 1
        }
497
498
//        if(!empty($this->options['data']) && !Http::hasBody($this->options['method'])){
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
499
//            $this->withURIQuery =  is_array($this->options['data']) ? http_build_query($this->options['data']) : $this->options['data'];
500
//        }
501 6
        if (isset($this->withURIQuery)) {
502 1
            $this->options['url'] .= strpos($this->options['url'], '?') === FALSE ? '?' : '&';
503 1
            $this->options['url'] .= $this->withURIQuery;
504 1
        }
505
506 6
        $this->serializeBody();
507
508
        //try fix url
509 6
        if (strpos($this->options['url'], '://') === FALSE) $this->options['url'] = 'http://' . $this->options['url'];
510 6
        $components = parse_url($this->options['url']);
511 6
        if(FALSE === $components) throw new InvalidArgumentException('formatting url occurs error: '. $this->options['url']);
512 6
        if($this->withURIQuery){
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->withURIQuery of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
513 1
            if(isset($components['query'])) $components['query'] .= '&'. trim($this->withURIQuery);
514 1
            else $components['query'] = trim($this->withURIQuery);
515 1
        }
516 6
        $this->options['url'] = self::combineUrl($components);
517
518 6
        if (isset($this->options['callback'])) {
519 5
            $this->onEnd($this->options['callback']);
520 5
        }
521
        //swap ip and host
522 6
        if (!empty($this->options['ip'])) {
523 2
            $matches = array();
524 2
            preg_match('/\/\/([^\/]+)/', $this->options['url'], $matches);
525 2
            $host = $matches[1];
526 2
            if (empty($this->options['headers']) || !is_array($this->options['headers'])) {
527 2
                $this->options['headers'] = array('Host: ' . $host);
528 2
            } else {
529
                $this->options['headers'][] = 'Host: ' . $host;
530
            }
531 2
            $this->options['url'] = preg_replace('/\/\/([^\/]+)/', '//' . $this->options['ip'], $this->options['url']);
532 2
            unset($host);
533 2
        }
534
        //process version
535 6
        if (!empty($this->options['http_version'])) {
536
            $version = $this->options['http_version'];
537
            if ($version == '1.0') {
538
                $this->options['CURLOPT_HTTP_VERSION'] = CURLOPT_HTTP_VERSION_1_0;
539
            } elseif ($version == '1.1') {
540
                $this->options['CURLOPT_HTTP_VERSION'] = CURLOPT_HTTP_VERSION_1_1;
541
            }
542
543
            unset($version);
544
        }
545
546
        //convert secs to milliseconds
547 6
        if (defined('CURLOPT_TIMEOUT_MS')) {
548 6
            if (!isset($this->options['timeout_ms'])) {
549 6
                $this->options['timeout_ms'] = intval($this->options['timeout'] * 1000);
550 6
            } else {
551 1
                $this->options['timeout_ms'] = intval($this->options['timeout_ms']);
552
            }
553 6
        }
554
555 6
        $cURLOptions = self::filterAndRaw($this->options);
556 6
        if(isset($this->body))$cURLOptions[CURLOPT_POSTFIELDS] = $this->body;//use serialized body not raw data
557 6
        curl_setopt_array($this->curlHandle, $cURLOptions);
558
559 6
        return $this;
560
    }
561
562 6
    public function serializeBody()
563
    {
564 6
        if (isset($this->options['data'])) {
565 6
            if (isset($this->sendMime)) {
566 2
                $method = $this->sendMime;
567 2
                if (!method_exists($this, $method)) throw new InvalidOperationException($method . ' is not exists in ' . __CLASS__);
568 2
                $this->body = $this->$method($this->options['data']);
569 2
            } else {
570 6
                $this->body =  $this->options['data'];
571
            }
572
573 6
        }
574 6
    }
575
576
    /**
577
     * @param callable $callback
578
     * @return $this
579
     */
580 5
    public function onEnd(callable $callback)
581
    {
582 5
        if (!is_callable($callback)) {
583
            throw new InvalidArgumentException('callback not is callable :' . print_r($callback, 1));
584
        }
585
586 5
        $this->endCallback = $callback;
587 5
        return $this;
588
    }
589
590
    /**
591
     * @param array $options
592
     * @return array
593
     */
594 6
    protected static function filterAndRaw(array &$options)
595
    {
596 6
        $opts = $fullsOpts = array();
597 6
        foreach ($options as $key => $val) {
598 6
            $fullOption = self::fullOption($key);
599
600 6
            if ($fullOption) {
601 6
                $fullsOpts[$fullOption] = $val;
602 6
                $opts[constant($fullOption)] = $val;
603 6
            }
604 6
            unset($options[$key]);
605 6
        }
606 6
        $options = $fullsOpts;
607 6
        return $opts;
608
    }
609
610
    /**
611
     * @param bool $isMultiCurl
612
     * @return Response
613
     * @throws \Exception
614
     */
615 6
    public function makeResponse($isMultiCurl = false)
616
    {
617 6
        $handle = $this->curlHandle;
618 6
        $body = $errno = null;
619 6
        Helper::retry($this->retryTimes, function()use(&$body, &$errno, $isMultiCurl, $handle){
620 6
            $body = $isMultiCurl ? curl_multi_getcontent($handle) : curl_exec($handle);
621 5
            $errno = curl_errno($handle);
622 5
            return 0 == $errno;
623 6
        }, $this->retryDuration);
624
625 5
        $info = curl_getinfo($this->curlHandle);
626 5
        $errorCode = curl_errno($this->curlHandle);
627 5
        $error = curl_error($this->curlHandle);
628 5
        $response = Response::create($this, $body, $info, $errorCode, $error);
629 5
        return $response;
630
    }
631
632
633
}
634