Completed
Push — master ( 1194b0...9342ad )
by Oss
03:45
created

CurlAdapter::setDefaultOpt()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 10
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 1

Importance

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