Completed
Pull Request — master (#60)
by Hiraku
02:22
created

HttpGetRequest::setOr()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 8
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 4
CRAP Score 2

Importance

Changes 2
Bugs 0 Features 0
Metric Value
c 2
b 0
f 0
dl 0
loc 8
ccs 4
cts 4
cp 1
rs 9.4285
cc 2
eloc 4
nc 2
nop 3
crap 2
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 = false;
34
    public $verbose = false;
35
36
    /** @var CConfig */
37
    protected $config;
38
39
    /**
40
     * normalize url and authentication info
41
     * @param string $origin domain text
42
     * @param string $url
43
     * @param IO\IOInterface $io
44
     */
45 25
    public function __construct($origin, $url, IO\IOInterface $io)
46
    {
47 25
        $this->origin = $origin;
48 25
        $this->importURL($url);
49
50 25
        if ($this->username && $this->password) {
51 3
            $io->setAuthentication($origin, $this->username, $this->password);
52 25
        } elseif ($io->hasAuthentication($origin)) {
53 1
            $auth = $io->getAuthentication($origin);
54 1
            $this->username = $auth['username'];
55 1
            $this->password = $auth['password'];
56 1
        }
57 25
    }
58
59
    /**
60
     * @param string $url
61
     */
62 25
    public function importURL($url)
63
    {
64 25
        $struct = parse_url($url);
65
        // @codeCoverageIgnoreStart
66
        if (! $struct) {
67
            throw new \InvalidArgumentException("$url is not valid URL");
68
        }
69
        // @codeCoverageIgnoreEnd
70
71 25
        $this->scheme = self::setOr($struct, 'scheme', $this->scheme);
72 25
        $this->host = self::setOr($struct, 'host', $this->host);
73 25
        $this->port = self::setOr($struct, 'port', null);
74 25
        $this->path = self::setOr($struct, 'path', '');
75 25
        $this->username = self::setOr($struct, 'user', null);
76 25
        $this->password = self::setOr($struct, 'pass', null);
77
78 25
        if (! empty($struct['query'])) {
79 8
            parse_str($struct['query'], $this->query);
80 8
        }
81 25
    }
82
83
84
    /**
85
     * @param string $key
86
     * @param string $default
87
     */
88 25
    private static function setOr(array $struct, $key, $default = null)
89
    {
90 25
        if (!empty($struct[$key])) {
91 25
            return $struct[$key];
92
        }
93
94 25
        return $default;
95
    }
96
97
    /**
98
     * process option for RemortFileSystem
99
     * @return void
100
     */
101 5
    public function processRFSOption(array $option)
102
    {
103
        // template method
104 5
    }
105
106 8
    public function getCurlOpts()
107
    {
108 8
        $curlOpts = $this->curlOpts + array(
109 8
            CURLOPT_HTTPGET => true,
110 8
            CURLOPT_FOLLOWLOCATION => true,
111 8
            CURLOPT_MAXREDIRS => 20,
112 8
            CURLOPT_ENCODING => 'gzip',
113 8
            CURLOPT_HTTPHEADER => $this->headers,
114 8
            CURLOPT_USERAGENT => $this->genUA(),
115 8
        );
116
117 8
        $curlOpts[CURLOPT_VERBOSE] = (bool)$this->verbose;
118
119 8
        if ($this->username && $this->password) {
120 1
            $curlOpts[CURLOPT_USERPWD] = "$this->username:$this->password";
121 1
        } else {
122 8
            unset($curlOpts[CURLOPT_USERPWD]);
123
        }
124
125 8
        $curlOpts[CURLOPT_URL] = $this->getUrl();
126
127 8
        return $curlOpts;
128
    }
129
130 11
    public function getURL()
131
    {
132 11
        if ($this->scheme) {
133 11
            $url = "$this->scheme://";
134 11
        } else {
135 1
            $url = '';
136
        }
137 11
        $url .= $this->host;
138
139 11
        if ($this->port) {
140 8
            $url .= ":$this->port";
141 8
        }
142
143 11
        $url .= $this->path;
144
145 11
        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...
146 8
            $url .= '?' . http_build_query($this->query);
147 8
        }
148
149 11
        return $url;
150
    }
151
152 3
    public function setConfig(CConfig $config)
153
    {
154 3
        $this->config = $config;
155 3
    }
156
157 3
    public function promptAuth(HttpGetResponse $res, IO\IOInterface $io)
158
    {
159 3
        $httpCode = $res->info['http_code'];
160
        // 404s are only handled for github
161 3
        if (404 === $httpCode) {
162 1
            return false;
163
        }
164
165
        // fail if the console is not interactive
166 2
        if (!$io->isInteractive()) {
167
            switch ($httpCode) {
168 2
                case 401:
169 1
                    $message = "The '{$this->getURL()}' URL required authentication.\nYou must be using the interactive console to authenticate";
170 1
                    throw new Downloader\TransportException($message, $httpCode);
171 1
                case 403:
172 1
                    $message = "The '{$this->getURL()}' URL could not be accessed.";
173 1
                    throw new Downloader\TransportException($message, $httpCode);
174
            }
175
        }
176
177
        // fail if we already have auth
178
        if ($io->hasAuthentication($this->origin)) {
179
            throw new Downloader\TransportException("Invalid credentials for '{$this->getURL()}', aborting.", $httpCode);
180
        }
181
182
        $io->overwrite("    Authentication required (<info>$this->host</info>):");
183
        $username = $io->ask('      Username: ');
184
        $password = $io->askAndHideAnswer('      Password: ');
185
        $io->setAuthentication($this->origin, $username, $password);
186
        return true;
187
    }
188
189 8
    public static function genUA()
190
    {
191 8
        static $ua;
192 8
        if ($ua) {
193 8
            return $ua;
194
        }
195 1
        $phpVersion = defined('HHVM_VERSION') ? 'HHVM ' . HHVM_VERSION : 'PHP ' . PHP_VERSION;
196
197 1
        return $ua = sprintf(
198 1
            'Composer/%s (%s; %s; %s)',
199 1
            str_replace('@package_version@', 'source', Composer::VERSION),
200 1
            php_uname('s'),
201 1
            php_uname('r'),
202
            $phpVersion
203 1
        );
204
    }
205
}
206