StreamEncryption::__construct()   A
last analyzed

Complexity

Conditions 4
Paths 8

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 17
ccs 11
cts 11
cp 1
rs 9.2
c 1
b 0
f 0
cc 4
eloc 10
nc 8
nop 1
crap 4
1
<?php
2
3
namespace Thruster\Component\SocketClient;
4
5
use Thruster\Component\EventLoop\EventLoopInterface;
6
use Thruster\Component\Promise\Deferred;
7
use Thruster\Component\Stream\Stream;
8
use UnexpectedValueException;
9
10
/**
11
 * Class StreamEncryption
12
 *
13
 * @package Thruster\Component\SocketClient
14
 * @author  Aurimas Niekis <[email protected]>
15
 */
16
class StreamEncryption
17
{
18
    /**
19
     * @var EventLoopInterface
20
     */
21
    private $loop;
22
23
    /**
24
     * @var int
25
     */
26
    private $method;
27
28
    /**
29
     * @var string
30
     */
31
    private $errStr;
32
33
    /**
34
     * @var int
35
     */
36
    private $errno;
37
38
    /**
39
     * @var bool
40
     */
41
    private $wrapSecure;
42
43 1
    public function __construct(EventLoopInterface $loop)
44
    {
45 1
        $this->method     = STREAM_CRYPTO_METHOD_TLS_CLIENT;
46 1
        $this->wrapSecure = false;
47
48 1
        $this->loop = $loop;
49
50 1
        if (defined('STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT')) {
51 1
            $this->method |= STREAM_CRYPTO_METHOD_TLSv1_0_CLIENT;
52
        }
53 1
        if (defined('STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT')) {
54 1
            $this->method |= STREAM_CRYPTO_METHOD_TLSv1_1_CLIENT;
55
        }
56 1
        if (defined('STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT')) {
57 1
            $this->method |= STREAM_CRYPTO_METHOD_TLSv1_2_CLIENT;
58
        }
59 1
    }
60
61 1
    public function enable(Stream $stream)
62
    {
63 1
        return $this->toggle($stream, true);
64
    }
65
66
    public function disable(Stream $stream)
67
    {
68
        return $this->toggle($stream, false);
69
    }
70
71 1
    public function toggle(Stream $stream, $toggle)
72
    {
73 1
        if ($stream instanceof SecureStream) {
74
            $stream = $stream->getDecorating();
75
        }
76
77
        // pause actual stream instance to continue operation on raw stream socket
78 1
        $stream->pause();
79
80
        // TODO: add write() event to make sure we're not sending any excessive data
81
82 1
        $deferred = new Deferred();
83
84
        // get actual stream socket from stream instance
85 1
        $socket = $stream->getStream();
86
87
        $toggleCrypto = function () use ($socket, $deferred, $toggle) {
88 1
            $this->toggleCrypto($socket, $deferred, $toggle);
89 1
        };
90
91 1
        $this->loop->addReadStream($socket, $toggleCrypto);
92 1
        $toggleCrypto();
93
94
        return $deferred->promise()->then(function () use ($stream, $toggle) {
95 1
            if ($toggle && $this->wrapSecure) {
96
                return new SecureStream($stream, $this->loop);
97
            }
98
99 1
            $stream->resume();
100
101 1
            return $stream;
102 1
        }, function ($error) use ($stream) {
103
            $stream->resume();
104
            throw $error;
105 1
        });
106
    }
107
108 1
    public function toggleCrypto($socket, Deferred $deferred, $toggle)
109
    {
110
        //set_error_handler([$this, 'handleError']);
0 ignored issues
show
Unused Code Comprehensibility introduced by
80% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
111 1
        $result = stream_socket_enable_crypto($socket, $toggle, $this->method);
112
        //restore_error_handler();
113
114 1
        if (true === $result) {
115 1
            $this->loop->removeReadStream($socket);
116
117 1
            $deferred->resolve();
118 1
        } elseif (false === $result) {
119
            $this->loop->removeReadStream($socket);
120
121
            $deferred->reject(new UnexpectedValueException(
122
                sprintf('Unable to complete SSL/TLS handshake: %s', $this->errStr),
123
                $this->errno
124
            ));
125
        } else {
0 ignored issues
show
Unused Code introduced by
This else statement is empty and can be removed.

This check looks for the else branches of if statements that have no statements or where all statements have been commented out. This may be the result of changes for debugging or the code may simply be obsolete.

These else branches can be removed.

if (rand(1, 6) > 3) {
print "Check failed";
} else {
    //print "Check succeeded";
}

could be turned into

if (rand(1, 6) > 3) {
    print "Check failed";
}

This is much more concise to read.

Loading history...
126
            // need more data, will retry
127
        }
128 1
    }
129
130
    public function handleError($errNo, $errStr)
131
    {
132
        $this->errstr = str_replace(["\r", "\n"], ' ', $errStr);
0 ignored issues
show
Bug introduced by
The property errstr does not seem to exist. Did you mean errStr?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
133
        $this->errno  = $errNo;
134
    }
135
}
136