Skip to content

Commit 3e15a8a

Browse files
authored
Merge pull request #12 from kodedphp/psr-18
2 parents fe43bea + 05eaa5c commit 3e15a8a

38 files changed

+800
-311
lines changed

.gitattributes

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
*.php diff=php
22

3-
/build export-ignore
4-
/Tests export-ignore
5-
/vendor export-ignore
6-
/.gitattributes export-ignore
7-
/.gitignore export-ignore
8-
/.env export-ignore
9-
/phpunit.xml export-ignore
10-
/composer.lock export-ignore
11-
/*.yml export-ignore
3+
/build export-ignore
4+
/Tests export-ignore
5+
/vendor export-ignore
6+
/diagrams export-ignore
7+
/.gitattributes export-ignore
8+
/.gitignore export-ignore
9+
/.env export-ignore
10+
/phpunit.xml.dist export-ignore
11+
/composer.lock export-ignore
12+
/*.yml export-ignore

.gitignore

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,3 @@ vendor
44
.idea
55
.tmp
66
composer.lock
7-
*.yml
8-
!.travis.yml

.scrutinizer.yml

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
build:
2+
nodes:
3+
analysis:
4+
tests:
5+
stop_on_failure: true
6+
override:
7+
- php-scrutinizer-run
8+
environment:
9+
php:
10+
version: '7.2'
11+
dependencies:
12+
override:
13+
- composer install --no-interaction --prefer-source
14+
15+
filter:
16+
excluded_paths:
17+
- 'Tests/'
18+
- 'vendor/'
19+
- 'diagrams/'
20+
- 'build/'
21+
22+
tools:
23+
php_analyzer: true
24+
external_code_coverage: true

.travis.yml

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,15 @@
11
language: php
22

33
php:
4-
- 7.1
54
- 7.2
65
- 7.3
6+
- 7.4
7+
- nightly
78

89
matrix:
910
fast_finish: true
11+
allow_failures:
12+
- php: nightly
1013

1114
install:
1215
- composer update -o --no-interaction --prefer-stable --ignore-platform-reqs
@@ -15,7 +18,7 @@ script:
1518
- vendor/bin/phpunit --coverage-clover build/coverage/clover.xml
1619

1720
after_success:
18-
- travis_retry vendor/bin/codacycoverage clover build/coverage/clover.xml
21+
- travis_retry vendor/bin/ocular code-coverage:upload --format=php-clover build/coverage/clover.xml
1922

2023
sudo: false
2124

AcceptHeaderNegotiator.php

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -13,16 +13,14 @@
1313
namespace Koded\Http;
1414

1515
/**
16-
*
17-
*
1816
* Content negotiation module.
1917
*
20-
* Supported access headers:
18+
* Supported HTTP/1.1 Accept headers:
2119
*
22-
* Access
23-
* Access-Language
24-
* Access-Charset
25-
* Access-Encoding
20+
* Accept
21+
* Accept-Language
22+
* Accept-Charset
23+
* Accept-Encoding
2624
*
2725
* @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Content_negotiation
2826
*/
@@ -59,7 +57,8 @@ public function match(string $accepts): AcceptHeader
5957
* The consuming clients should handle this according to
6058
* their internal logic. This is much better then throwing
6159
* exceptions which must be handled in every place where
62-
* match() is called. The client may issue a 406 status code.
60+
* match() is called. For example, the client may issue a
61+
* 406 status code and be done with it.
6362
*/
6463
$types[] = new class('*;q=0') extends AcceptHeader {};
6564
}
@@ -101,32 +100,34 @@ public function __construct(string $header)
101100
$type = array_shift($bits);
102101

103102
if (!empty($type) && !preg_match('~^(\*|[a-z0-9._]+)([/|_-])?(\*|[a-z0-9.\-_+]+)?$~i', $type, $matches)) {
104-
throw new InvalidArgumentException(sprintf('"%s" is not a valid Access header', $header), StatusCode::NOT_ACCEPTABLE);
103+
throw new InvalidArgumentException(sprintf('"%s" is not a valid Access header', $header),
104+
StatusCode::NOT_ACCEPTABLE);
105105
}
106106

107107
$this->separator = $matches[2] ?? '/';
108108
[$type, $subtype] = explode($this->separator, $type, 2) + [1 => '*'];
109109

110110
if ('*' === $type && '*' !== $subtype) {
111111
// @see https://tools.ietf.org/html/rfc7231#section-5.3.2
112-
throw new InvalidArgumentException(sprintf('"%s" is not a valid Access header', $header), StatusCode::NOT_ACCEPTABLE);
112+
throw new InvalidArgumentException(sprintf('"%s" is not a valid Access header', $header),
113+
StatusCode::NOT_ACCEPTABLE);
113114
}
114115

115116
// @see https://tools.ietf.org/html/rfc7540#section-8.1.2
116117
$this->type = strtolower($type);
117118

118119
/* Uses a simple heuristic to check if subtype is part of
119120
* some obscure media type like "vnd.api-v1+json".
121+
*
122+
* NOTE: It is a waste of time to negotiate on the basis
123+
* of obscure parameters while using a meaningless media
124+
* type like "vnd.whatever". But the web world is a big mess
125+
* and this module can handle the Dunning-Kruger effect.
120126
*/
121127
$this->subtype = explode('+', $subtype)[1] ?? $subtype;
122128
$this->catchAll = '*' === $this->type && '*' === $this->subtype;
123129

124130
parse_str(join('&', $bits), $this->params);
125-
/* NOTE: It is a waste of time to negotiate on the basis
126-
* of obscure parameters while using a meaningless media
127-
* type like "vnd.whatever". But the IT world is a big
128-
* mess for now and this module supports ignorant devs.
129-
*/
130131
$this->quality = (float)($this->params['q'] ?? 1);
131132
unset($this->params['q']);
132133
}
@@ -138,16 +139,10 @@ public function __toString(): string
138139
}
139140

140141

141-
public function quality(): float
142-
{
143-
return $this->quality;
144-
}
145-
146-
147142
public function value(): string
148143
{
149144
// The header is explicitly rejected
150-
if (0.0 === $this->quality()) {
145+
if (0.0 === $this->quality) {
151146
return '';
152147
}
153148

@@ -160,6 +155,12 @@ public function value(): string
160155
}
161156

162157

158+
public function quality(): float
159+
{
160+
return $this->quality;
161+
}
162+
163+
163164
public function weight(): float
164165
{
165166
return $this->weight;
@@ -168,15 +169,16 @@ public function weight(): float
168169
/**
169170
* @internal
170171
*
171-
* This method finds the best match from the accept header,
172-
* including all the stupidity that may be passed by the
173-
* ignorant developers who do not follow RFC standards.
174-
*
175172
* @param AcceptHeader $accept The accept header part
176173
* @param AcceptHeader[] $matches Matched types
177174
*
178175
* @return bool TRUE if the accept header part is a match
179176
* against the supported (this) header part
177+
*
178+
* This method finds the best match for the Accept header,
179+
* including all the nonsense that may be passed by the
180+
* developers who do not follow RFC standards.
181+
*
180182
*/
181183
public function matches(AcceptHeader $accept, array &$matches = null): bool
182184
{
@@ -193,18 +195,21 @@ public function matches(AcceptHeader $accept, array &$matches = null): bool
193195
$accept->type = $this->type;
194196
$accept->subtype = $this->subtype;
195197
$matches[] = $accept;
198+
196199
return true;
197200
}
198201

199202
// Explicitly denied
200203
if (0.0 === $this->quality) {
201204
$matches[] = clone $this;
205+
202206
return true;
203207
}
204208

205209
// Explicitly denied
206210
if (0.0 === $accept->quality) {
207211
$matches[] = $accept;
212+
208213
return true;
209214
}
210215

CallableStream.php

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,6 @@ class CallableStream implements StreamInterface
3131
/** @var bool If callable is Generator instance */
3232
private $isGenerator = false;
3333

34-
/**
35-
* CallableStream constructor.
36-
*
37-
* @param callable $callable
38-
*
39-
* @throws \ReflectionException
40-
*/
4134
public function __construct(callable $callable)
4235
{
4336
$this->callable = $callable;
@@ -101,15 +94,15 @@ public function write($string): int
10194

10295
public function read($length): string
10396
{
104-
$contents = '';
97+
$content = '';
10598

10699
if (null === $this->callable) {
107-
return $contents;
100+
return $content;
108101
}
109102

110103
try {
111104
foreach ($this->reader($length) as $chunk) {
112-
$contents .= $chunk;
105+
$content .= $chunk;
113106
$this->position += mb_strlen($chunk);
114107
}
115108
} catch (Exception $e) {
@@ -118,7 +111,7 @@ public function read($length): string
118111
$this->callable = null;
119112
}
120113

121-
return $contents;
114+
return $content;
122115
}
123116

124117
public function getContents(): string

Client/ClientFactory.php

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,6 @@
1818

1919
class ClientFactory
2020
{
21-
2221
const CURL = 0;
2322
const PHP = 1;
2423

@@ -59,6 +58,11 @@ public function head($uri, array $headers = []): HttpRequestClient
5958
return $this->create(Request::HEAD, $uri, null, $headers)->maxRedirects(0);
6059
}
6160

61+
public function psr18(): HttpRequestClient
62+
{
63+
return $this->create(Request::HEAD, '');
64+
}
65+
6266
protected function create(string $method, $uri, $body = null, array $headers = []): HttpRequestClient
6367
{
6468
switch ($this->clientType) {
@@ -72,4 +76,4 @@ protected function create(string $method, $uri, $body = null, array $headers = [
7276
throw new InvalidArgumentException("{$this->clientType} is not a valid HTTP client");
7377
}
7478
}
75-
}
79+
}

0 commit comments

Comments
 (0)