Issues (18)

php-src/Helper.php (1 issue)

1
<?php
2
3
namespace kalanis\RemoteRequest;
4
5
6
use kalanis\RemoteRequest\Connection;
7
use kalanis\RemoteRequest\Interfaces;
8
use kalanis\RemoteRequest\Sockets;
9
10
11
/**
12
 * Class Helper
13
 * @package kalanis\RemoteRequest
14
 * Simplified reading from remote machine with a whole power of RemoteRequest and mainly streams underneath
15
 * -> throw Curl into /dev/null
16
 */
17
class Helper
18
{
19
    protected static ?Interfaces\IRRTranslations $lang = null; // translations
20
    protected string $link = ''; // target
21
    /** @var string|string[]|array<string|int, string|int> */
22
    protected $postContent = ''; // what to say to the target
23
    /** @var array<string, string|int|bool|null> */
24
    protected array $connectionParams = [
25
        'timeout' => 30,
26
        'maxLength' => 0,
27
        'method' => 'get',
28
        'multipart' => false,
29
        'permanent' => false,
30
        'sequence' => 0,
31
        'secret' => 0,
32
        'seek' => 0,
33
    ];
34
    /** @var array<string, array<string, string>|string> */
35
    protected array $contextParams = [];
36
37
    /**
38
     * @param string $link link to remote source (server, page, ...)
39
     * @param string|string[] $postContent array(key=>value) for http or fsp, string otherwise
40
     * @param array<string, string|int|bool|null> $connectionParams overwrite default values for connection
41
     * @param array<string, array<string, string>|string> $contextParams added to stream context (like skipping ssl checkup)
42
     * @throws RequestException
43
     * @return string
44
     */
45
    public static function getRemoteContent(string $link, $postContent = '', array $connectionParams = [], array $contextParams = []): string
46
    {
47
        $lib = new Helper();
48
        $lib
49
            ->setLink($link)
50
            ->setPostContent($postContent)
51
            ->setConnectionParams($connectionParams)
52
            ->setContextParams($contextParams)
53
        ;
54
        return $lib->getResponse()->getContent();
55
    }
56
57
    public static function fillLang(?Interfaces\IRRTranslations $lang = null): void
58
    {
59
        static::$lang = $lang;
60
    }
61
62
    public static function getLang(): Interfaces\IRRTranslations
63
    {
64
        if (empty(static::$lang)) {
65
            static::$lang = new Translations();
66
        }
67
        return static::$lang;
0 ignored issues
show
Bug Best Practice introduced by
The expression return static::lang could return the type null which is incompatible with the type-hinted return kalanis\RemoteRequest\Interfaces\IRRTranslations. Consider adding an additional type-check to rule them out.
Loading history...
68
    }
69
70
    public function setLink(string $link): self
71
    {
72
        $this->link = $link;
73
        return $this;
74
    }
75
76
    /**
77
     * @param string|string[]|array<string|int, string|int> $postContent
78
     * @return $this
79
     */
80
    public function setPostContent($postContent = ''): self
81
    {
82
        $this->postContent = $postContent;
83
        return $this;
84
    }
85
86
    /**
87
     * @param array<string, string|int|bool|null> $params
88
     * @return $this
89
     */
90
    public function setConnectionParams(array $params = []): self
91
    {
92
        $this->connectionParams = array_merge($this->connectionParams, $params);
93
        return $this;
94
    }
95
96
    /**
97
     * @param array<string, array<string, string>|string> $params
98
     * @return $this
99
     */
100
    public function setContextParams(array $params = []): self
101
    {
102
        $this->contextParams = $params;
103
        return $this;
104
    }
105
106
    /**
107
     * @throws RequestException
108
     * @return Protocols\Dummy\Answer
109
     */
110
    public function getResponse(): Protocols\Dummy\Answer
111
    {
112
        static::fillLang();
113
        $parsedLink = parse_url($this->link);
114
        if (false === $parsedLink) {
115
            throw new RequestException(static::getLang()->rrHelpInvalidLink($this->link));
116
        }
117
        $schema = !empty($parsedLink["scheme"]) ? strtolower($parsedLink["scheme"]) : '' ;
118
        $libParams = $this->getFilledConnectionParams($schema, $parsedLink);
119
        $libQuery = $this->getLibRequest($schema, $parsedLink, $libParams);
120
        return $this->getLibResponseProcessor($schema)->setResponse(
121
            $this->getLibConnection($libQuery)
122
                ->setConnectionParams($libParams)
123
                ->setData($libQuery)
124
                ->process()
125
                ->getResponse()
126
        );
127
    }
128
129
    protected function getLibConnection(Protocols\Dummy\Query $libQuery): Connection\Processor
130
    {
131
        return new Connection\Processor($this->getLibSockets($libQuery), static::getLang());
132
    }
133
134
    protected function getLibSockets(Protocols\Dummy\Query $libQuery): ?Sockets\ASocket
135
    {
136
        if (!empty($this->contextParams)) {
137
            $processing = new Sockets\Stream(static::getLang());
138
            return $processing->setContextOptions($this->contextParams);
139
        } elseif ($this->connectionParams['permanent']) {
140
            return new Sockets\PfSocket(static::getLang());
141
        } elseif ($libQuery instanceof Protocols\Fsp\Query) {
142
            return new Sockets\Socket(static::getLang());
143
        } else {
144
            return new Sockets\FSocket(static::getLang());
145
        }
146
    }
147
148
    /**
149
     * @param string $schema
150
     * @param array<string, int|string> $parsedLink from parse_url()
151
     * @throws RequestException
152
     * @return Connection\Params\AParams
153
     */
154
    protected function getFilledConnectionParams(string $schema, $parsedLink): Connection\Params\AParams
155
    {
156
        $libParams = $this->getConnectionParams($schema);
157
        return $libParams->setTarget(
158
            strval($parsedLink["host"]),
159
            empty($parsedLink["port"]) ? $libParams->getPort() : intval($parsedLink["port"]),
160
            empty($this->connectionParams['timeout']) ? null : floatval($this->connectionParams['timeout'])
161
        );
162
    }
163
164
    /**
165
     * @param string $schema
166
     * @throws RequestException
167
     * @return Connection\Params\AParams
168
     */
169
    protected function getConnectionParams(string $schema): Connection\Params\AParams
170
    {
171
        switch ($schema) {
172
            case 'tcp':
173
                return new Connection\Params\Tcp();
174
            case 'udp':
175
            case 'fsp':
176
                return new Connection\Params\Udp();
177
            case 'http':
178
                return new Connection\Params\Tcp();
179
            case 'https':
180
                return new Connection\Params\Ssl();
181
            case 'file':
182
                return new Connection\Params\File();
183
            default:
184
                throw new RequestException(static::getLang()->rrHelpInvalidProtocolSchema($schema));
185
        }
186
    }
187
188
    /**
189
     * @param string $schema
190
     * @param array<string, int|string> $parsed from parse_url()
191
     * @param Interfaces\ITarget $settings
192
     * @throws RequestException
193
     * @return Protocols\Dummy\Query
194
     */
195
    protected function getLibRequest(string $schema, array $parsed, Interfaces\ITarget $settings): Protocols\Dummy\Query
196
    {
197
        switch ($schema) {
198
            case 'tcp':
199
            case 'udp':
200
            case 'file':
201
                $query = new Protocols\Dummy\Query();
202
                $query->maxLength = is_null($this->connectionParams['maxLength']) ? null : intval($this->connectionParams['maxLength']);
203
                $query->body = strval($this->postContent);
204
                return $query;
205
            case 'fsp':
206
                $query = new Protocols\Fsp\Query();
207
                return $query
208
                    ->setCommand(intval($this->connectionParams['method']))
209
                    ->setSequence(intval($this->connectionParams['sequence']))
210
                    ->setKey(intval($this->connectionParams['secret']))
211
                    ->setFilePosition(intval($this->connectionParams['seek']))
212
                    ->setContent(strval($this->postContent))
213
                ;
214
            case 'http':
215
            case 'https':
216
                if (isset($parsed['user'])) {
217
                    $query = new Protocols\Http\Query\AuthBasic();
218
                    $query->setCredentials(
219
                        strval($parsed['user']),
220
                        isset($parsed['pass']) ? strval($parsed['pass']) : ''
221
                    );
222
                } else {
223
                    $query = new Protocols\Http\Query();
224
                }
225
                $query->maxLength = is_null($this->connectionParams['maxLength']) ? null : intval($this->connectionParams['maxLength']);
226
                return $query
227
                    ->setRequestSettings($settings)
228
                    ->setPath($parsed['path'] . (!empty($parsed['query']) ? '?' . $parsed['query'] : '' ))
229
                    ->setMethod($this->getMethod())
230
                    ->setInline(boolval($this->connectionParams['multipart']))
231
                    ->addValues(empty($this->postContent) ? [] : (array) $this->postContent)
232
                ;
233
            default:
234
                throw new RequestException(static::getLang()->rrHelpInvalidRequestSchema($schema));
235
        }
236
    }
237
238
    protected function getMethod(): string
239
    {
240
        $method = strtoupper(strval($this->connectionParams['method']));
241
        return (in_array($method, ['GET', 'POST', 'PUT', 'DELETE'])) ? $method : 'GET' ;
242
    }
243
244
    /**
245
     * @param string $schema
246
     * @throws RequestException
247
     * @return Protocols\Dummy\Answer
248
     */
249
    protected function getLibResponseProcessor(string $schema): Protocols\Dummy\Answer
250
    {
251
        switch ($schema) {
252
            case 'tcp':
253
            case 'udp':
254
            case 'file':
255
                return new Protocols\Dummy\Answer();
256
            case 'fsp':
257
                return new Protocols\Fsp\Answer(static::getLang());
258
            case 'http':
259
            case 'https':
260
                return new Protocols\Http\Answer(static::getLang());
261
            default:
262
                throw new RequestException(static::getLang()->rrHelpInvalidResponseSchema($schema));
263
        }
264
    }
265
}
266