Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
EprtCommand
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
56
0.00% covered (danger)
0.00%
0 / 1
 run
0.00% covered (danger)
0.00%
0 / 26
0.00% covered (danger)
0.00%
0 / 1
56
1<?php
2namespace Apie\FtpServer\Commands;
3
4use Apie\Core\Context\ApieContext;
5use Apie\FtpServer\FtpConstants;
6use Apie\FtpServer\Transfers\PortTransfer;
7use Apie\FtpServer\Transfers\TransferInterface;
8use React\Socket\ConnectionInterface;
9
10class EprtCommand implements CommandInterface
11{
12    public function run(ApieContext $apieContext, string $arg = ''): ApieContext
13    {
14        $conn = $apieContext->getContext(ConnectionInterface::class);
15
16        // EPRT format: |af|host|port|
17        // The delimiter is the first character.
18        if ($arg === '') {
19            $conn->write("501 Syntax error in parameters or arguments\r\n");
20            return $apieContext;
21        }
22
23        $delim = $arg[0];
24        $parts = explode($delim, $arg);
25
26        if (count($parts) !== 5) {
27            $conn->write("501 Syntax error in parameters or arguments\r\n");
28            return $apieContext;
29        }
30
31        [$empty, $af, $host, $port, $empty2] = $parts;
32
33        // Only IPv4 supported
34        if ($af !== '1') {
35            $conn->write("522 Network protocol not supported (IPv6 not available)\r\n");
36            return $apieContext;
37        }
38
39        if (!filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4)) {
40            $conn->write("501 Invalid IP address\r\n");
41            return $apieContext;
42        }
43
44        $port = (int)$port;
45        if ($port <= 0 || $port > 65535) {
46            $conn->write("501 Invalid port number\r\n");
47            return $apieContext;
48        }
49
50        // Store for use by the server
51        $apieContext = $apieContext
52            ->withContext(FtpConstants::IP, $host)
53            ->withContext(FtpConstants::PORT, $port)
54            ->withContext(TransferInterface::class, new PortTransfer($host, $port));
55
56        $conn->write("200 EPRT command successful.\r\n");
57
58        return $apieContext;
59    }
60}