Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
30.00% covered (danger)
30.00%
6 / 20
80.00% covered (warning)
80.00%
4 / 5
CRAP
0.00% covered (danger)
0.00%
0 / 1
NullConnectionPool
30.00% covered (danger)
30.00%
6 / 20
80.00% covered (warning)
80.00%
4 / 5
29.95
0.00% covered (danger)
0.00%
0 / 1
 __construct
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 acquire
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 release
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 close
100.00% covered (success)
100.00%
1 / 1
100.00% covered (success)
100.00%
1 / 1
1
 defaultConnector
12.50% covered (danger)
12.50%
2 / 16
0.00% covered (danger)
0.00%
0 / 1
14.72
1<?php
2
3/**
4 * SPDX-License-Identifier: EUPL-1.2
5 *
6 * This file is part of icap-flow.
7 *
8 * Licensed under the EUPL, Version 1.2 only (the "Licence");
9 * you may not use this work except in compliance with the Licence.
10 * You may obtain a copy of the Licence at:
11 *
12 *     https://joinup.ec.europa.eu/collection/eupl/eupl-text-eupl-12
13 *
14 * Unless required by applicable law or agreed to in writing, software
15 * distributed under the Licence is distributed on an "AS IS" basis,
16 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
17 */
18
19declare(strict_types=1);
20
21namespace Ndrstmr\Icap\Transport;
22
23use Amp\Cancellation;
24use Amp\Socket;
25use Amp\Socket\ConnectContext;
26use Amp\Socket\Socket as SocketInterface;
27use Closure;
28use Ndrstmr\Icap\Config;
29use Ndrstmr\Icap\Exception\IcapConnectionException;
30
31/**
32 * No-op connection pool: every {@see acquire()} opens a fresh TCP/TLS
33 * connection, every {@see release()} closes it immediately. No idle
34 * sockets are ever kept.
35 *
36 * Use this when connection reuse is explicitly unwanted (e.g. testing,
37 * debugging, or ICAP servers that close the connection after every
38 * request anyway).
39 *
40 * @see AmpConnectionPool for the keep-alive variant
41 */
42final class NullConnectionPool implements ConnectionPoolInterface
43{
44    /** @var Closure(Config, ?Cancellation): SocketInterface */
45    private Closure $connector;
46
47    /**
48     * @param (Closure(Config, ?Cancellation): SocketInterface)|null $connector optional override for testing
49     */
50    public function __construct(?Closure $connector = null)
51    {
52        $this->connector = $connector ?? self::defaultConnector();
53    }
54
55    #[\Override]
56    public function acquire(Config $config, ?Cancellation $cancellation = null): SocketInterface
57    {
58        return ($this->connector)($config, $cancellation);
59    }
60
61    #[\Override]
62    public function release(Config $config, SocketInterface $socket): void
63    {
64        $socket->close();
65    }
66
67    #[\Override]
68    public function close(): void
69    {
70        // Nothing to do — no idle sockets are ever stored.
71    }
72
73    /**
74     * @return Closure(Config, ?Cancellation): SocketInterface
75     */
76    private static function defaultConnector(): Closure
77    {
78        return static function (Config $config, ?Cancellation $cancellation): SocketInterface {
79            $tls = $config->getTlsContext();
80            $url = sprintf('tcp://%s:%d', $config->host, $config->port);
81            $context = (new ConnectContext())->withConnectTimeout($config->getSocketTimeout());
82            if ($tls !== null) {
83                $context = $context->withTlsContext($tls);
84            }
85
86            try {
87                if ($tls !== null) {
88                    return Socket\connectTls($url, $context, $cancellation);
89                }
90                return Socket\connect($url, $context, $cancellation);
91            } catch (Socket\ConnectException $e) {
92                throw new IcapConnectionException(
93                    sprintf('NullConnectionPool connect to %s:%d failed.', $config->host, $config->port),
94                    0,
95                    $e,
96                );
97            }
98        };
99    }
100}