• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

gordalina / cachetool / 9069543501

13 May 2024 08:43PM UTC coverage: 90.117%. Remained the same
9069543501

push

github

web-flow
Merge pull request #245 from barasimumatik/phpdoc_type_info_fix

improve phpdoc return type for apcu_cache_info

848 of 941 relevant lines covered (90.12%)

81.33 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

93.33
/src/Adapter/FastCGI.php
1
<?php
2

3
/*
4
 * This file is part of CacheTool.
5
 *
6
 * (c) Samuel Gordalina <samuel.gordalina@gmail.com>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
namespace CacheTool\Adapter;
13

14
use CacheTool\Code;
15
use hollodotme\FastCGI\Client;
16
use hollodotme\FastCGI\Interfaces\ConfiguresSocketConnection;
17
use hollodotme\FastCGI\SocketConnections\NetworkSocket;
18
use hollodotme\FastCGI\SocketConnections\UnixDomainSocket;
19
use hollodotme\FastCGI\Requests\PostRequest;
20

21
class FastCGI extends AbstractAdapter
22
{
23
    /**
24
     * @var Client
25
     */
26
    protected $client;
27

28
    /**
29
     * @var ConfiguresSocketConnection
30
     */
31
    protected $connection;
32

33
    /**
34
     * @var Array of patterns matching php socket files
35
     */
36
    protected $possibleSocketFilePatterns = [
37
        '/var/run/php*.sock',
38
        '/var/run/php/*.sock'
39
    ];
40

41
    /**
42
     * @var string
43
     */
44
    protected $host;
45

46
    /**
47
     * @var string
48
     */
49
    protected $chroot;
50

51
    /**
52
     * @param string $host 127.0.0.1:9000 or /var/run/php5-fpm.sock
53
     * @param string $chroot
54
     */
55
    public function __construct($host = null, $chroot = null)
56
    {
57
        // try to guess where it is
58
        if ($host === null) {
84✔
59
            foreach ($this->possibleSocketFilePatterns as $possibleSocketFilePattern) {
49✔
60
                $possibleSocketFile = current(glob($possibleSocketFilePattern));
49✔
61
                if (file_exists($possibleSocketFile)) {
49✔
62
                    $host = $possibleSocketFile;
21✔
63
                    break;
64
                }
65
            }
66
            if ($host === null) {
49✔
67
                $host = '127.0.0.1:9000';
28✔
68
            }
69
        }
70

71
        $this->host = $host;
84✔
72

73
        if (false !== strpos($host, ':')) {
84✔
74
            $last = strrpos($host, ':');
56✔
75
            $port = substr($host, $last + 1, strlen($host));
56✔
76
            $host = substr($host, 0, $last);
56✔
77

78
            $IPv6 = '/^(?:[A-F0-9]{0,4}:){1,7}[A-F0-9]{0,4}$/';
56✔
79
            if (preg_match($IPv6, $host) === 1) {
56✔
80
                // IPv6 addresses need to be surrounded by brackets
81
                // see: https://www.php.net/manual/en/function.stream-socket-client.php#refsect1-function.stream-socket-client-notes
82
                $host = "[{$host}]";
7✔
83
            }
84

85
            $this->connection = new NetworkSocket(
56✔
86
                $host,    # Hostname
87
                $port,    # Port
88
                5000,     # Connect timeout in milliseconds (default: 5000)
89
                120000    # Read/write timeout in milliseconds (default: 5000)
90
            );
91
        } else {
92
            $this->connection = new UnixDomainSocket(
28✔
93
                $host,  # Socket path to php-fpm
94
                5000,   # Connect timeout in milliseconds (default: 5000)
95
                120000  # Read/write timeout in milliseconds (default: 5000)
96
            );
97
        }
98

99
        $this->client = new Client();
84✔
100

101
        if ($chroot !== null) {
84✔
102
            $this->chroot = rtrim($chroot, '/');
14✔
103
        }
104
    }
105

106
    /**
107
     * {@inheritdoc}
108
     */
109
    protected function doRun(Code $code)
110
    {
111
        $body = $this->request($code);
28✔
112

113
        if (@unserialize($body) === false) {
14✔
114
            throw new \RuntimeException(sprintf("Error: %s", $body));
×
115
        }
116

117
        return $body;
14✔
118
    }
119

120
    protected function request(Code $code)
121
    {
122
        $file = $this->createTemporaryFile();
28✔
123
        $this->logger->info(sprintf('FastCGI: Dumped code to file: %s', $file));
28✔
124

125
        try {
126
            $code->writeTo($file);
28✔
127

128
            $this->logger->info(sprintf('FastCGI: Requesting FPM using socket: %s', $this->host));
14✔
129
            $request = new PostRequest($this->getScriptFileName($file), '');
14✔
130
            $response = $this->client->sendRequest($this->connection, $request);
14✔
131
            $this->logger->debug(sprintf('FastCGI: Response: %s', json_encode($response)));
14✔
132

133
            if (!@unlink($file)) {
14✔
134
                $this->logger->debug(sprintf('FastCGI: Could not delete file: %s', $file));
×
135
            }
136

137
            return $response->getBody();
14✔
138
        } catch (\Exception $e) {
14✔
139
            if (!@unlink($file)) {
14✔
140
                $this->logger->debug(sprintf('FastCGI: Could not delete file: %s', $file));
14✔
141
            }
142

143
            throw new \RuntimeException(
14✔
144
                sprintf('FastCGI error: %s (%s)', $e->getMessage(), $this->host),
14✔
145
                $e->getCode(),
14✔
146
                $e
147
            );
148
        }
149
    }
150

151
    /**
152
     * @param string $file
153
     * @return string
154
     * @throws \RuntimeException
155
     */
156
    protected function getScriptFileName($file)
157
    {
158
        if ($this->chroot) {
21✔
159
            if (substr($file, 0, strlen($this->chroot)) === $this->chroot) {
7✔
160
                return substr($file, strlen($this->chroot));
7✔
161
            }
162
            throw new \RuntimeException('FastCGI configured to be chrooted, but file not in chroot directory.');
×
163
        }
164
        return $file;
14✔
165
    }
166
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc