Completed
Pull Request — master (#82)
by
unknown
01:30
created

HTTPClient::sendFrame()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

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