Httprequest::init_curl()   F
last analyzed

Complexity

Conditions 29
Paths 811

Size

Total Lines 140

Duplication

Lines 61
Ratio 43.57 %

Code Coverage

Tests 64
CRAP Score 37.894

Importance

Changes 0
Metric Value
dl 61
loc 140
ccs 64
cts 82
cp 0.7805
rs 0.2099
c 0
b 0
f 0
cc 29
nc 811
nop 1
crap 37.894

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php namespace Comodojo\Httprequest;
2
3
use \Comodojo\Exception\HttpException;
4
use \League\Url\Url;
5
6
/**
7
 * HTTP requests library   
8
 * 
9
 * @package     Comodojo Spare Parts
10
 * @author      Marco Giovinazzi <[email protected]>
11
 * @license     MIT
12
 *
13
 * LICENSE:
14
 * 
15
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21
 * THE SOFTWARE.
22
 */
23
 
24
class Httprequest {
25
26
    /**
27
     * Remote host address (complete url)
28
     *
29
     * @var string
30
     */
31
    private $address = null;
32
    
33
    /**
34
     * Remote host port
35
     *
36
     * @var integer
37
     */
38
    private $port = 80;
39
    
40
    /**
41
     * Conversation method (GET or POST)
42
     *
43
     * @var string
44
     */
45
    private $method = 'GET';
46
    
47
    /**
48
     * Timeout for request, in seconds.
49
     *
50
     * @var integer
51
     */
52
    private $timeout = 30;
53
    
54
    /**
55
     * HTTP Version (1.0/1.1)
56
     *
57
     * @var string
58
     */
59
    private $httpVersion = "1.0";
60
    
61
    /**
62
     * Auth method to use. It currently support only:
63
     * - BASIC
64
     * - NTLM (only if CURL is available)
65
     *
66
     * @var string
67
     */
68
    private $authenticationMethod = null;
69
    
70
    /**
71
     * Remote host auth username
72
     *
73
     * @var string
74
     */
75
    private $user = null;
76
    
77
    /**
78
     * Remote host auth password
79
     *
80
     * @var string
81
     */
82
    private $pass = null;
83
84
    /**
85
     * Request user agent
86
     * 
87
     * @var string
88
     */
89
    private $userAgent = 'Comodojo-Httprequest';
90
    
91
    /**
92
     * Content type
93
     * 
94
     * @var string
95
     */
96
    private $contentType = 'application/x-www-form-urlencoded';
97
98
    /**
99
     * array of headers to send
100
     *
101
     * @var array
102
     */
103
    private $headers = array(
104
        'Accept'            =>  'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
105
        'Accept-Language'   =>  'en-us,en;q=0.5',
106
        'Accept-Encoding'   =>  'gzip,deflate',
107
        'Accept-Charset'    =>  'UTF-8;q=0.7,*;q=0.7'
108
    );
109
110
    /**
111
     * Should we use a proxy?
112
     *
113
     * @var string
114
     */
115
    private $proxy = null;
116
117
    private $proxy_auth = null;
118
119
    /**
120
     * Allowed HTTP methods
121
     *
122
     * @var array
123
     */
124
    private $supported_auth_methods = array("BASIC", "DIGEST", "SPNEGO", "NTLM");
125
126
    /**
127
     * Allowed HTTP authentication
128
     *
129
     * @var array
130
     */
131
    private $supported_http_methods = array("GET", "POST", "PUT", "DELETE");
132
133
    /**
134
     * Are we using curl?
135
     */
136
    private $curl = true;
137
    
138
    /**
139
     * Received headers
140
     *
141
     * @var array
142
     */
143
    private $receivedHeaders = array();
144
145
    /**
146
     * Received http status code
147
     *
148
     * @var int
149
     */
150
    private $receivedHttpStatus = null;
151
152
    /**
153
     * Transfer channel
154
     *
155
     * @var resource
156
     */
157
    private $ch = false;
158
159
    private $stream_get_data = null;
160
161
    /**
162
     * Ignore Errors (stream only)
163
     *
164
     * @var boolean
165
     */
166
    private $ignore_errors = false;
167
    
168
    /**
169
     * Class constructor
170
     *
171
     * @param   string  $address Remote host address
172
     * @param   bool    $curl    Use curl (true) or stream (false)
173
     * 
174
     * @throws \Comodojo\Exception\HttpException
175
     */
176 84
    final public function __construct($address = false, $curl = true) {
177
178 84
        if ( !empty($address) ) {
179
            
180
            try {
181
                
182
                $this->setHost($address);
183
                
184
            } catch (HttpException $he) {
185
                
186
                throw $he;
187
                
188
            }
189
            
190
        }
191
        
192 84
        $this->setCurl($curl);
193
        
194 84
    }
195
196
    /**
197
     * Class destructor
198
     *
199
     */
200 6
    final public function __destruct() {
201
202 6
        if ( $this->ch !== false ) $this->close_transport();
203
204 6
    }
205
206
    /**
207
     * Set remote host address
208
     *
209
     * @param   string  $address Remote host address
210
     *
211
     * @return  \Comodojo\Httprequest\Httprequest
212
     * 
213
     * @throws  \Comodojo\Exception\HttpException
214
     */
215 84
    final public function setHost($address) {
216
        
217 84
        $url = filter_var($address, FILTER_VALIDATE_URL);
218
219 84
        if ( $url === false ) throw new HttpException("Invalid remote address");
220
        
221 81
        $this->address = $address;
222
        
223 81
        return $this;
224
        
225 3
    }
226
    
227
    /**
228
     * Force lib to use curl (default if available) or stream
229
     *
230
     * @param   bool    $mode    Use curl (true) or stream (false)
231
     *
232
     * @return  \Comodojo\Httprequest\Httprequest
233
     */
234 84
    final public function setCurl($mode = true) {
235
        
236 84
        $curl = filter_var($mode, FILTER_VALIDATE_BOOLEAN);
237
        
238 84
        if ( !function_exists("curl_init") OR !$curl ) $this->curl = false;
239 45
        else $this->curl = true;
240
        
241 84
        return $this;
242
        
243
    }
244
245
    /**
246
     * Set http authentication
247
     *
248
     * @param   string  $method Auth method (BASIC or NTLM)
249
     * @param   string  $user   Username to use
250
     * @param   string  $pass   User password
251
     *
252
     * @return  \Comodojo\Httprequest\Httprequest
253
     * 
254
     * @throws \Comodojo\Exception\HttpException
255
     */
256 9
    final public function setAuth($method, $user, $pass = null) {
257
258 9
        $method = strtoupper($method);
259
260 9
        if ( !in_array($method, $this->supported_auth_methods) ) {
261
262
            throw new HttpException("Unsupported authentication method");
263
264
        }
265
266 9
        $this->authenticationMethod = $method;
267
268 9
        if ( empty($user) ) {
269
270
            throw new HttpException("User name cannot be null");
271
272
        }
273
274 9
        $this->user = $user;
275 9
        $this->pass = $pass;
276
                
277 9
        return $this;
278
279
    }
280
281
    /**
282
     * Set user agent for request
283
     *
284
     * @param   string  $ua     User Agent
285
     *
286
     * @return  \Comodojo\Httprequest\Httprequest
287
     * 
288
     * @throws \Comodojo\Exception\HttpException
289
     */
290 9
    final public function setUserAgent($ua) {
291
292 9
        if ( empty($ua) ) throw new HttpException("Useragent cannot be null");
293
294 9
        $this->userAgent = $ua;
295
296 9
        return $this;
297
298
    }
299
300
    /**
301
     * Set connection timeout
302
     *
303
     * @param   int $sec    Timeout to wait for (in second)
304
     *
305
     * @return  \Comodojo\Httprequest\Httprequest
306
     */
307 9
    final public function setTimeout($sec) {
308
309 9
        $time = filter_var($sec, FILTER_VALIDATE_INT);
310
311 9
        $this->timeout = $time;
312
313 9
        return $this;
314
315
    }
316
317
    /**
318
     * Set http version (1.0/1.1)
319
     *
320
     * @param   string  $ver    1.0 or 1.1
321
     *
322
     * @return  \Comodojo\Httprequest\Httprequest
323
     */
324 3
    final public function setHttpVersion($ver) {
325
326 3
        if ( !in_array($ver, array("1.0", "1.1")) ) {
327
            
328
            $this->httpVersion = "NONE";
329
        
330
        } else {
331
332 3
            $this->httpVersion = $ver;
333
334
        }
335
        
336 3
        return $this;
337
338
    }
339
340
    /**
341
     * Set http content type
342
     *
343
     * @param   string  $type
344
     *
345
     * @return  \Comodojo\Httprequest\Httprequest
346
     * 
347
     * @throws  \Comodojo\Exception\HttpException
348
     */
349 9
    final public function setContentType($type) {
350
351 9
        if ( empty($type) ) throw new HttpException("Conte Type cannot be null");
352
353 9
        $this->contentType = $type;
354
355 9
        return $this;
356
357
    }
358
359
    /**
360
     * Set TCP port to connect to
361
     *
362
     * @param   integer $port   TCP port (default 80)
363
     *
364
     * @return  \Comodojo\Httprequest\Httprequest
365
     */
366 3
    final public function setPort($port) {
367
368 3
        $this->port = filter_var($port, FILTER_VALIDATE_INT, array(
369
            "options" => array(
370 3
                "min_range" => 1,
371 3
                "max_range" => 65535,
372 3
                "default" => 80 )
373 3
            )
374 3
        );
375
        
376 3
        return $this;
377
378
    }
379
380
    /**
381
     * Set HTTP method to use
382
     *
383
     * @param   string  $method  HTTP METHOD
384
     *
385
     * @return  \Comodojo\Httprequest\Httprequest
386
     * 
387
     * @throws \Comodojo\Exception\HttpException
388
     */
389 27
    final public function setHttpMethod($method) {
390
391 27
        $method = strtoupper($method);
392
393 27
        if ( !in_array($method, $this->supported_http_methods) ) {
394
395
            throw new HttpException("Unsupported HTTP method");
396
397
        }
398
399 27
        $this->method = $method;
400
401 27
        return $this;
402
403
    }
404
405
    /**
406
     * Set whether or not to ignore errors
407
     *
408
     * @param   boolean $ignore    Should stream ignore errors
409
     *
410
     * @return  \Comodojo\Httprequest\Httprequest
411
     */
412
    final public function setIgnoreErrors($ignore = true) {
413
414
        $this->ignore_errors = (bool)$ignore;
415
416
        return $this;
417
418
    }
419
420
    /**
421
     * Set HTTP method to use
422
     *
423
     * @param   string  $address    Proxy URL or IP address
424
     * @param   string  $user       (optional) User name for proy auth
425
     * @param   string  $pass       (optional) User password for proxy auth
426
     *
427
     * @return  \Comodojo\Httprequest\Httprequest
428
     * 
429
     * @throws \Comodojo\Exception\HttpException
430
     */
431 3
    final public function setProxy($address, $user = null, $pass = null) {
432
433 3
        $proxy = filter_var($address, FILTER_VALIDATE_URL);
434
435 3
        if ( $proxy == false ) throw new HttpException("Invalid proxy address or URL");
436
        
437 3
        $this->proxy = $proxy;
438
439 3
        if ( !is_null($user) AND !is_null($pass) ) {
440
441 3
            $this->proxy_auth = $user.':'.$pass;
442
443 3
        } else if ( !is_null($user) ) {
444
445
            $this->proxy_auth = $user;
446
447
        } else $this->proxy_auth = NULL; 
448
449 3
        return $this;
450
451
    }
452
453
    /**
454
     * Set header component
455
     *
456
     * @param   string  $header     Header name
457
     * @param   string  $value      Header content (optional)
458
     *
459
     * @return  \Comodojo\Httprequest\Httprequest
460
     */
461 27
    final public function setHeader($header, $value = NULL) {
462
463 27
        $this->headers[$header] = $value;
464
465 27
        return $this;
466
467
    }
468
469
    /**
470
     * Unset header component
471
     *
472
     * @param   string  $header     Header name
473
     *
474
     * @return  \Comodojo\Httprequest\Httprequest
475
     */
476
    final public function unsetHeader($header) {
477
478
        if ( array_key_exists($header, $this->headers) ) unset($this->headers[$header]);
479
480
        return $this;
481
482
    }
483
484
    /**
485
     * Get the whole headers array
486
     *
487
     * @return  array
488
     */
489 78
    final public function getHeaders() {
490
491 78
        return $this->headers;
492
493
    }
494
495
    /**
496
     * Get received headers
497
     *
498
     * @return  array
499
     */
500 24
    final public function getReceivedHeaders() {
501
502 24
        return $this->receivedHeaders;
503
504
    }
505
506
    /**
507
     * Get received headers
508
     *
509
     * @return  integer
510
     */
511 60
    final public function getHttpStatusCode() {
512
513 60
        return $this->receivedHttpStatus;
514
515
    }
516
517
    /**
518
     * Get transport channel (curl channel or stream context)
519
     *
520
     * @return  mixed
521
     */
522 6
    final public function getChannel() {
523
524 6
        return $this->ch;
525
526
    }
527
528
    /**
529
     * Init transport and send data to the remote host.
530
     * 
531
     * @return  string
532
     * 
533
     * @throws \Comodojo\Exception\HttpException
534
     */
535 30 View Code Duplication
    public function send($data = null) {
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...
536
        
537
        try {
538
539 30
            if ( $this->curl ) {
540
541 15
                $this->init_curl($data);
542
543 15
                $received = $this->send_curl();
544
545 15
            } else {
546
547 15
                $this->init_stream($data);
548
549 15
                $received = $this->send_stream();
550
551
            }
552
        
553
554 30
        } catch (HttpException $ioe) {
555
            
556
            throw $ioe;
557
558
        }
559
560 30
        return $received;
561
562
    }
563
564
    /**
565
     * Init transport and get remote content
566
     * 
567
     * @return  string
568
     * 
569
     * @throws \Comodojo\Exception\HttpException
570
     */
571 48 View Code Duplication
    public function get() {
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...
572
        
573
        try {
574
575 48
            if ( $this->curl ) {
576
577 24
                $this->init_curl(null);
578
579 24
                $received = $this->send_curl();
580
581 21
            } else {
582
583 24
                $this->init_stream(null);
584
585 24
                $received = $this->send_stream();
586
587
            }
588
589 48
        } catch (HttpException $ioe) {
590
            
591 6
            throw $ioe;
592
593
        }
594
595 42
        return $received;
596
597
    }
598
    
599
    /**
600
     * Reset the data channel for new request
601
     * 
602
     */
603
    final public function reset() {
604
605
        $this->address = null;
606
607
        $this->port = 80;
608
609
        $this->method = 'GET';
610
611
        $this->timeout = 30;
612
613
        $this->httpVersion = "1.0";
614
615
        $this->authenticationMethod = null;
616
617
        $this->user = null;
618
619
        $this->pass = null;
620
621
        $this->userAgent = 'Comodojo-Httprequest';
622
623
        $this->contentType = 'application/x-www-form-urlencoded';
624
625
        $this->headers = array(
626
            'Accept'            =>  'text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8',
627
            'Accept-Language'   =>  'en-us,en;q=0.5',
628
            'Accept-Encoding'   =>  'deflate',
629
            'Accept-Charset'    =>  'UTF-8;q=0.7,*;q=0.7'
630
        );
631
632
        $this->proxy = null;
633
634
        $this->proxy_auth = null;
635
636
        $this->receivedHeaders = array();
637
638
        $this->receivedHttpStatus = null;
639
640
        $this->stream_get_data = null;
641
        
642
        if ( $this->ch !== false ) $this->close_transport();
643
644
    }
645
    
646
    /**
647
     * Parse a single header
648
     *
649
     * @param   string  $header
650
     * @param   string  $value
651
     * 
652
     * @return  string
653
     */
654
    private function parseHeader($header, $value) {
0 ignored issues
show
Unused Code introduced by
This method is not used, and could be removed.
Loading history...
655
656
        if ( is_null($value) ) return $header;
657
658
        else return $header.': '.$value;
659
660
    }
661
662
    /**
663
     * Init the CURL channel
664
     *
665
     * @param   string  $data
666
     * 
667
     * @throws  \Comodojo\Exception\HttpException
668
     */
669 39
    private function init_curl($data) {
670
671 39
        $this->ch = curl_init();
672
            
673 39
        if ( $this->ch === false ) throw new HttpException("Cannot init data channel");
674
675 39
        switch ( $this->httpVersion ) {
676
677 39
            case '1.0':
678 39
                curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
679 39
                break;
680
681
            case '1.1':
682
                curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
683
                break;
684
685
            default:
686
                curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_NONE);
687
                break;
688
689 39
        }
690
691 39
        switch ( $this->authenticationMethod ) {
692
693 39 View Code Duplication
            case 'BASIC':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
694 3
                curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
695 3
                curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.":".$this->pass); 
696 3
                break;
697
698 36 View Code Duplication
            case 'DIGEST':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
699
                curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
700
                curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.":".$this->pass); 
701
                break;
702
703 36 View Code Duplication
            case 'SPNEGO':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
704
                curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_GSSNEGOTIATE);
705
                curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.":".$this->pass); 
706
                break;
707
708 36 View Code Duplication
            case 'NTLM':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
709
                curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
710
                curl_setopt($this->ch, CURLOPT_USERPWD, $this->user.":".$this->pass); 
711
                break;
712
713 39
        }
714
715 39
        if ( !is_null($this->proxy) ) {
716
717
            curl_setopt($this->ch, CURLOPT_PROXY, $this->proxy);
718
719
            if ( !is_null($this->proxy_auth) ) curl_setopt($this->ch, CURLOPT_PROXYUSERPWD, $this->proxy_auth);
720
721
        }
722
723 39
        switch ( $this->method ) {
724
            
725 39
            case 'GET':
726
727 27
                if ( empty($data) ) curl_setopt($this->ch, CURLOPT_URL, $this->address);
728
729 3
                else curl_setopt($this->ch, CURLOPT_URL, $this->address."?".((is_array($data) OR is_object($data)) ? http_build_query($data) : $data));
730
731 27
                break;
732
            
733 12 View Code Duplication
            case 'PUT':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
734
735 3
                curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, "PUT"); 
736
737 3
                if ( !empty($data) ) {
738
739 3
                    curl_setopt($this->ch, CURLOPT_POSTFIELDS, (is_array($data) OR is_object($data)) ? http_build_query($data) : $data);
740
741 3
                    $this->setHeader('Content-Type', $this->contentType);
742
743 3
                }
744
745 3
                curl_setopt($this->ch, CURLOPT_URL, $this->address);
746
747 3
                break;
748
            
749 9 View Code Duplication
            case 'POST':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
750
751 6
                curl_setopt($this->ch, CURLOPT_POST, true);
752
753 6
                if ( !empty($data) ) {
754
755 6
                    curl_setopt($this->ch, CURLOPT_POSTFIELDS, (is_array($data) OR is_object($data)) ? http_build_query($data) : $data);
756
757 6
                    $this->setHeader('Content-Type', $this->contentType);
758
759 6
                }
760
761 6
                curl_setopt($this->ch, CURLOPT_URL, $this->address);
762
763 6
                break;
764
            
765 3 View Code Duplication
            case 'DELETE':
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
766
767 3
                curl_setopt($this->ch, CURLOPT_CUSTOMREQUEST, "DELETE");
768
769 3
                if ( !empty($data) ) {
770
771 3
                    curl_setopt($this->ch, CURLOPT_POSTFIELDS, (is_array($data) OR is_object($data)) ? http_build_query($data) : $data);
772
773 3
                    $this->setHeader('Content-Type', $this->contentType);
774
775 3
                }
776
                
777 3
                curl_setopt($this->ch, CURLOPT_URL, $this->address);
778
779 3
                break;
780
781 39
        }
782
783 39
        if ( sizeof($this->headers) != 0 ) {
784
785 39
            $headers = array();
786
787 39
            foreach ( $this->getHeaders() as $header => $value ) {
788
                
789 39
                if ( is_null($value) ) array_push($headers, $header);
790
            
791 39
                else array_push($headers, $header.': '.$value);
792
793 39
            }
794
795 39
        } else $headers = array();
796
797 39
        curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, 1);
798 39
        curl_setopt($this->ch, CURLOPT_FOLLOWLOCATION, 1);
799 39
        curl_setopt($this->ch, CURLOPT_TIMEOUT, $this->timeout);
800 39
        curl_setopt($this->ch, CURLOPT_PORT, $this->port);
801 39
        curl_setopt($this->ch, CURLOPT_USERAGENT, $this->userAgent);
802 39
        curl_setopt($this->ch, CURLOPT_HTTPHEADER, $headers);
803 39
        curl_setopt($this->ch, CURLOPT_HEADER, 1);
804 39
        curl_setopt($this->ch, CURLOPT_ENCODING, "");
805
806
        //curl_setopt($this->ch, CURLOPT_VERBOSE, true);
807
808 39
    }
809
810
    /**
811
     * Init the STREAM channel
812
     *
813
     * @param   string  $data
814
     * 
815
     * @throws  \Comodojo\Exception\HttpException
816
     */
817 39
    private function init_stream($data) {
818
819 39
        if ( in_array($this->authenticationMethod, array("DIGEST", "SPNEGO", "NTLM")) ) throw new HttpException("Selected auth method not available in stream mode");
820
821
        $stream_options = array(
822
            'http'  =>  array(
823 39
                'method'            =>  $this->method,
824 39
                'protocol_version'  =>  $this->httpVersion == "NONE" ? "1.0" : $this->httpVersion,
825 39
                'user_agent'        =>  $this->userAgent,
826 39
                'timeout'           =>  $this->timeout,
827
                'header'            =>  array(
828
                    'Connection: close'
829 39
                )
830 39
            )
831 39
        );
832
833 39
        if ( !is_null($this->proxy) ) {
834
835
            $stream_options['http']['proxy'] = $this->proxy;
836
837
            if ( !is_null($this->proxy_auth) ) array_push($stream_options['http']['header'], 'Proxy-Authorization: Basic '.base64_encode($this->proxy_auth));
838
839
        }
840
841 39
        if ( $this->authenticationMethod == "BASIC" ) array_push($stream_options['http']['header'], 'Authorization: Basic  '.base64_encode($this->user.":".$this->pass));
842
        
843 39
        if ( $this->ignore_errors ) {
844
            $stream_options['http']['ignore_errors'] = true;
845
        }
846
847 39
        foreach ( $this->getHeaders() as $header => $value ) {
848
849 39
            if ( is_null($value) ) array_push($stream_options['http']['header'], $header);
850
            
851 39
            else array_push($stream_options['http']['header'], $header.': '.$value);
852
853 39
        }
854
855 39
        if ( !empty($data) ) {
856
857 15
            $data_query = (is_array($data) OR is_object($data)) ? http_build_query($data) : $data;
858
859 15
            if ( $this->method == "GET" ) {
860
861 3
                $this->stream_get_data = $data_query;
862
863 3
            } else {
864
865 12
                array_push($stream_options['http']['header'], 'Content-Type: '.$this->contentType);
866
867 12
                array_push($stream_options['http']['header'], 'Content-Length: '.strlen($data_query));
868
869 12
                $stream_options['http']['content'] = $data_query;
870
871
            }
872
            
873 15
        }
874
875 39
        $this->ch = stream_context_create($stream_options);
876
877 39
        if ( !$this->ch ) {
878
879
            throw new HttpException("Cannot init data channel");
880
881
        }
882
883 39
    }
884
885
    /**
886
     * Send data via CURL
887
     *
888
     * @return  string
889
     * 
890
     * @throws  \Comodojo\Exception\HttpException
891
     */
892 39
    private function send_curl() {
893
894 39
        $request = curl_exec($this->ch);
895
        
896 39
        if ( $request === false ) {
897
                
898 3
            throw new HttpException(curl_error($this->ch), curl_errno($this->ch));
899
900
        }
901
902 36
        $this->receivedHttpStatus = curl_getinfo($this->ch, CURLINFO_HTTP_CODE);
903
904 36
        $header_size = curl_getinfo($this->ch, CURLINFO_HEADER_SIZE);
905
906 36
        $headers = substr($request, 0, $header_size);
907
908 36
        $body = substr($request, $header_size);
909
910 36
        $this->receivedHeaders = self::tokenizeHeaders($headers);
911
912 36
        return $body;
913
914
    }
915
916
    /**
917
     * Send data via STREAM
918
     *
919
     * @return  string
920
     * 
921
     * @throws  \Comodojo\Exception\HttpException
922
     */
923 39
    private function send_stream() {
924
925 39
        $url = Url::createFromUrl($this->address);
926
927 39
        if ( $this->port != 80 ) $url->setPort($this->port);
928
929 39
        if ( !is_null($this->stream_get_data) ) $url->setQuery($this->stream_get_data);
930
931 39
        $host = $url;
932
933 39
        set_error_handler( 
934
935 3
            function($severity, $message, $file, $line) {
0 ignored issues
show
Unused Code introduced by
The parameter $file is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $line is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
936
937 3
                throw new HttpException($message);
938
939
            }
940
941 39
        );
942
943
        try {
944
        
945 39
            $received = file_get_contents($host, false, $this->ch);
946
947 39
        } catch (HttpException $he) {
948
949 3
            throw $he;
950
            
951
        }
952
953 36
        restore_error_handler();
954
        
955 36
        if ( $received === false ) {
956
                            
957
            throw new HttpException("Cannot read stream socket");
958
959
        }
960
        
961 36
        $this->receivedHeaders = self::tokenizeHeaders(implode("\r\n", $http_response_header));
962
963 36
        $content_encoding = array_key_exists('Content-Encoding', $this->receivedHeaders);
964
965 36
        list($version, $this->receivedHttpStatus, $msg) = explode(' ', $this->receivedHeaders[0], 3);
0 ignored issues
show
Unused Code introduced by
The assignment to $version is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
Unused Code introduced by
The assignment to $msg is unused. Consider omitting it like so list($first,,$third).

This checks looks for assignemnts to variables using the list(...) function, where not all assigned variables are subsequently used.

Consider the following code example.

<?php

function returnThreeValues() {
    return array('a', 'b', 'c');
}

list($a, $b, $c) = returnThreeValues();

print $a . " - " . $c;

Only the variables $a and $c are used. There was no need to assign $b.

Instead, the list call could have been.

list($a,, $c) = returnThreeValues();
Loading history...
966
967 36
        if ( $content_encoding === true AND strpos($this->receivedHeaders['Content-Encoding'], 'gzip') !== false ) {
968
969 3
            return gzinflate(substr($received, 10, -8));
970
971 33
        } else return $received;
972
973
    }
974
975
    /**
976
     * Tokenize received headers
977
     *
978
     * @param   string  $headers
979
     *
980
     * @return  array
981
     */
982 72
    private static function tokenizeHeaders($headers) {
983
984 72
        $return = array();
985
986 72
        $headers_array = explode("\r\n", $headers);
987
988 72
        foreach ( $headers_array as $header ) {
989
990 72
            if ( empty($header) ) continue;
991
992 72
            $header_components = explode(":", $header);
993
994 72
            if ( !isset($header_components[1]) OR @empty($header_components[1]) ) array_push($return, $header_components[0]);
995
996 72
            else $return[$header_components[0]] = $header_components[1];
997
998 72
        }
999
1000 72
        return $return;
1001
1002
    }
1003
1004
    /**
1005
     * Close transport layer
1006
     */
1007
    private function close_transport() {
1008
1009
        if ( $this->curl ) {
1010
1011
            curl_close($this->ch);
1012
1013
        }
1014
1015
    }
1016
1017
}
1018