Passed
Push — master ( c65e58...1194b0 )
by Oss
02:24
created

CurlAdapter::createCookieHeaderList()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 3

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 11
ccs 8
cts 8
cp 1
rs 9.4285
cc 3
eloc 7
nc 4
nop 1
crap 3
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\Cookie\Cookie;
11
use Brownie\HttpClient\Cookie\CookieList;
12
use Brownie\HttpClient\Header\Header;
13
use Brownie\HttpClient\Header\HeaderList;
14
use Brownie\HttpClient\Request;
15
use Brownie\HttpClient\Response;
16
use Brownie\HttpClient\Client;
17
use Brownie\HttpClient\Exception\ClientException;
18
19
/**
20
 * API(Adapter) for using CURL functions in HTTP requests.
21
 */
22
class CurlAdapter implements Client
23
{
24
25
    /**
26
     * API CURL functions.
27
     *
28
     * @var CurlAdaptee
29
     */
30
    private $adaptee;
31
32
    /**
33
     * Sets incoming data.
34
     *
35
     * @param CurlAdaptee       $adaptee        API CURL functions.
36
     */
37 7
    public function __construct(CurlAdaptee $adaptee)
38
    {
39 7
        $this->setAdaptee($adaptee);
40 7
    }
41
42
    /**
43
     * Sets API CURL functions wrapper.
44
     * Returns the current object.
45
     *
46
     * @param CurlAdaptee $adaptee
47
     *
48
     * @return self
49
     */
50 7
    private function setAdaptee(CurlAdaptee $adaptee)
51
    {
52 7
        $this->adaptee = $adaptee;
53 7
        return $this;
54
    }
55
56
    /**
57
     * Returns API CURL functions wrapper.
58
     *
59
     * @return CurlAdaptee
60
     */
61 7
    private function getAdaptee()
62
    {
63 7
        return $this->adaptee;
64
    }
65
66
    /**
67
     * Performs a network request.
68
     * Returns the response.
69
     *
70
     * @param Request       $request    HTTP request params.
71
     *
72
     * @throws ClientException
73
     *
74
     * @return Response
75
     */
76 7
    public function httpRequest(Request $request)
77
    {
78 7
        $curl = $this->getCurlClient($request);
79
80
        /**
81
         * Executes a network resource request.
82
         */
83 7
        $responseBody = $this->getAdaptee()->exec($curl);
84
85
        /**
86
         * Network error checking.
87
         */
88 7
        if ((0 != $this->getAdaptee()->errno($curl)) || !is_string($responseBody)) {
89 1
            throw new ClientException($this->getAdaptee()->error($curl));
90
        }
91
92 6
        $runtime = $this->getAdaptee()->getinfo($curl, CURLINFO_TOTAL_TIME);
93 6
        $httpCode = $this->getAdaptee()->getinfo($curl, CURLINFO_HTTP_CODE);
94 6
        $headerSize = $this->getAdaptee()->getinfo($curl, CURLINFO_HEADER_SIZE);
95
96 6
        $this->getAdaptee()->close($curl);
97
98
        /**
99
         * Gets the HTTP headers and the body separately.
100
         */
101 6
        $body = substr($responseBody, $headerSize);
102 6
        $httpHeadersString = substr($responseBody, 0, $headerSize);
103
104 6
        $response = new Response();
105
        return $response
106 6
            ->setBody($body)
107 6
            ->setHttpCode($httpCode)
108 6
            ->setRuntime($runtime)
109 6
            ->setHttpHeaderList(new HeaderList($httpHeadersString))
110 6
            ->setHttpCookieList(new CookieList($httpHeadersString));
111
    }
112
113
    /**
114
     * Creates and returns a CURL resource.
115
     *
116
     * @param Request       $request        HTTP request params.
117
     *
118
     * @return resource
119
     */
120 7
    private function getCurlClient(Request $request)
121
    {
122
123
        /**
124
         * Build URL.
125
         */
126 7
        $url = $this->getUrl($request);
127
128
        /**
129
         * Initializing CURL.
130
         */
131 7
        $curl = $this->getAdaptee()->init($url);
132
133
        /**
134
         * CURL setting.
135
         */
136 7
        $this->setBaseOpt($curl, $request, $url);
137
138
        /**
139
         * Configuring HTTP headers.
140
         */
141 7
        $this->setHedaers($curl, $request);
142
143 7
        return $curl;
144
    }
145
146
    /**
147
     * Generates and returns URL.
148
     *
149
     * @param Request   $request    HTTP request params.
150
     *
151
     * @return string
152
     */
153 7
    private function getUrl(Request $request)
154
    {
155 7
        $url = $request->getUrl();
156
157
        /**
158
         * Adds GET parameters.
159
         */
160 7
        $params = $request->getParams();
161 7
        if ((Request::HTTP_METHOD_GET == $request->getMethod()) && !empty($params)) {
162 6
            $url .= '?' . http_build_query($params);
163
        }
164
165 7
        return $url;
166
    }
167
168
    /**
169
     * Sets the basic options.
170
     *
171
     * @param resource  $curl       CURL resource.
172
     * @param Request   $request    HTTP request params.
173
     * @param string    $url        Request URL.
174
     */
175 7
    private function setBaseOpt($curl, Request $request, $url)
176
    {
177
        $this
178 7
            ->getAdaptee()
179 7
            ->setopt($curl, CURLOPT_CUSTOMREQUEST, $request->getMethod())
180 7
            ->setopt($curl, CURLOPT_TIMEOUT, $request->getTimeOut())
181 7
            ->setopt($curl, CURLOPT_NOPROGRESS, true)
182 7
            ->setopt($curl, CURLOPT_RETURNTRANSFER, true)
183 7
            ->setopt($curl, CURLOPT_URL, $url)
184 7
            ->setopt($curl, CURLOPT_HEADER, true);
185
186 7
        if ($this->isPostParams($request)) {
187
            $this
188 1
                ->getAdaptee()
189 1
                ->setopt($curl, CURLOPT_POST, true);
190 1
            $params = $request->getParams();
191 1
            if (!empty($params)) {
192 1
                $params = http_build_query($params);
193 1
                $request->setBody($params);
194
            }
195
        }
196
197
        $this
198 7
            ->getAdaptee()
199 7
            ->setopt($curl, CURLOPT_POSTFIELDS, $request->getBody());
200
201 7
        $this->triggerDisableSSLCertificateValidation($curl, $request);
202
203 7
        $this->triggerAuthentication($curl, $request);
204 7
    }
205
206
    /**
207
     * Returns the POST character of the data.
208
     *
209
     * @param Request   $request    HTTP request params.
210
     *
211
     * @return bool
212
     */
213 7
    private function isPostParams(Request $request)
214
    {
215 7
        return (Request::HTTP_METHOD_POST == $request->getMethod()) ||
216 7
            (Request::HTTP_METHOD_PUT == $request->getMethod());
217
    }
218
219
    /**
220
     * Controlling verification of SSL certificates.
221
     *
222
     * @param resource  $curl           CURL resource.
223
     * @param Request   $request        HTTP request params.
224
     */
225 7
    private function triggerDisableSSLCertificateValidation($curl, Request $request)
226
    {
227 7
        if ($request->isDisableSSLValidation()) {
228
            /**
229
             * Disable SSL validation.
230
             */
231
            $this
232 2
                ->getAdaptee()
233 2
                ->setopt($curl, CURLOPT_SSL_VERIFYPEER, false)
234 2
                ->setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
235
        }
236 7
    }
237
238
    /**
239
     * Controlling request authentication.
240
     *
241
     * @param resource  $curl           CURL resource.
242
     * @param Request   $request        HTTP request params.
243
     */
244 7
    private function triggerAuthentication($curl, Request $request)
245
    {
246 7
        $authentication = $request->getAuthentication();
247 7
        if (!empty($authentication)) {
248
            /**
249
             * Enable authentication.
250
             */
251
            $this
252 7
                ->getAdaptee()
253 7
                ->setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_ANY)
254 7
                ->setopt($curl, CURLOPT_USERPWD, $authentication);
255
        }
256 7
    }
257
258
    /**
259
     * Sets HTTP headers.
260
     *
261
     * @param resource  $curl       CURL resource.
262
     * @param Request   $request    HTTP request params.
263
     */
264 7
    private function setHedaers($curl, Request $request)
265
    {
266
        /**
267
         * Sets the basic set of HTTP headers.
268
         */
269 7
        $headers = $this->createBaseHeaderList($request);
270 7
        if (!$this->isPostParams($request)) {
271 6
            $headers[] = 'Content-Type: ' . $request->getBodyFormat() . '; charset=utf-8';
272
        }
273
274
        /**
275
         * Sets a custom set of HTTP headers.
276
         */
277 7
        $headers = array_merge($headers, $this->createCustomHeaderList($request));
278
279
        /**
280
         * Sets the HTTP cookie.
281
         */
282 7
        $headers = array_merge($headers, $this->createCookieHeaderList($request));
283
284 7
        $this->getAdaptee()->setopt($curl, CURLOPT_HTTPHEADER, $headers);
285 7
    }
286
287
    /**
288
     * Returns the basic set of HTTP headers.
289
     *
290
     * @param Request   $request    HTTP request params.
291
     *
292
     * @return array
293
     */
294 7
    private function createBaseHeaderList(Request $request)
295
    {
296
        return array(
297 7
            'Connection: close',
298 7
            'Accept-Ranges: bytes',
299 7
            'Content-Length: ' . strlen($request->getBody()),
300 7
            'Accept: ' . $request->getBodyFormat() . ',*/*',
301 7
            'User-Agent: ' . $this->getAdaptee()->getAgentString(),
302
        );
303
    }
304
305
    /**
306
     * Returns a custom set of HTTP headers.
307
     *
308
     * @param Request   $request    HTTP request params.
309
     *
310
     * @return array
311
     */
312 7
    private function createCustomHeaderList(Request $request)
313
    {
314 7
        $headers = array();
315 7
        foreach ($request->getHeaders() as $header) {
316 7
            $headers[] = $header->toString();
317
        }
318 7
        return $headers;
319
    }
320
321
    /**
322
     * Returns the HTTP cookies for the HTTP header.
323
     *
324
     * @param Request   $request    HTTP request params.
325
     *
326
     * @return array
327
     */
328 7
    private function createCookieHeaderList(Request $request)
329
    {
330 7
        $cookies = array();
331 7
        foreach ($request->getCookies() as $cookie) {
332 7
            $cookies[] = $cookie->toString();
333
        }
334 7
        $headers = array();
335 7
        if (!empty($cookies)) {
336 7
            $headers[] = 'Cookie: ' . implode('; ', $cookies);
337
        }
338 7
        return $headers;
339
    }
340
}
341