Completed
Pull Request — master (#54)
by Hiraku
06:18
created

HttpGetRequest::processRFSOption()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 2
CRAP Score 1

Importance

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