Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
CRAP
0.00% covered (danger)
0.00%
0 / 1
PortCommand
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
6
0.00% covered (danger)
0.00%
0 / 1
 run
0.00% covered (danger)
0.00%
0 / 21
0.00% covered (danger)
0.00%
0 / 1
6
1<?php
2namespace Apie\FtpServer\Commands;
3
4use Apie\Core\Context\ApieContext;
5use Apie\FtpServer\Factories\ServerFactoryInterface;
6use Apie\FtpServer\Factories\SimpleFtpServerFactory;
7use Apie\FtpServer\FtpConstants;
8use Apie\FtpServer\Transfers\PortTransfer;
9use Apie\FtpServer\Transfers\TransferInterface;
10use React\Socket\ConnectionInterface;
11
12class PortCommand implements CommandInterface
13{
14    public function run(ApieContext $apieContext, string $arg = ''): ApieContext
15    {
16        $conn = $apieContext->getContext(ConnectionInterface::class);
17        $factory = $apieContext->getContext(ServerFactoryInterface::class, false) ?? new SimpleFtpServerFactory();
18
19        // Parse the argument: h1,h2,h3,h4,p1,p2
20        $parts = explode(',', $arg);
21        if (count($parts) !== 6) {
22            $conn->write("501 Syntax error in parameters or arguments\r\n");
23            return $apieContext;
24        }
25        $ip = implode('.', array_slice($parts, 0, 4));
26        $port = ((int)$parts[4] << 8) + (int)$parts[5];
27
28        $transfer = new PortTransfer($factory->createConnector(), $ip, $port);
29        $transfer->connectOnly()->then(
30            function() use ($conn) {
31                $conn->write("200 PORT command successful.\r\n");
32            },
33            function (\Throwable $error) use ($conn) {
34                error_log($error->getMessage());
35                $conn->write("425 Can't open data connection.\r\n");
36            }
37        );
38
39        return $apieContext->withContext(FtpConstants::IP, $ip)
40            ->withContext(FtpConstants::PORT, $port)
41            ->withContext(TransferInterface::class, $transfer);
42    }
43}