Skip to content

Commit

Permalink
Surrogate flush (#9)
Browse files Browse the repository at this point in the history
* fix finding hosts

* remove placeholder code

* surrogate key flushing

* attempt to flush any all caches
  • Loading branch information
mattvb91 authored Jul 27, 2022
1 parent 6205c2d commit 0dc71e0
Show file tree
Hide file tree
Showing 6 changed files with 141 additions and 22 deletions.
2 changes: 1 addition & 1 deletion docker/caddy/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
FROM caddy:2.5.1-builder-alpine

RUN xcaddy build --with github.com/darkweak/souin/plugins/caddy \
--with github.com/darkweak/[email protected].16
--with github.com/darkweak/[email protected].17


# See https://caddyserver.com/docs/conventions#file-locations for details
Expand Down
44 changes: 29 additions & 15 deletions src/Caddy.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,20 +5,13 @@
use GuzzleHttp\Client;
use GuzzleHttp\Exception\ClientException;
use mattvb91\CaddyPhp\Config\Admin;
use mattvb91\CaddyPhp\Config\Apps\Http;
use mattvb91\CaddyPhp\Config\Logging;
use mattvb91\CaddyPhp\Exceptions\CaddyClientException;
use mattvb91\caddyPhp\Interfaces\App;
use mattvb91\CaddyPhp\Interfaces\Arrayable;

class Caddy implements Arrayable
{
/**
* We need a reference to ourselves for adding domains and hosts
* dynamically later.
*/
private static self $_instance;

/**
* This is the collection of hosts with the associated paths to where they are
* in the config.
Expand All @@ -41,25 +34,21 @@ class Caddy implements Arrayable
/** @var App[] */
private array $_apps;

private $_hostname;

public function __construct(?string $hostname = 'caddy', ?Admin $admin = new Admin(), ?Client $client = null)
{
$this->setAdmin($admin);

$this->_hostname = $hostname;

$this->_client = $client ?? new Client([
'base_uri' => $hostname . $this->getAdmin()->getListen() . '/config',
'headers' => [
'Content-Type' => 'application/json',
],
]
);

//Reference ourselves
self::$_instance = &$this;
}

public static function getInstance(): self
{
return self::$_instance;
}

/**
Expand Down Expand Up @@ -113,6 +102,31 @@ public function removeHostname(string $hostIdentifier, string $hostname): bool
return false;
}

/**
* Get the current config of the caddy server.
*
* TODO we should be able to build our $caddy object back up from this.
* So instead of toArray we should be able to do fromArray() or something
*/
public function getRemoteConfig(): object
{
return json_decode($this->_client->get('/config')->getBody(), false, 512, JSON_THROW_ON_ERROR);
}

/**
* This is responsible for flushing the individual caches of items on the caddy server.
*/
public function flushSurrogates(array $surrogates): bool
{
//TODO this is missing the fact that you could customize your cache paths.

return $this->_client->request('PURGE', 'http://' . $this->_hostname . '/cache/souin', [
'headers' => [
'Surrogate-Key' => implode(', ', $surrogates),
],
])->getStatusCode() === 204;
}

/**
* @throws \GuzzleHttp\Exception\GuzzleException
* @throws \Exception
Expand Down
7 changes: 1 addition & 6 deletions src/Traits/IterableProps.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,7 @@ trait IterableProps
{
public function iterateAllProperties(): array
{
$props = [];
foreach ($this as $key => $value) {
$props[$key] = &$value;
}

return $props;
return get_object_vars($this);
}

}
57 changes: 57 additions & 0 deletions tests/Integration/Apps/CacheTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -61,4 +61,61 @@ public function test_keys()
$caddy->addApp($cache);
$this->assertCaddyConfigLoaded($caddy);
}

/**
* @covers \mattvb91\CaddyPhp\Caddy::flushSurrogates
*/
public function test_surrogate_key_flush()
{
$caddy = new Caddy();

$http = new Http();
$server = new Http\Server();
$route = new Http\Server\Route();

$route->addHandle(new Http\Server\Routes\Handle\Cache())
->addHandle((new Http\Server\Routes\Handle\StaticResponse('cache test'))
->setHeaders([
'Surrogate-Key' => [
'test_cache_key',
],
]
)
);

$server->addRoute($route);
$http->addServer(key: 'cacheServer', server: $server);

$caddy->addApp(new Cache());
$caddy->addApp($http);
$this->assertCaddyConfigLoaded($caddy);

$caddy->flushSurrogates(['test_cache_key']);

$client = new Client([
'base_uri' => 'caddy',
]);

$client->request('PURGE', 'caddy/cache/souin/GET-caddy-/');
$client->request('PURGE', 'caddy/cache/souin/GET-localhost-/');
sleep(1);

$request = $client->get('');
$this->assertEquals(200, $request->getStatusCode());

$this->assertEquals('cache test', $request->getBody()->getContents());
$this->assertStringContainsString('Souin; fwd=uri-miss; stored', $request->getHeader('cache-status')[0]);

$request = $client->get('');
$this->assertEquals(200, $request->getStatusCode());
$this->assertStringContainsString('Souin; hit;', $request->getHeader('cache-status')[0]);

$caddy->flushSurrogates(['test_cache_key']);
sleep(1);

$request = $client->get('');
$this->assertEquals(200, $request->getStatusCode());
$this->assertStringContainsString('Souin; fwd=uri-miss; stored', $request->getHeader('cache-status')[0]);

}
}
16 changes: 16 additions & 0 deletions tests/Integration/CaddyTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -274,4 +274,20 @@ public function test_http_basic_auth()
//
// $this->assertTrue($caddy->load());
// }

/**
* @covers \mattvb91\CaddyPhp\Caddy::getRemoteConfig
*/
public function test_caddy_get_config()
{
$caddy = new Caddy();
$caddy->addApp((new Http())
->addServer('test', (new Http\Server())
->addRoute((new Route())
->addHandle((new StaticResponse('test'))))));
$caddy->load();

$this->assertEquals(json_decode(json_encode($caddy->toArray())), $caddy->getRemoteConfig());
}

}
37 changes: 37 additions & 0 deletions tests/Unit/MiscTest.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

namespace Tests\Unit;

use mattvb91\CaddyPhp\Config\Apps\Http;
use PHPUnit\Framework\TestCase;
use function mattvb91\CaddyPhp\findHost;

class MiscTest extends TestCase
{
/**
* @covers \mattvb91\CaddyPhp\findHost
*/
public function test_finding_host()
{
$http = new Http();
$server = new Http\Server();
$server->setListen([":80"]);


$host = (new Http\Server\Routes\Match\Host('shops'))
->setHosts([
"{http.request.host}.localhost",
]);

$shopDeploymentsRoute = new Http\Server\Route();
$shopDeploymentsRoute->addMatch($host)
->setTerminal(true);


$server->addRoute($shopDeploymentsRoute);
$http->addServer('platform', $server);

$this->assertEquals($host, findHost($http, 'shops')['host']);
}

}

0 comments on commit 0dc71e0

Please sign in to comment.