Completed
Pull Request — master (#44)
by Hiraku
08:54 queued 06:28
created

HttpGetRequest::setSpecial()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

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