Skip to content

Commit e37a7bf

Browse files
committed
+ Partial request implementation
+ Partial response implementation + Partial uri implementation + Some tests
1 parent e02880b commit e37a7bf

File tree

11 files changed

+597
-24
lines changed

11 files changed

+597
-24
lines changed

LICENSE.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
Copyright (c) 2016 Jorge Matricali <jorgematricali@gmail.com>
1+
Copyright (c) 2017 Jorge Matricali <jorgematricali@gmail.com>
22

33
Permission is hereby granted, free of charge, to any person obtaining a copy
44
of this software and associated documentation files (the "Software"), to deal

README.md

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
1-
PSR Http Client
1+
PSR-7 HTTP Client (cURL)
22
================
33

4-
[PSR-7](http://www.php-fig.org/psr/psr-7/).
5-
64
Note that this is not a HTTP protocol implementation of its own. It is merely a
7-
wrapper of libcurl that implements PSR-7 HTTP message interface.
5+
wrapper of libcurl that implements [PSR-7](http://www.php-fig.org/psr/psr-7/) HTTP message interface.

src/Client.php

Lines changed: 108 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,26 +1,131 @@
11
<?php
2+
/*
3+
Copyright (c) 2017 Jorge Matricali <jorgematricali@gmail.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
22+
*/
223

324
namespace Matricali\Http;
425

526
use Psr\Http\Message\RequestInterface;
627
use Psr\Http\Message\ResponseInterface;
728

29+
use Matricali\Http\Client\Exception as ClientException;
30+
831
class Client
932
{
33+
const VERSION = '1.1';
34+
1035
protected $handle = null;
36+
protected $responseHeader = '';
37+
protected $responseHeaders = [];
1138

12-
public function sendRequest(RequestInterface $request): ResponseInterface
39+
public function __construct()
1340
{
14-
if ($this->handle === null) {
15-
$this->handle = curl_init();
41+
$this->handle = curl_init();
42+
43+
if (!is_resource($this->handle)) {
44+
throw new ClientException(curl_error($this->handle), 'curl');
1645
}
1746

47+
curl_setopt_array($this->handle, [
48+
CURLOPT_RETURNTRANSFER => true,
49+
CURLOPT_AUTOREFERER => true,
50+
CURLOPT_FOLLOWLOCATION => true,
51+
CURLOPT_MAXREDIRS => 20,
52+
CURLOPT_HEADER => false,
53+
CURLOPT_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
54+
CURLOPT_REDIR_PROTOCOLS => CURLPROTO_HTTP | CURLPROTO_HTTPS,
55+
CURLOPT_USERAGENT => 'jorge-matricali/php-http-client HTTP/' . self::VERSION . ' (libcurl)',
56+
CURLOPT_CONNECTTIMEOUT => 30,
57+
CURLOPT_TIMEOUT => 30,
58+
]);
59+
}
60+
61+
public function __destruct()
62+
{
63+
curl_close($this->handle);
64+
}
65+
66+
public function headerFunction($handler, $line)
67+
{
68+
$this->responseHeader .= $line;
69+
return strlen($line);
70+
}
71+
72+
public function __clone()
73+
{
74+
$client = new self;
75+
$client->handle = curl_copy_handle($this->handle);
76+
return $client;
77+
}
78+
79+
protected function parseHeaders($lines)
80+
{
81+
if (empty($lines)) {
82+
return [];
83+
}
84+
if (is_string($lines)) {
85+
$lines = array_filter(explode("\r\n", $lines));
86+
} elseif (!is_array($lines)) {
87+
return false;
88+
}
89+
$status = [];
90+
if (preg_match('%^HTTP/(\d(?:\.\d)?)\s+(\d{3})\s?+(.+)?$%i', $lines[0], $status)) {
91+
$this->status = array_shift($lines);
92+
$this->version = $lines[1];
93+
$this->statusCode = intval($lines[2]);
94+
$this->statusMessage = isset($lines[3]) ? $lines[3] : '';
95+
}
96+
97+
foreach ($lines as $field) {
98+
if (!is_array($field)) {
99+
$field = array_map('trim', explode(':', $field, 2));
100+
}
101+
if (count($field) == 2) {
102+
$this->responseHeaders[$field[0]] = $field[1];
103+
}
104+
}
105+
return $this->responseHeaders;
106+
}
107+
108+
public function sendRequest(RequestInterface $request): ResponseInterface
109+
{
110+
curl_setopt($this->handle, CURLOPT_URL, (string) $request->getUri());
111+
curl_setopt($this->handle, CURLOPT_HEADERFUNCTION, [$this, 'headerFunction']);
112+
18113
$ret = curl_exec($this->handle);
114+
115+
if ($errno = curl_errno($this->handle)) {
116+
throw new ClientException(curl_error($this->handle), $errno);
117+
}
118+
119+
$this->parseHeaders($this->responseHeader);
120+
121+
$response = new Response($ret, $this->statusCode, $this->responseHeaders);
122+
return $response;
19123
}
20124

21125
public function get($uri, $headers = []): ResponseInterface
22126
{
23127
$request = new Request('GET', $uri, $headers);
128+
print_r($request);
24129
return $this->sendRequest($request);
25130
}
26131
}

src/Client/Exception.php

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,25 @@
11
<?php
2+
/*
3+
Copyright (c) 2017 Jorge Matricali <jorgematricali@gmail.com>
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in
13+
all copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
21+
THE SOFTWARE.
22+
*/
223

324
namespace Matricali\Http\Client;
425

0 commit comments

Comments
 (0)