Skip to content

Commit a7b2f66

Browse files
authored
tls internal and closes #14 php 8 required in composer json (#15)
* tls internal and closes #14 php 8 required in composer json * phpstan * code sniffer fixes * codesniffer
1 parent 5fb4a46 commit a7b2f66

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

71 files changed

+799
-659
lines changed

.github/workflows/ci_cd.yml

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,8 +90,10 @@ jobs:
9090
run: |
9191
docker network create -d bridge caddy-network
9292
docker run --entrypoint caddy --name caddy -d --network="caddy-network" --hostname=caddy -v "$(pwd)/docker/caddy/autosave.json:/config/caddy/autosave.json" -v "$(pwd)/docker/caddy/files:/var/files" -p 80:80 -p 2019:2019 docker.pkg.github.com/mattvb91/caddy-php/caddy:head run --resume
93-
docker run -v $(pwd):/app composer composer install
94-
docker run --network="caddy-network" -e XDEBUG_MODE=coverage -v $(pwd):/app docker.pkg.github.com/mattvb91/${{ env.REPO_NAME }}/composer:head php ./vendor/bin/phpunit --testdox --coverage-clover=coverage.xml
93+
docker run -v $(pwd):/app docker.pkg.github.com/mattvb91/${{ env.REPO_NAME }}/composer:head composer install
94+
docker run -v $(pwd):/app docker.pkg.github.com/mattvb91/${{ env.REPO_NAME }}/composer:head composer phpstan
95+
docker run -v $(pwd):/app docker.pkg.github.com/mattvb91/${{ env.REPO_NAME }}/composer:head composer codesniffer
96+
docker run --network="caddy-network" -e XDEBUG_MODE=coverage -v $(pwd):/app docker.pkg.github.com/mattvb91/${{ env.REPO_NAME }}/composer:head composer phpunit
9597
env:
9698
REPO_NAME: ${{ github.event.repository.name }}
9799
- uses: codecov/[email protected]

codesniffer.xml

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?xml version="1.0" ?>
2+
<ruleset name="PHP-Caddy">
3+
<description>PSR-12 with array indenting</description>
4+
<rule ref="PSR12"/>
5+
<rule ref="Generic.Arrays.ArrayIndent">
6+
<exclude name="Generic.Arrays.ArrayIndent.CloseBraceNotNewLine"/>
7+
</rule>
8+
</ruleset>

composer.json

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,12 @@
33
"description": "Control your Caddy instance through PHP",
44
"type": "package",
55
"license": "MIT",
6+
"scripts": {
7+
"phpunit": "phpunit --testdox --coverage-clover=coverage.xml",
8+
"phpstan": "phpstan analyse",
9+
"codesniffer": "phpcs ./src ./tests/**/*.php --standard=./codesniffer.xml -p",
10+
"codefixer": "phpcbf ./src ./tests/**/*.php --standard=./codesniffer.xml"
11+
},
612
"autoload": {
713
"psr-4": {
814
"mattvb91\\CaddyPhp\\": "src/"
@@ -17,10 +23,13 @@
1723
}
1824
},
1925
"require": {
26+
"php": "^8.1",
2027
"guzzlehttp/guzzle": "^7.0"
2128
},
2229
"require-dev": {
2330
"phpunit/phpunit": "^9.5",
24-
"dms/phpunit-arraysubset-asserts": "^0.4.0"
31+
"dms/phpunit-arraysubset-asserts": "^0.4.0",
32+
"phpstan/phpstan": "^1.10",
33+
"squizlabs/php_codesniffer": "^3.7"
2534
}
2635
}

docker/composer/Dockerfile

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
FROM composer:2.3
1+
FROM composer:2.6.5
22

3-
RUN apk --update --no-cache add autoconf g++ make \
4-
&& pecl install -f xdebug-3.1.4 \
3+
RUN apk --update --no-cache add autoconf g++ make linux-headers \
4+
&& pecl install -f xdebug-3.2.2 \
55
&& docker-php-ext-enable xdebug \
6-
&& apk del --purge autoconf g++ make
6+
&& apk del --purge autoconf g++ make linux-headers
77

88

99
EXPOSE 9000

phpstan.neon

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
parameters:
2+
level: 9
3+
paths:
4+
- src
5+
excludePaths:
6+
- vendor
7+
- tests

src/Caddy.php

Lines changed: 91 additions & 71 deletions
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,12 @@
44

55
use GuzzleHttp\Client;
66
use GuzzleHttp\Exception\ClientException;
7+
use GuzzleHttp\Exception\GuzzleException;
78
use mattvb91\CaddyPhp\Config\Admin;
9+
use mattvb91\CaddyPhp\Config\Apps\Http\Server\Routes\Match\Host;
810
use mattvb91\CaddyPhp\Config\Logging;
911
use mattvb91\CaddyPhp\Exceptions\CaddyClientException;
10-
use mattvb91\caddyPhp\Interfaces\App;
12+
use mattvb91\CaddyPhp\Interfaces\App;
1113
use mattvb91\CaddyPhp\Interfaces\Arrayable;
1214

1315
class Caddy implements Arrayable
@@ -22,54 +24,57 @@ class Caddy implements Arrayable
2224
*
2325
* We need to build that path once based on the config and then cache it here. The format is
2426
* [ host_identifier => ['path' => '/anything', 'host' => &$host]
27+
* @var array<string, array{
28+
* path: string,
29+
* host: Host
30+
* }>
2531
*/
26-
private array $_hostsCache = [];
32+
private array $hostsCache = [];
2733

28-
private Client $_client;
34+
private Client $client;
2935

30-
private Admin $_admin;
36+
private Admin $admin;
3137

32-
private ?Logging $_logging;
38+
private ?Logging $logging;
3339

3440
/** @var App[] */
35-
private array $_apps;
41+
private array $apps = [];
3642

37-
private string $_hostname;
43+
private string $hostname;
3844

39-
private string $_cacheHostnameHeader;
45+
private string $cacheHostnameHeader;
4046

4147
public function __construct(
42-
?string $hostname = 'caddy',
43-
?Admin $admin = new Admin(),
44-
?Client $client = null,
45-
?string $cacheHostnameHeader = 'localhost')
46-
{
48+
string $hostname = 'caddy',
49+
Admin $admin = new Admin(),
50+
Client $client = null,
51+
string $cacheHostnameHeader = 'localhost'
52+
) {
4753
$this->setAdmin($admin);
48-
49-
$this->_hostname = $hostname;
50-
$this->_cacheHostnameHeader = $cacheHostnameHeader;
51-
52-
$this->_client = $client ?? new Client([
53-
'base_uri' => $hostname . $this->getAdmin()->getListen() . '/config',
54-
'headers' => [
55-
'Content-Type' => 'application/json',
56-
],
57-
]
58-
);
54+
$this->hostname = $hostname;
55+
$this->cacheHostnameHeader = $cacheHostnameHeader;
56+
57+
$this->client = $client ?? new Client([
58+
'base_uri' => $hostname . $this->getAdmin()->getListen() . '/config',
59+
'headers' => [
60+
'Content-Type' => 'application/json',
61+
],
62+
]);
5963
}
6064

6165
/**
6266
* If you are managing your hosts from an external source (for example db) and not directly in
63-
* your config you should sync your hosts from the caddy config before making any changes for example trying to remove
64-
* hosts
67+
* your config you should sync your hosts from the caddy config before
68+
* making any changes for example trying to remove hosts
6569
*/
66-
public function syncHosts(string $hostIdentifier)
70+
public function syncHosts(string $hostIdentifier): void
6771
{
6872
$this->buildHostsCache($hostIdentifier);
6973

70-
$hosts = json_decode($this->_client->get($this->_hostsCache[$hostIdentifier]['path'])->getBody(), true);
74+
/** @var string[] $hosts */
75+
$hosts = json_decode($this->client->get($this->hostsCache[$hostIdentifier]['path'])->getBody(), true);
7176

72-
$this->_hostsCache[$hostIdentifier]['host']->setHosts($hosts);
77+
$this->hostsCache[$hostIdentifier]['host']->setHosts($hosts);
7378
}
7479

7580
/**
@@ -79,10 +84,12 @@ public function addHostname(string $hostIdentifier, string $hostname): bool
7984
{
8085
$this->buildHostsCache($hostIdentifier);
8186

82-
if ($this->_client->put($this->_hostsCache[$hostIdentifier]['path'] . '/0', [
87+
if (
88+
$this->client->put($this->hostsCache[$hostIdentifier]['path'] . '/0', [
8389
'json' => $hostname,
84-
])->getStatusCode() === 200) {
85-
$this->_hostsCache[$hostIdentifier]['host']->addHost($hostname);
90+
])->getStatusCode() === 200
91+
) {
92+
$this->hostsCache[$hostIdentifier]['host']->addHost($hostname);
8693
return true;
8794
}
8895

@@ -96,13 +103,15 @@ public function removeHostname(string $hostIdentifier, string $hostname): bool
96103
{
97104
$this->buildHostsCache($hostIdentifier);
98105

99-
$path = $this->_hostsCache[$hostIdentifier]['path'];
100-
$path = $path . '/' . array_search($hostname, $this->_hostsCache[$hostIdentifier]['host']->getHosts());
106+
$path = $this->hostsCache[$hostIdentifier]['path'];
107+
$path = $path . '/' . array_search($hostname, $this->hostsCache[$hostIdentifier]['host']->getHosts());
101108

102-
if ($this->_client->delete($path, [
109+
if (
110+
$this->client->delete($path, [
103111
'json' => $hostname,
104-
])->getStatusCode() === 200) {
105-
$this->_hostsCache[$hostIdentifier]['host']->syncRemoveHost($hostname);
112+
])->getStatusCode() === 200
113+
) {
114+
$this->hostsCache[$hostIdentifier]['host']->syncRemoveHost($hostname);
106115
return true;
107116
}
108117

@@ -114,25 +123,31 @@ public function removeHostname(string $hostIdentifier, string $hostname): bool
114123
*
115124
* TODO we should be able to build our $caddy object back up from this.
116125
* So instead of toArray we should be able to do fromArray() or something
126+
*
127+
* @throws \JsonException|\GuzzleHttp\Exception\GuzzleException
117128
*/
118129
public function getRemoteConfig(): object
119130
{
120-
return json_decode($this->_client->get('/config')->getBody(), false, 512, JSON_THROW_ON_ERROR);
131+
/** @var object */
132+
return json_decode($this->client->get('/config')->getBody(), false, 512, JSON_THROW_ON_ERROR);
121133
}
122134

123135
/**
124136
* This is responsible for flushing the individual caches of items on the caddy server.
137+
*
138+
* @param string[] $surrogates
139+
* @throws GuzzleException
125140
*/
126141
public function flushSurrogates(array $surrogates): bool
127142
{
128143
//TODO this is missing the fact that you could customize your cache paths.
129144

130-
return $this->_client->request('PURGE', 'http://' . $this->_hostname . '/cache/souin', [
131-
'headers' => [
132-
'Surrogate-Key' => implode(', ', $surrogates),
133-
'Host' => $this->_cacheHostnameHeader,
134-
],
135-
])->getStatusCode() === 204;
145+
return $this->client->request('PURGE', 'http://' . $this->hostname . '/cache/souin', [
146+
'headers' => [
147+
'Surrogate-Key' => implode(', ', $surrogates),
148+
'Host' => $this->cacheHostnameHeader,
149+
],
150+
])->getStatusCode() === 204;
136151
}
137152

138153
/**
@@ -142,11 +157,13 @@ public function flushSurrogates(array $surrogates): bool
142157
public function load(): bool
143158
{
144159
try {
145-
return $this->_client->post('/load', [
146-
'json' => $this->toArray(),
147-
])->getStatusCode() === 200;
160+
return $this->client->post('/load', [
161+
'json' => $this->toArray(),
162+
])->getStatusCode() === 200;
148163
} catch (ClientException $e) {
149-
throw new CaddyClientException($e->getResponse()->getBody() . PHP_EOL . json_encode($this->toArray(), JSON_PRETTY_PRINT));
164+
throw new CaddyClientException(
165+
$e->getResponse()->getBody() . PHP_EOL . json_encode($this->toArray(), JSON_PRETTY_PRINT)
166+
);
150167
}
151168
}
152169

@@ -155,37 +172,35 @@ public function load(): bool
155172
*/
156173
public function getClient(): Client
157174
{
158-
return $this->_client;
175+
return $this->client;
159176
}
160177

161-
public function getAdmin(): ?Admin
178+
public function getAdmin(): Admin
162179
{
163-
return $this->_admin;
180+
return $this->admin;
164181
}
165182

166183
protected function setAdmin(Admin $admin): static
167184
{
168-
$this->_admin = $admin;
185+
$this->admin = $admin;
169186

170187
return $this;
171188
}
172189

173-
public function setLogging(Logging $logging)
190+
public function setLogging(Logging $logging): static
174191
{
175-
$this->_logging = $logging;
192+
$this->logging = $logging;
176193

177194
return $this;
178195
}
179196

180197
public function addApp(App $app): static
181198
{
182-
$namespace = strtolower(substr(strrchr(get_class($app), '\\'), 1));
199+
/** @var string $name */
200+
$name = strrchr(get_class($app), '\\');
201+
$namespace = strtolower(substr($name, 1));
183202

184-
if (!isset($this->_apps)) {
185-
$this->_apps = [$namespace => $app];
186-
} else {
187-
$this->_apps[$namespace] = $app;
188-
}
203+
$this->apps[$namespace] = $app;
189204

190205
return $this;
191206
}
@@ -194,34 +209,39 @@ public function toArray(): array
194209
{
195210
$config = [];
196211

197-
if (isset($this->_admin)) {
198-
$config['admin'] = $this->_admin->toArray();
212+
if (isset($this->admin)) {
213+
$config['admin'] = $this->admin->toArray();
199214
}
200215

201-
if (isset($this->_logging)) {
202-
$config['logging'] = $this->_logging->toArray();
216+
if (isset($this->logging)) {
217+
$config['logging'] = $this->logging->toArray();
203218
}
204219

205-
if (isset($this->_apps)) {
220+
if (count($this->apps)) {
206221
$apps = [];
207222

208223
array_map(static function (App $app, string $appNamespace) use (&$apps) {
209224
$apps[$appNamespace] = $app->toArray();
210-
}, $this->_apps, array_keys($this->_apps));
225+
}, $this->apps, array_keys($this->apps));
211226

212227
$config['apps'] = $apps;
213228
}
214229

215230
return $config;
216231
}
217232

233+
/**
234+
* @param string $hostIdentifier
235+
* @return void
236+
* @throws \Exception
237+
*/
218238
protected function buildHostsCache(string $hostIdentifier): void
219239
{
220-
if (!in_array($hostIdentifier, $this->_hostsCache, true)) {
240+
if (!key_exists($hostIdentifier, $this->hostsCache)) {
221241
//Find the host so we can get its path
222242

223-
$hostPath = '';
224-
foreach ($this->_apps as $app) {
243+
$hostPath = null;
244+
foreach ($this->apps as $app) {
225245
if ($found = findHost($app, $hostIdentifier)) {
226246
$hostPath = $found;
227247
break;
@@ -232,7 +252,7 @@ protected function buildHostsCache(string $hostIdentifier): void
232252
throw new \Exception('Host does not exist. Check your host identified');
233253
}
234254

235-
$this->_hostsCache[$hostIdentifier] = $hostPath;
255+
$this->hostsCache[$hostIdentifier] = $hostPath;
236256
}
237257
}
238-
}
258+
}

src/Config/Admin.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ class Admin implements Arrayable
1515
{
1616
/**
1717
* If true, the admin endpoint will be completely disabled.
18-
* Note that this makes any runtime changes to the config impossible, since the interface to do so is through the admin endpoint.
18+
* Note that this makes any runtime changes to the config impossible,
19+
* since the interface to do so is through the admin endpoint.
1920
*/
2021
private bool $disabled = false;
2122

@@ -51,4 +52,4 @@ public function toArray(): array
5152
'listen' => $this->getListen(),
5253
];
5354
}
54-
}
55+
}

0 commit comments

Comments
 (0)