Completed
Push — master ( 17dfca...2f9de9 )
by Samuel
01:17
created

FastCGI   A

Complexity

Total Complexity 16

Size/Duplication

Total Lines 136
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 8

Test Coverage

Coverage 92.59%

Importance

Changes 0
Metric Value
wmc 16
lcom 1
cbo 8
dl 0
loc 136
ccs 50
cts 54
cp 0.9259
rs 10
c 0
b 0
f 0

4 Methods

Rating   Name   Duplication   Size   Complexity  
A doRun() 0 10 2
A getScriptFileName() 0 10 3
B __construct() 0 40 7
A request() 0 30 4
1
<?php
2
3
/*
4
 * This file is part of CacheTool.
5
 *
6
 * (c) Samuel Gordalina <[email protected]>
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 8
    public function __construct($host = null, $chroot = null)
56
    {
57
        // try to guess where it is
58 8
        if ($host === null) {
59 6
            foreach ($this->possibleSocketFilePatterns as $possibleSocketFilePattern) {
60 6
                $possibleSocketFile = current(glob($possibleSocketFilePattern));
61 6
                if (file_exists($possibleSocketFile)) {
62 6
                    $host = $possibleSocketFile;
63 6
                    break;
64
                }
65
            }
66 6
            if ($host === null) {
67
                $host = '127.0.0.1:9000';
68
            }
69
        }
70
71 8
        $this->host = $host;
72
73 8
        if (false !== strpos($host, ':')) {
74 2
            [$host, $port] = explode(':', $host);
0 ignored issues
show
Bug introduced by
The variable $port does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
75 2
            $this->connection = new NetworkSocket(
76 2
            	  $host,    # Hostname
77 2
            	  $port,    # Port
78 2
            	  5000,     # Connect timeout in milliseconds (default: 5000)
79 2
            	  120000    # Read/write timeout in milliseconds (default: 5000)
80
            );
81
        } else {
82 6
            $this->connection = new UnixDomainSocket(
83 6
                $host,  # Socket path to php-fpm
84 6
                5000,   # Connect timeout in milliseconds (default: 5000)
85 6
                120000  # Read/write timeout in milliseconds (default: 5000)
86
            );
87
        }
88
89 8
        $this->client = new Client();
90
91 8
        if ($chroot !== null) {
92 3
            $this->chroot = rtrim($chroot, '/');
93
        }
94 8
    }
95
96
    /**
97
     * {@inheritdoc}
98
     */
99 3
    protected function doRun(Code $code)
100
    {
101 3
        $body = $this->request($code);
102
103 1
        if (@unserialize($body) === false) {
104
            throw new \RuntimeException(sprintf("Error: %s", $body));
105
        }
106
107 1
        return $body;
108
    }
109
110 3
    protected function request(Code $code)
111
    {
112 3
        $file = $this->createTemporaryFile();
113 3
        $this->logger->info(sprintf('FastCGI: Dumped code to file: %s', $file));
114
115
        try {
116 3
            $code->writeTo($file);
117
118 1
            $this->logger->info(sprintf('FastCGI: Requesting FPM using socket: %s', $this->host));
119 1
            $request = new PostRequest($this->getScriptFileName($file), '');
120 1
            $response = $this->client->sendRequest($this->connection, $request);
121 1
            $this->logger->debug(sprintf('FastCGI: Response: %s', json_encode($response)));
122
123 1
            if (!@unlink($file)) {
124
                $this->logger->debug(sprintf('FastCGI: Could not delete file: %s', $file));
125
            }
126
127 1
            return $response->getBody();
128 2
        } catch (\Exception $e) {
129 2
            if (!@unlink($file)) {
130 2
                $this->logger->debug(sprintf('FastCGI: Could not delete file: %s', $file));
131
            }
132
133 2
            throw new \RuntimeException(
134 2
                sprintf('FastCGI error: %s (%s)', $e->getMessage(), $this->host),
135 2
                $e->getCode(),
136 2
                $e
137
            );
138
        }
139
    }
140
141
    /**
142
     * @param string $file
143
     * @return string
144
     * @throws \RuntimeException
145
     */
146 2
    protected function getScriptFileName($file)
147
    {
148 2
        if ($this->chroot) {
149 1
            if (substr($file, 0, strlen($this->chroot)) === $this->chroot) {
150 1
                return substr($file, strlen($this->chroot));
151
            }
152
            throw new \RuntimeException('FastCGI configured to be chrooted, but file not in chroot directory.');
153
        }
154 1
        return $file;
155
    }
156
}
157