Completed
Pull Request — master (#64)
by
unknown
01:32
created

HTTPClient::setupCurlOpts()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

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