Passed
Push — master ( 9342ad...ee9015 )
by Oss
03:08
created

CurlAdapter::isPostParams()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 3
CRAP Score 2

Importance

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