Passed
Branch master (6a7e64)
by Oss
02:13
created

CurlAdapter   A

Complexity

Total Complexity 17

Size/Duplication

Total Lines 239
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 239
ccs 72
cts 72
cp 1
rs 10
wmc 17

10 Methods

Rating   Name   Duplication   Size   Complexity  
B httpRequest() 0 37 3
B getCurlClient() 0 32 2
A getUrl() 0 13 2
A getAdaptee() 0 3 1
A __construct() 0 3 1
A setAdaptee() 0 4 1
A setBaseOpt() 0 14 1
A setHedaers() 0 14 2
A triggerAuthentication() 0 11 2
A triggerDisableSSLCertificateValidation() 0 10 2
1
<?php
2
/**
3
 * @category    Brownie/HttpClient
4
 * @author      Brownie <[email protected]>
5
 * @license     http://www.gnu.org/copyleft/lesser.html
6
 */
7
8
namespace Brownie\HttpClient\Client;
9
10
use Brownie\HttpClient\Request;
11
use Brownie\HttpClient\Response;
12
use Brownie\HttpClient\Client;
13
use Brownie\HttpClient\Exception\ClientException;
14
use Brownie\HttpClient\Headers;
15
16
/**
17
 * API(Adapter) for using CURL functions in HTTP requests.
18
 */
19
class CurlAdapter implements Client
20
{
21
22
    /**
23
     * API CURL functions.
24
     *
25
     * @var CurlAdaptee
26
     */
27
    private $adaptee;
28
29
    /**
30
     * Sets incoming data.
31
     *
32
     * @param CurlAdaptee       $adaptee        API CURL functions.
33
     */
34 6
    public function __construct(CurlAdaptee $adaptee)
35
    {
36 6
        $this->setAdaptee($adaptee);
37 6
    }
38
39
    /**
40
     * Sets API CURL functions wrapper.
41
     * Returns the current object.
42
     *
43
     * @param CurlAdaptee $adaptee
44
     *
45
     * @return self
46
     */
47 6
    private function setAdaptee(CurlAdaptee $adaptee)
48
    {
49 6
        $this->adaptee = $adaptee;
50 6
        return $this;
51
    }
52
53
    /**
54
     * Returns API CURL functions wrapper.
55
     *
56
     * @return CurlAdaptee
57
     */
58 6
    private function getAdaptee()
59
    {
60 6
        return $this->adaptee;
61
    }
62
63
    /**
64
     * Performs a network request.
65
     * Returns the response.
66
     *
67
     * @param Request       $request    HTTP request params.
68
     *
69
     * @throws ClientException
70
     *
71
     * @return Response
72
     */
73 6
    public function httpRequest(Request $request)
74
    {
75 6
        $curl = $this->getCurlClient($request);
76
77
        /**
78
         * Executes a network resource request.
79
         */
80 6
        $responseBody = $this->getAdaptee()->exec($curl);
81
82 6
        $httpCode = $this->getAdaptee()->getinfo($curl, CURLINFO_HTTP_CODE);
83
84
        /**
85
         * Network error checking.
86
         */
87 6
        if ((0 != $this->getAdaptee()->errno($curl)) || !is_string($responseBody)) {
88 1
            throw new ClientException($this->getAdaptee()->error($curl));
89
        }
90
91
        /**
92
         * Gets the execution time of the request.
93
         */
94 5
        $runtime = $this->getAdaptee()->getinfo($curl, CURLINFO_TOTAL_TIME);
95
96
        /**
97
         * Gets the HTTP headers and the body separately.
98
         */
99 5
        $headerSize = $this->getAdaptee()->getinfo($curl, CURLINFO_HEADER_SIZE);
100 5
        $body = substr($responseBody, $headerSize);
101
102 5
        $this->getAdaptee()->close($curl);
103
104 5
        $response = new Response();
105
        return $response
106 5
            ->setBody($body)
107 5
            ->setHttpCode($httpCode)
108 5
            ->setRuntime($runtime)
109 5
            ->setHttpHeaders(new Headers(substr($responseBody, 0, $headerSize)));
110
    }
111
112
    /**
113
     * Creates and returns a CURL resource.
114
     *
115
     * @param Request       $request        HTTP request params.
116
     *
117
     * @return resource
118
     */
119 6
    private function getCurlClient(Request $request)
120
    {
121
122
        /**
123
         * Build URL.
124
         */
125 6
        $url = $this->getUrl($request);
126
127
        /**
128
         * Initializing CURL.
129
         */
130 6
        $curl = $this->getAdaptee()->init($url);
131
132
        /**
133
         * Sets the request body.
134
         */
135 6
        $body = $request->getBody();
136 6
        if (!empty($body)) {
137 5
            $this->getAdaptee()->setopt($curl, CURLOPT_POSTFIELDS, $body);
138
        }
139
140
        /**
141
         * CURL setting.
142
         */
143 6
        $this->setBaseOpt($curl, $request, $url);
144
145
        /**
146
         * Configuring HTTP headers.
147
         */
148 6
        $this->setHedaers($curl, $request, $body);
149
150 6
        return $curl;
151
    }
152
153
    /**
154
     * Generates and returns URL.
155
     *
156
     * @param Request   $request    HTTP request params.
157
     *
158
     * @return string
159
     */
160 6
    private function getUrl(Request $request)
161
    {
162 6
        $url = $request->getUrl();
163
164
        /**
165
         * Adds GET parameters.
166
         */
167 6
        $params = $request->getParams();
168 6
        if (!empty($params)) {
169 6
            $url .= '?' . http_build_query($params);
170
        }
171
172 6
        return $url;
173
    }
174
175
    /**
176
     * Sets the basic options.
177
     *
178
     * @param resource  $curl       CURL resource.
179
     * @param Request   $request    HTTP request params.
180
     * @param string    $url        Request URL.
181
     */
182 6
    private function setBaseOpt($curl, Request $request, $url)
183
    {
184
        $this
185 6
            ->getAdaptee()
186 6
            ->setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getMethod())
187 6
            ->setopt($curl, CURLOPT_TIMEOUT, $request->getTimeOut())
188 6
            ->setopt($curl, CURLOPT_NOPROGRESS, true)
189 6
            ->setopt($curl, CURLOPT_RETURNTRANSFER, true)
190 6
            ->setopt($curl, CURLOPT_URL, $url)
191 6
            ->setopt($curl, CURLOPT_HEADER, true);
192
193 6
        $this->triggerDisableSSLCertificateValidation($curl, $request);
194
195 6
        $this->triggerAuthentication($curl, $request);
196 6
    }
197
198
    /**
199
     * Controlling verification of SSL certificates.
200
     *
201
     * @param resource  $curl           CURL resource.
202
     * @param Request   $request        HTTP request params.
203
     */
204 6
    private function triggerDisableSSLCertificateValidation($curl, Request $request)
205
    {
206 6
        if ($request->isDisableSSLValidation()) {
207
            /**
208
             * Disable SSL validation.
209
             */
210
            $this
211 2
                ->getAdaptee()
212 2
                ->setopt($curl, CURLOPT_SSL_VERIFYPEER, false)
213 2
                ->setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
214
        }
215 6
    }
216
217
    /**
218
     * Controlling request authentication.
219
     *
220
     * @param resource  $curl           CURL resource.
221
     * @param Request   $request        HTTP request params.
222
     */
223 6
    private function triggerAuthentication($curl, Request $request)
224
    {
225 6
        $authentication = $request->getAuthentication();
226 6
        if (!empty($authentication)) {
227
            /**
228
             * Enable authentication.
229
             */
230
            $this
231 6
                ->getAdaptee()
232 6
                ->setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY)
233 6
                ->setopt($curl, CURLOPT_USERPWD, $authentication);
234
        }
235 6
    }
236
237
    /**
238
     * Sets HTTP headers.
239
     *
240
     * @param resource  $curl       CURL resource.
241
     * @param Request   $request    HTTP request params.
242
     * @param string    $body       The body of the request.
243
     */
244 6
    private function setHedaers($curl, Request $request, $body)
245
    {
246
        $headers = array(
247 6
            'Connection: close',
248 6
            'Accept-Ranges: bytes',
249 6
            'Content-Length: ' . strlen($body),
250 6
            'Accept: ' . $request->getBodyFormat() . ',*/*',
251 6
            'Content-Type: ' . $request->getBodyFormat() . '; charset=utf-8',
252 6
            'User-Agent: ' . $this->getAdaptee()->getAgentString(),
253
        );
254 6
        foreach ($request->getHeaders() as $name => $value) {
255 6
            $headers[] = $name . ': ' . $value;
256
        }
257 6
        $this->getAdaptee()->setopt($curl, CURLOPT_HTTPHEADER, $headers);
258 6
    }
259
}
260