123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118 |
- <?php
- namespace App\Controller;
- use PhpParser\Node\Stmt\Throw_;
- use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
- use Symfony\Component\Cache\Adapter\FilesystemAdapter;
- use Symfony\Component\HttpClient\Exception\TimeoutException;
- use Symfony\Component\HttpClient\HttpClient;
- use Symfony\Component\HttpFoundation\Response;
- use Symfony\Component\HttpKernel\Exception\NotFoundHttpException;
- use Symfony\Component\Routing\Annotation\Route;
- use Symfony\Contracts\Cache\CacheInterface;
- use Symfony\Contracts\Cache\ItemInterface;
- class ProxyController extends AbstractController
- {
- private $cache;
- private $client;
- private $expiration = 3600 * 2;
- private $tryAfter = 1800 * 2;
- public function __construct(CacheInterface $cache)
- {
- $this->cache = $cache;
- $this->client = HttpClient::create();
- }
- /**
- * @Route("/proxy/{type}/{name}", name="proxy")
- */
- public function proxy(string $type, string $name): Response {
- $valid = [
- 'kategorier',
- 'malgruppe',
- 'program',
- ];
- if (!in_array($type, $valid))
- throw new NotFoundHttpException(sprintf("Invalid type «%s»", $type));
- $key = sha1(sprintf('%s/%s', $type, $name));
- $item = $this->cache->getItem($key);
- if ($type == 'program')
- $callback = function () use ($name) {
- return $this->client->request(
- 'GET',
- sprintf('https://tromsotid.no/program%s',
- base64_decode($name . '==')
- ), [
- 'max_duration' => 3
- ]
- );
- };
- else
- $callback = function () use ($type, $name) {
- return $this->client->request(
- 'GET',
- sprintf('https://tromsotid.no/%s/%s', $type, $name), [
- 'max_duration' => 3
- ]
- );
- };
- if ($item->isHit()) {
- $data = $item->get();
- if ((time() - $data['last_update']) > $this->tryAfter) {
- $this->updateCache($item, $callback);
- }
- } else {
- $this->updateCache($item, $callback);
- }
- if (!isset($item->get()['data']))
- throw new TimeoutException("TimeoutException");
- /*
- if ($type == 'program') {
- dump($type, $name, base64_decode($name . '=='));
- return new Response(htmlentities($item->get()['data']));
- }
- */
- return new Response(($item->get()['data']));
- }
- private function updateCache(ItemInterface $item, $callback, int $retry = 5): ?ItemInterface {
- try {
- $resp = $callback();
- if ($resp->getStatusCode() != 200)
- throw new \Exception("Failed with status code " + $resp->getStatusCode());
-
- $item->set([
- 'last_update' => time(),
- 'data' => $resp->getContent()
- ]);
- } catch (\Exception $e) {
- if ($retry > 0) {
- return $this->updateCache($item, $callback, $retry - 1);
- }
- }
- if (isset($item->get()['data'])) {
- $item->expiresAfter($this->expiration);
- $this->cache->save($item);
- }
- return $item;
- }
- }
|