Completed
Pull Request — master (#85)
by
unknown
01:26
created

HTTPClient::debugLog()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 9

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 9
rs 9.9666
c 0
b 0
f 0
nc 2
cc 2
nop 1
1
<?php
2
3
namespace AfriCC\EPP;
4
5
use AfriCC\EPP\Frame\Command\Logout as LogoutCommand;
6
use Psr\Log\LoggerAwareInterface;
7
use Psr\Log\LoggerAwareTrait;
8
9
/**
10
 * A high level HTTP(S) based client for the Extensible Provisioning Protocol (EPP)
11
 *
12
 * @see http://tools.ietf.org/html/rfc5734
13
 *
14
 * As this class deals directly with cURL it's untestable
15
 * @codeCoverageIgnore
16
 */
17
class HTTPClient extends AbstractClient implements ClientInterface, LoggerAwareInterface
18
{
19
    use LoggerAwareTrait;
20
21
    protected $curl;
22
    protected $cookiejar;
23
    protected $curlDebugStream;
24
25
    public function __construct(array $config, ObjectSpec $objectSpec = null)
26
    {
27
        parent::__construct($config, $objectSpec);
28
29
        $proto = \parse_url($this->host, PHP_URL_SCHEME);
30
        if ($proto == 'https') {
31
            $this->ssl = true;
32
        } else {
33
            $this->ssl = false;
34
        }
35
36
        $this->prepareCookieJar($config);
37
    }
38
39
    protected function prepareCookieJar(array $config)
40
    {
41
        if (!empty($config['cookiejar'])) {
42
            $this->cookiejar = $config['cookiejar'];
43
        } else {
44
            $this->cookiejar = tempnam(sys_get_temp_dir(), 'ehc');
45
        }
46
47
        if (!is_readable($this->cookiejar) || !is_writable($this->cookiejar)) {
48
            throw new \Exception(
49
                sprintf(
50
                    'unable to read/write cookiejar: %s',
51
                    $this->cookiejar
52
                    )
53
                );
54
        }
55
    }
56
57
    public function __destruct()
58
    {
59
        $this->close();
60
    }
61
62
    private function setupCurl()
63
    {
64
        $this->curl = curl_init($this->host);
65
66
        if ($this->curl === false) {
67
            throw new \Exception('Cannot initialize cURL extension');
68
        }
69
70
        $this->setupCurlOpts();
71
72
        // certs
73
        if ($this->ssl) {
74
            $this->setupCurlSSL();
75
        }
76
77
        if ($this->debug) {
78
            $this->setupCurlDebug();
79
        }
80
    }
81
82
    private function setupCurlOpts()
83
    {
84
        // set stream time out
85
        curl_setopt($this->curl, CURLOPT_TIMEOUT, $this->timeout);
86
        curl_setopt(
87
            $this->curl,
88
            CURLOPT_CONNECTTIMEOUT,
89
            $this->connect_timeout
90
            );
91
92
        // set necessary options
93
        curl_setopt($this->curl, CURLOPT_RETURNTRANSFER, true);
94
        curl_setopt($this->curl, CURLOPT_FOLLOWLOCATION, true);
95
        curl_setopt($this->curl, CURLOPT_HEADER, false);
96
97
        // cookies
98
        curl_setopt($this->curl, CURLOPT_COOKIEFILE, $this->cookiejar);
99
        curl_setopt($this->curl, CURLOPT_COOKIEJAR, $this->cookiejar);
100
    }
101
102
    private function setupCurlSSL()
103
    {
104
        curl_setopt($this->curl, CURLOPT_SSL_VERIFYPEER, true);
105
        curl_setopt($this->curl, CURLOPT_SSLKEYTYPE, 'PEM');
106
107
        if ($this->ca_cert) {
108
            curl_setopt($this->curl, CURLOPT_CAINFO, $this->ca_cert);
109
        }
110
        if ($this->pk_cert) {
111
            curl_setopt($this->curl, CURLOPT_SSLKEY, $this->pk_cert);
112
        }
113
        if ($this->local_cert) {
114
            curl_setopt($this->curl, CURLOPT_SSLCERT, $this->local_cert);
115
        }
116
        if ($this->passphrase) {
117
            curl_setopt($this->curl, CURLOPT_SSLCERTPASSWD, $this->passphrase);
118
        }
119
    }
120
121
    private function setupCurlDebug()
122
    {
123
        curl_setopt($this->curl, CURLOPT_VERBOSE, true);
124
        $this->curlDebugStream = fopen('php://temp', 'w+');
125
        curl_setopt($this->curl, CURLOPT_STDERR, $this->curlDebugStream);
126
    }
127
128
    /**
129
     * Open a new connection to the EPP server
130
     *
131
     * @param bool|string $newPassword String with new password to set upon login, false if no password
132
     */
133
    public function connect($newPassword = false)
134
    {
135
        $this->setupCurl();
136
137
        // get greeting
138
        $greeting = $this->request(new \AfriCC\EPP\Frame\Hello($this->objectSpec));
139
140
        // login
141
        $this->login($newPassword);
142
143
        // return greeting
144
        return $greeting;
145
    }
146
147
    /**
148
     * Closes a previously opened EPP connection
149
     */
150
    public function close()
151
    {
152
        if ($this->active()) {
153
            // send logout frame
154
            $this->request(new LogoutCommand($this->objectSpec));
155
156
            return curl_close($this->curl);
157
        }
158
159
        return false;
160
    }
161
162
    public function sendFrame(FrameInterface $frame)
163
    {
164
        $content = (string) $frame;
165
        curl_setopt($this->curl, CURLOPT_POSTFIELDS, $content);
166
    }
167
168
    public function getFrame()
169
    {
170
        $return = curl_exec($this->curl);
171
172
        if ($return === false) {
173
            $code = curl_errno($this->curl);
174
            $msg = curl_error($this->curl);
175
            $this->debugLog("cURL error: $msg");
176
            throw new \Exception($msg, $code);
177
        }
178
179
        return $return;
180
    }
181
182
    protected function debugLog($message)
183
    {
184
        if ($this->debug) {
185
            \error_log($message);
186
            rewind($this->curlDebugStream);
187
            $curlDebug = stream_get_contents($this->curlDebugStream);
188
            \error_log("Full info:\n$curlDebug");
189
        }
190
    }
191
192
    /**
193
     * Check if curl session is still active
194
     *
195
     * @return bool
196
     */
197
    private function active()
198
    {
199
        return is_resource($this->curl);
200
    }
201
}
202