Protocol::createHttpHandler()   C
last analyzed

Complexity

Conditions 13
Paths 112

Size

Total Lines 54
Code Lines 39

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 12
CRAP Score 63.0815

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 13
eloc 39
c 1
b 0
f 0
nc 112
nop 0
dl 0
loc 54
ccs 12
cts 36
cp 0.3333
crap 63.0815
rs 6.5166

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
declare(strict_types=1);
4
5
/**
6
 * soluble-japha / PHPJavaBridge driver client.
7
 *
8
 * Refactored version of phpjababridge's Java.inc file compatible
9
 * with php java bridge 6.2
10
 *
11
 *
12
 * @credits   http://php-java-bridge.sourceforge.net/pjb/
13
 *
14
 * @see      http://github.com/belgattitude/soluble-japha
15
 *
16
 * @author Jost Boekemeier
17
 * @author Vanvelthem Sébastien (refactoring and fixes from original implementation)
18
 * @license   MIT
19
 *
20
 * The MIT License (MIT)
21
 * Copyright (c) 2014-2017 Jost Boekemeier
22
 * Permission is hereby granted, free of charge, to any person obtaining a copy
23
 * of this software and associated documentation files (the "Software"), to deal
24
 * in the Software without restriction, including without limitation the rights
25
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
26
 * copies of the Software, and to permit persons to whom the Software is
27
 * furnished to do so, subject to the following conditions:
28
 *
29
 * The above copyright notice and this permission notice shall be included in
30
 * all copies or substantial portions of the Software.
31
 *
32
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
33
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
34
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
35
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
36
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
37
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
38
 * THE SOFTWARE.
39
 */
40
41
namespace Soluble\Japha\Bridge\Driver\Pjb62;
42
43
use Soluble\Japha\Bridge\Driver\Pjb62\Exception\BrokenConnectionException;
44
use Soluble\Japha\Bridge\Exception\ConfigurationException;
45
use Soluble\Japha\Bridge\Exception\ConnectionException;
46
47
class Protocol
48
{
49
    /**
50
     * @var Client
51
     */
52
    public $client;
53
54
    /**
55
     * @var string|null
56
     */
57
    public $webContext;
58
59
    /**
60
     * @var string
61
     */
62
    public $serverName;
63
64
    /**
65
     * @var SimpleHttpHandler|HttpTunnelHandler|SocketHandler
66
     */
67
    public $handler;
68
69
    /**
70
     * @var SocketHandler
71
     */
72
    protected $socketHandler;
73
74
    /**
75
     * @var array
76
     */
77
    protected $host;
78
79
    /**
80
     * @var string
81
     */
82
    protected $java_hosts;
83
84
    /**
85
     * @var string
86
     */
87
    protected $java_servlet;
88
89
    /**
90
     * @var int
91
     */
92
    public $java_recv_size;
93
94
    /**
95
     * @var int
96
     */
97
    public $java_send_size;
98
99
    /**
100
     * @var string
101
     */
102
    protected $internal_encoding;
103
104
    /**
105
     * @param Client $client
106
     * @param string $java_hosts
107
     * @param string $java_servlet
108
     * @param int    $java_recv_size
109
     * @param int    $java_send_size
110
     */
111 30
    public function __construct(Client $client, $java_hosts, $java_servlet, $java_recv_size, $java_send_size)
112
    {
113 30
        $this->client = $client;
114 30
        $this->internal_encoding = $client->getParam(Client::PARAM_JAVA_INTERNAL_ENCODING);
115 30
        $this->java_hosts = $java_hosts;
116 30
        $this->java_servlet = $java_servlet;
117 30
        $this->java_recv_size = $java_recv_size;
118 30
        $this->java_send_size = $java_send_size;
119 30
        $this->setHost($java_hosts);
120 30
        $this->handler = $this->createHandler();
121 28
    }
122
123
    /**
124
     * @return Client
125
     */
126 30
    public function getClient(): Client
127
    {
128 30
        return $this->client;
129
    }
130
131
    /**
132
     * @return string
133
     */
134 30
    public function getOverrideHosts(): string
135
    {
136 30
        if (array_key_exists('X_JAVABRIDGE_OVERRIDE_HOSTS', $_ENV)) {
137
            $override = $_ENV['X_JAVABRIDGE_OVERRIDE_HOSTS'];
138
            if (null !== $override && $override !== '/') {
139
                return $override;
140
            }
141
        }
142
143 30
        return Pjb62Driver::getJavaBridgeHeader('X_JAVABRIDGE_OVERRIDE_HOSTS_REDIRECT', $_SERVER);
144
    }
145
146 9
    public function setSocketHandler(SocketHandler $socketHandler): void
147
    {
148 9
        $this->socketHandler = $socketHandler;
149 9
    }
150
151
    /**
152
     * @throws BrokenConnectionException
153
     */
154 9
    public function getSocketHandler(): SocketHandler
155
    {
156 9
        if ($this->socketHandler === null) {
157
            throw new BrokenConnectionException('No SocketHandler defined');
158
        }
159
160 9
        return $this->socketHandler;
161
    }
162
163
    /**
164
     * @param string $java_hosts
165
     */
166 30
    public function setHost(string $java_hosts): void
167
    {
168 30
        $hosts = explode(';', $java_hosts);
169
        //$hosts = explode(";", JAVA_HOSTS);
170 30
        $host = explode(':', $hosts[0]);
171 30
        while (count($host) < 3) {
172 30
            array_unshift($host, '');
173
        }
174 30
        if (substr($host[1], 0, 2) === '//') {
175
            $host[1] = substr($host[1], 2);
176
        }
177 30
        $this->host = $host;
178 30
    }
179
180
    /**
181
     * @return array
182
     */
183 30
    public function getHost(): array
184
    {
185 30
        return $this->host;
186
    }
187
188
    /**
189
     * @return HttpTunnelHandler|SimpleHttpHandler
190
     *
191
     * @throws Exception\IllegalStateException
192
     */
193 30
    public function createHttpHandler()
194
    {
195 30
        $overrideHosts = $this->getOverrideHosts();
196 30
        $ssl = '';
197 30
        if ($overrideHosts) {
198
            $s = $overrideHosts;
199
            if ((strlen($s) > 2) && ($s[1] === ':')) {
200
                if ($s[0] === 's') {
201
                    $ssl = 'ssl://';
202
                }
203
                $s = substr($s, 2);
204
            }
205
            $webCtx = strpos($s, '//');
206
            if ($webCtx) {
207
                $host = substr($s, 0, $webCtx);
208
            } else {
209
                $host = $s;
210
            }
211
            $idx = strpos($host, ':');
212
            if ($idx) {
213
                if ($webCtx) {
214
                    $port = substr($host, $idx + 1, $webCtx);
215
                } else {
216
                    $port = substr($host, $idx + 1);
217
                }
218
                $host = substr($host, 0, $idx);
219
            } else {
220
                $port = '8080';
221
            }
222
            if ($webCtx) {
223
                $webCtx = substr($s, $webCtx + 1);
224
            }
225
            if (!is_string($webCtx)) {
226
                throw new ConfigurationException(
227
                    'Cannot get a valid context'
228
                );
229
            }
230
            $this->webContext = $webCtx;
231
        } else {
232 30
            $hostVec = $this->getHost();
233 30
            if ($ssl = $hostVec[0]) {
234
                $ssl .= '://';
235
            }
236 30
            $host = $hostVec[1];
237 30
            $port = $hostVec[2];
238
        }
239 30
        $this->serverName = "${ssl}${host}:$port";
240
241 30
        if ((array_key_exists('X_JAVABRIDGE_REDIRECT', $_SERVER)) ||
242 30
                (array_key_exists('HTTP_X_JAVABRIDGE_REDIRECT', $_SERVER))) {
243
            return new SimpleHttpHandler($this, $ssl, $host, $port, $this->java_servlet, $this->java_recv_size, $this->java_send_size);
244
        }
245
246 30
        return new HttpTunnelHandler($this, $ssl, $host, $port, $this->java_servlet, $this->java_recv_size, $this->java_send_size);
247
    }
248
249
    /**
250
     * @param string $channelName With format <host:port>. If host is omitted, '127.0.0.1' by default
251
     *
252
     * @throws ConnectionException
253
     * @throws Exception\IOException
254
     */
255
    public function createSimpleHandler(string $channelName): SocketHandler
256
    {
257
        if (is_numeric($channelName)) {
258
            $host = '127.0.0.1';
259
            $port = $channelName;
260
        } else {
261
            list($host, $port) = explode(':', $channelName);
262
        }
263
        $timeout = in_array($host, ['localhost', '127.0.0.1']) ? 5 : 20;
264
        $peer = pfsockopen($host, (int) $port, $errno, $errstr, $timeout);
265
        if (!\is_resource($peer)) {
266
            throw new ConnectionException(
267
                sprintf(
268
                    'No Java server at %s:%s. Error message: %s (errno: %s)',
269
                    $host,
270
                    $port,
271
                    $errstr,
272
                    $errno
273
                )
274
            );
275
        }
276
277
        stream_set_timeout($peer, -1);
278
        $handler = new SocketHandler($this, new SocketChannelP($peer, $host, $this->java_recv_size, $this->java_send_size));
279
        $compatibility = PjbProxyClient::getInstance()->getCompatibilityOption($this->client);
280
        $this->write("\177$compatibility");
281
        $this->serverName = "$host:$port";
282
283
        return $handler;
284
    }
285
286 30
    public function java_get_simple_channel(): ?string
287
    {
288 30
        $java_hosts = $this->java_hosts;
289 30
        $java_servlet = $this->java_servlet;
290
291 30
        return ($java_hosts && (!$java_servlet || ($java_servlet === 'Off'))) ? $java_hosts : null;
292
    }
293
294 30
    public function createHandler()
295
    {
296 30
        if (!Pjb62Driver::getJavaBridgeHeader('X_JAVABRIDGE_OVERRIDE_HOSTS', $_SERVER) &&
297
                //((function_exists('java_get_default_channel') && ($defaultChannel = java_get_default_channel())) ||
298 30
                ($defaultChannel = $this->java_get_simple_channel())) {
299
            return $this->createSimpleHandler($defaultChannel);
300
        } else {
301 30
            return $this->createHttpHandler();
302
        }
303
    }
304
305 113
    public function redirect(): void
306
    {
307 113
        $this->handler->redirect();
308 113
    }
309
310
    /**
311
     * @return string
312
     */
313 114
    public function read(int $size): string
314
    {
315 114
        return $this->handler->read($size);
316
    }
317
318 132
    public function sendData(): void
319
    {
320 132
        if ($this->client->sendBuffer !== null) {
321 132
            $this->handler->write($this->client->sendBuffer);
322 132
            $this->client->sendBuffer = null;
323
        }
324 132
    }
325
326 132
    public function flush(): void
327
    {
328 132
        $this->sendData();
329 132
    }
330
331 23
    public function getKeepAlive(): string
332
    {
333 23
        return $this->handler->getKeepAlive();
334
    }
335
336 23
    public function keepAlive(): void
337
    {
338 23
        $this->handler->keepAlive();
339 8
    }
340
341 114
    public function handle(): void
342
    {
343 114
        $this->client->handleRequests();
344 113
    }
345
346
    /**
347
     * @param string $data
348
     */
349 114
    public function write($data): void
350
    {
351 114
        $this->client->sendBuffer .= $data;
352 114
    }
353
354 114
    public function finish(): void
355
    {
356 114
        $this->flush();
357 114
        $this->handle();
358 113
        $this->redirect();
359 113
    }
360
361
    /*
362
     * @param string $name java class name, i.e java.math.BigInteger
363
     */
364
365 24
    public function referenceBegin($name): void
366
    {
367 24
        $this->client->sendBuffer .= $this->client->preparedToSendBuffer;
368 24
        $this->client->preparedToSendBuffer = null;
369 24
        $signature = sprintf('<H p="1" v="%s">', $name);
370 24
        $this->write($signature);
371 24
        $signature[6] = '2';
372 24
        $this->client->currentArgumentsFormat = $signature;
373 24
    }
374
375 24
    public function referenceEnd(): void
376
    {
377 24
        $format = '</H>';
378 24
        $this->client->currentArgumentsFormat .= $format;
379 24
        $this->write($format);
380 24
        $this->finish();
381 24
        $this->client->currentCacheKey = null;
382 24
    }
383
384
    /**
385
     * @param string $name java class name i.e java.math.BigInteger
386
     */
387 72
    public function createObjectBegin($name): void
388
    {
389 72
        $this->client->sendBuffer .= $this->client->preparedToSendBuffer;
390 72
        $this->client->preparedToSendBuffer = null;
391 72
        $signature = sprintf('<K p="1" v="%s">', $name);
392 72
        $this->write($signature);
393 72
        $signature[6] = '2';
394 72
        $this->client->currentArgumentsFormat = $signature;
395 72
    }
396
397 72
    public function createObjectEnd(): void
398
    {
399 72
        $format = '</K>';
400 72
        $this->client->currentArgumentsFormat .= $format;
401 72
        $this->write($format);
402 72
        $this->finish();
403 71
        $this->client->currentCacheKey = null;
404 71
    }
405
406
    /**
407
     * @param int    $object object id
408
     * @param string $method method name
409
     */
410 24
    public function propertyAccessBegin($object, $method): void
411
    {
412 24
        $this->client->sendBuffer .= $this->client->preparedToSendBuffer;
413 24
        $this->client->preparedToSendBuffer = null;
414 24
        $this->write(sprintf('<G p="1" v="%x" m="%s">', $object, $method));
415 24
        $this->client->currentArgumentsFormat = "<G p=\"2\" v=\"%x\" m=\"${method}\">";
416 24
    }
417
418 24
    public function propertyAccessEnd(): void
419
    {
420 24
        $format = '</G>';
421 24
        $this->client->currentArgumentsFormat .= $format;
422 24
        $this->write($format);
423 24
        $this->finish();
424 24
        $this->client->currentCacheKey = null;
425 24
    }
426
427
    /**
428
     * @param int    $object_id object id
429
     * @param string $method    method name
430
     */
431 106
    public function invokeBegin($object_id, $method): void
432
    {
433 106
        $this->client->sendBuffer .= $this->client->preparedToSendBuffer;
434 106
        $this->client->preparedToSendBuffer = null;
435 106
        $this->write(sprintf('<Y p="1" v="%x" m="%s">', $object_id, $method));
436 106
        $this->client->currentArgumentsFormat = "<Y p=\"2\" v=\"%x\" m=\"${method}\">";
437 106
    }
438
439 106
    public function invokeEnd(): void
440
    {
441 106
        $format = '</Y>';
442 106
        $this->client->currentArgumentsFormat .= $format;
443 106
        $this->write($format);
444 106
        $this->finish();
445 106
        $this->client->currentCacheKey = null;
446 106
    }
447
448
    public function resultBegin(): void
449
    {
450
        $this->client->sendBuffer .= $this->client->preparedToSendBuffer;
451
        $this->client->preparedToSendBuffer = null;
452
        $this->write('<R>');
453
    }
454
455
    public function resultEnd(): void
456
    {
457
        $this->client->currentCacheKey = null;
458
        $this->write('</R>');
459
        $this->flush();
460
    }
461
462
    /**
463
     * @param string $name
464
     */
465 85
    public function writeString($name): void
466
    {
467 85
        $format = '<S v="%s"/>';
468 85
        $this->client->currentArgumentsFormat .= $format;
469 85
        $this->write(sprintf($format, htmlspecialchars($name, ENT_COMPAT, $this->internal_encoding)));
470 85
    }
471
472
    /**
473
     * @param bool $boolean
474
     */
475 3
    public function writeBoolean($boolean): void
476
    {
477 3
        $format = '<T v="%s"/>';
478 3
        $this->client->currentArgumentsFormat .= $format;
479 3
        $this->write(sprintf($format, $boolean));
480 3
    }
481
482
    /**
483
     * @param int $l
484
     */
485 25
    public function writeLong($l): void
486
    {
487 25
        $this->client->currentArgumentsFormat .= '<J v="%d"/>';
488 25
        if ($l < 0) {
489
            $this->write(sprintf('<L v="%x" p="A"/>', -$l));
490
        } else {
491 25
            $this->write(sprintf('<L v="%x" p="O"/>', $l));
492
        }
493 25
    }
494
495
    /**
496
     * @param mixed $l
497
     */
498
    public function writeULong($l): void
499
    {
500
        $format = '<L v="%x" p="O"/>';
501
        $this->client->currentArgumentsFormat .= $format;
502
        $this->write(sprintf($format, $l));
503
    }
504
505
    /**
506
     * @param float $d
507
     */
508 4
    public function writeDouble($d): void
509
    {
510 4
        $format = '<D v="%.14e"/>';
511 4
        $this->client->currentArgumentsFormat .= $format;
512 4
        $this->write(sprintf($format, $d));
513 4
    }
514
515
    /**
516
     * @param string|int|null $object
517
     */
518 98
    public function writeObject($object): void
519
    {
520 98
        $format = '<O v="%x"/>';
521 98
        $this->client->currentArgumentsFormat .= $format;
522 98
        $this->write(sprintf($format, $object));
523 98
    }
524
525
    /**
526
     * @param int    $object
527
     * @param string $str
528
     */
529
    public function writeException($object, $str): void
530
    {
531
        $this->write(sprintf('<E v="%x" m="%s"/>', $object, htmlspecialchars($str, ENT_COMPAT, $this->internal_encoding)));
532
    }
533
534 1
    public function writeCompositeBegin_a(): void
535
    {
536 1
        $this->write('<X t="A">');
537 1
    }
538
539 13
    public function writeCompositeBegin_h(): void
540
    {
541 13
        $this->write('<X t="H">');
542 13
    }
543
544 14
    public function writeCompositeEnd(): void
545
    {
546 14
        $this->write('</X>');
547 14
    }
548
549
    /**
550
     * @param string $key
551
     */
552 10
    public function writePairBegin_s($key): void
553
    {
554 10
        $this->write(sprintf('<P t="S" v="%s">', htmlspecialchars($key, ENT_COMPAT, 'ISO-8859-1')));
555 10
    }
556
557
    /**
558
     * @param int $key
559
     */
560 7
    public function writePairBegin_n($key): void
561
    {
562 7
        $this->write(sprintf('<P t="N" v="%x">', $key));
563 7
    }
564
565
    public function writePairBegin(): void
566
    {
567
        $this->write('<P>');
568
    }
569
570 13
    public function writePairEnd(): void
571
    {
572 13
        $this->write('</P>');
573 13
    }
574
575
    /**
576
     * @param int $object
577
     */
578 107
    public function writeUnref($object): void
579
    {
580 107
        $this->client->sendBuffer .= $this->client->preparedToSendBuffer;
581 107
        $this->client->preparedToSendBuffer = null;
582 107
        $this->write(sprintf('<U v="%x"/>', $object));
583 107
    }
584
585
    /**
586
     * @return string
587
     */
588 1
    public function getServerName(): string
589
    {
590 1
        return $this->serverName;
591
    }
592
593
    /**
594
     * @param int $code
595
     */
596
    public function writeExitCode($code): void
597
    {
598
        $this->client->sendBuffer .= $this->client->preparedToSendBuffer;
599
        $this->client->preparedToSendBuffer = null;
600
        $this->write(sprintf('<Z v="%x"/>', 0xffffffff & $code));
601
    }
602
}
603