Completed
Push — master ( cf526e...c4e476 )
by Hiraku
02:24
created

HttpGetRequest::getURL()   A

Complexity

Conditions 4
Paths 8

Size

Total Lines 21
Code Lines 12

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 14
CRAP Score 4

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 21
ccs 14
cts 14
cp 1
rs 9.0534
cc 4
eloc 12
nc 8
nop 0
crap 4
1
<?php
2
/*
3
 * hirak/prestissimo
4
 * @author Hiraku NAKANO
5
 * @license MIT https://github.com/hirak/prestissimo
6
 */
7
namespace Hirak\Prestissimo\Aspects;
8
9
use Composer\IO;
10
use Composer\Composer;
11
use Composer\Config as CConfig;
12
use Composer\Downloader;
13
14
/**
15
 * Simple Container for http-get request
16
 */
17
class HttpGetRequest
18
{
19
    public $origin;
20
    public $scheme = 'http';
21
    public $host = 'example.com';
22
    public $port = 80;
23
    public $path = '/';
24
25
    public $query = array();
26
    public $headers = array();
27
28
    public $curlOpts = array();
29
30
    public $username = null;
31
    public $password = null;
32
33
    public $maybePublic = true;
34
    public $verbose = false;
35
36
    /**
37
     * normalize url and authentication info
38
     * @param string $origin domain text
39
     * @param string $url
40
     * @param IO\IOInterface $io
41
     */
42 23
    public function __construct($origin, $url, IO\IOInterface $io)
43
    {
44 23
        $this->origin = $origin;
45 23
        $this->importURL($url);
46
47 23
        if ($this->username && $this->password) {
48 3
            $io->setAuthentication($origin, $this->username, $this->password);
49 23
        } elseif ($io->hasAuthentication($origin)) {
50 1
            $auth = $io->getAuthentication($origin);
51 1
            $this->username = $auth['username'];
52 1
            $this->password = $auth['password'];
53 1
        }
54 23
    }
55
56
    /**
57
     * @param string $url
58
     */
59 23
    public function importURL($url)
60
    {
61 23
        $struct = parse_url($url);
62
        // @codeCoverageIgnoreStart
63
        if (! $struct) {
64
            throw new \InvalidArgumentException("$url is not valid URL");
65
        }
66
        // @codeCoverageIgnoreEnd
67
68 23
        $this->scheme = self::setOr($struct, 'scheme', $this->scheme);
69 23
        $this->host = self::setOr($struct, 'host', $this->host);
70 23
        $this->port = self::setOr($struct, 'port', null);
71 23
        $this->path = self::setOr($struct, 'path', '');
72 23
        $this->username = self::setOr($struct, 'user', null);
73 23
        $this->password = self::setOr($struct, 'pass', null);
74
75 23
        if (! empty($struct['query'])) {
76 6
            parse_str($struct['query'], $this->query);
77 6
        }
78 23
    }
79
80
81
    /**
82
     * @param string $key
83
     * @param string $default
84
     */
85 23
    private static function setOr(array $struct, $key, $default=null)
86
    {
87 23
        if (!empty($struct[$key])) {
88 23
            return $struct[$key];
89
        }
90
91 23
        return $default;
92
    }
93
94
    /**
95
     * process option for RemortFileSystem
96
     * @return void
97
     */
98 5
    public function processRFSOption(array $option)
99
    {
100
        // template method
101 5
    }
102
103 6
    public function getCurlOpts()
104
    {
105 6
        $curlOpts = $this->curlOpts + array(
106 6
            CURLOPT_HTTPGET => true,
107 6
            CURLOPT_FOLLOWLOCATION => true,
108 6
            CURLOPT_MAXREDIRS => 20,
109 6
            CURLOPT_ENCODING => 'gzip',
110 6
            CURLOPT_HTTPHEADER => $this->headers,
111 6
            CURLOPT_USERAGENT => $this->genUA(),
112 6
        );
113
114 6
        $curlOpts[CURLOPT_VERBOSE] = (bool)$this->verbose;
115
116 6
        if ($this->username && $this->password) {
117 1
            $curlOpts[CURLOPT_USERPWD] = "$this->username:$this->password";
118 1
        } else {
119 6
            unset($curlOpts[CURLOPT_USERPWD]);
120
        }
121
122 6
        $curlOpts[CURLOPT_URL] = $this->getUrl();
123
124 6
        return $curlOpts;
125
    }
126
127 9
    public function getURL()
128
    {
129 9
        if ($this->scheme) {
130 9
            $url = "$this->scheme://";
131 9
        } else {
132 1
            $url = '';
133
        }
134 9
        $url .= $this->host;
135
136 9
        if ($this->port) {
137 6
            $url .= ":$this->port";
138 6
        }
139
140 9
        $url .= $this->path;
141
142 9
        if ($this->query) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->query of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

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.

Loading history...
143 6
            $url .= '?' . http_build_query($this->query);
144 6
        }
145
146 9
        return $url;
147
    }
148
149 3
    public function promptAuth(HttpGetResponse $res, CConfig $config, IO\IOInterface $io)
150
    {
151 3
        $httpCode = $res->info['http_code'];
152
        // 404s are only handled for github
153 3
        if (404 === $httpCode) {
154 1
            return false;
155
        }
156
157
        // fail if the console is not interactive
158 2
        if (!$io->isInteractive()) {
159
            switch ($httpCode) {
160 2
                case 401:
161 1
                    $message = "The '{$this->getURL()}' URL required authentication.\nYou must be using the interactive console to authenticate";
162 1
                    break;
163 1
                case 403:
164 1
                    $message = "The '{$this->getURL()}' URL could not be accessed.";
165 1
                    break;
166
            }
167 2
            throw new Downloader\TransportException($message, $httpCode);
168
        }
169
170
        // fail if we already have auth
171
        if ($io->hasAuthentication($this->origin)) {
172
            throw new Downloader\TransportException("Invalid credentials for '{$this->getURL()}', aborting.", $httpCode);
173
        }
174
175
        $io->overwrite("    Authentication required (<info>$this->host</info>):");
176
        $username = $io->ask('      Username: ');
177
        $password = $io->askAndHideAnswer('      Password: ');
178
        $io->setAuthentication($this->origin, $username, $password);
179
        return true;
180
    }
181
182 6
    public static function genUA()
183
    {
184 6
        static $ua;
185 6
        if ($ua) {
186 6
            return $ua;
187
        }
188 1
        $phpVersion = defined('HHVM_VERSION') ? 'HHVM ' . HHVM_VERSION : 'PHP ' . PHP_VERSION;
189
190 1
        return $ua = sprintf(
191 1
            'Composer/%s (%s; %s; %s)',
192 1
            str_replace('@package_version@', 'source', Composer::VERSION),
193 1
            php_uname('s'),
194 1
            php_uname('r'),
195
            $phpVersion
196 1
        );
197
    }
198
}
199