Code Coverage
 
Lines
Functions and Methods
Classes and Traits
Total
0.00% covered (danger)
0.00%
0 / 89
0.00% covered (danger)
0.00%
0 / 3
CRAP
0.00% covered (danger)
0.00%
0 / 1
VaultPress_IXR_SSL_Client
0.00% covered (danger)
0.00%
0 / 86
0.00% covered (danger)
0.00%
0 / 3
702
0.00% covered (danger)
0.00%
0 / 1
 __construct
0.00% covered (danger)
0.00%
0 / 3
0.00% covered (danger)
0.00%
0 / 1
6
 ssl
0.00% covered (danger)
0.00%
0 / 5
0.00% covered (danger)
0.00%
0 / 1
12
 query
0.00% covered (danger)
0.00%
0 / 78
0.00% covered (danger)
0.00%
0 / 1
462
1<?php
2
3// don't call the file directly
4defined( 'ABSPATH' ) || die( 0 );
5
6if ( !class_exists( 'IXR_Client' ) )
7    include_once( ABSPATH . WPINC . '/class-IXR.php' );
8
9class VaultPress_IXR_SSL_Client extends IXR_Client {
10    var $ssl = false;
11    function __construct( $server, $path = false, $port = 80, $timeout = false, $useragent = false ) {
12        parent::__construct( $server, $path, $port, $timeout );
13        if ( ! empty( $useragent ) ) {
14            $this->useragent = $useragent;
15        }
16    }
17    function ssl( $port=443 ) {
18        if ( !extension_loaded( 'openssl' ) )
19            return;
20
21        $this->ssl = true;
22        if ( $port )
23            $this->port = $port;
24    }
25    /**
26     * Perform the IXR request.
27     *
28     * @param string[] ...$args IXR args.
29     *
30     * @return bool True if request succeeded, false otherwise.
31     */
32    function query( ...$args ) {
33        $method = array_shift($args);
34        $request = new IXR_Request($method, $args);
35        $length = $request->getLength();
36        $xml = $request->getXml();
37        $r = "\r\n";
38        $request  = "POST {$this->path} HTTP/1.0$r";
39
40        $this->headers['Host']           = preg_replace( '#^ssl://#', '', $this->server );
41        $this->headers['Content-Type']   = 'text/xml';
42        $this->headers['User-Agent']     = $this->useragent;
43        $this->headers['Content-Length'] = $length;
44
45        $sslverify = true;
46        if ( defined( 'VAULTPRESS_NO_SSL' ) && VAULTPRESS_NO_SSL ) {
47            $sslverify = false;
48        }
49        if ( class_exists( 'WP_Http' ) ) {
50            $args = array(
51                'method' => 'POST',
52                'body' => $xml,
53                'headers' => $this->headers,
54                'sslverify' => $sslverify,
55                );
56            if ( $this->timeout )
57                $args['timeout'] = $this->timeout;
58
59            $http = new WP_Http();
60            if ( $this->ssl )
61                $url = sprintf( 'https://%s%s', $this->server, $this->path );
62            else
63                $url = sprintf( 'http://%s%s', $this->server, $this->path );
64
65            $result = $http->request( $url, $args );
66            if ( is_wp_error( $result ) ) {
67                foreach( $result->errors as $type => $messages ) {
68                    $this->error = new IXR_Error(
69                        -32702,
70                        sprintf( 'WP_Http error: %s, %s', $type, $messages[0] )
71                    );
72                    break;
73                }
74                return false;
75            } else if ( $result['response']['code'] > 299 || $result['response']['code'] < 200 ) {
76                $this->error = new IXR_Error(
77                    -32701,
78                    sprintf( 'Server rejected request (HTTP response: %s %s)', $result['response']['code'], $result['response']['message'])
79                );
80                return false;
81            }
82            // Now parse what we've got back
83            $this->message = new IXR_Message( $result['body'] );
84        } else {
85            foreach( $this->headers as $header => $value ) {
86                $request .= "{$header}: {$value}{$r}";
87            }
88            $request .= $r;
89
90            $request .= $xml;
91            // Now send the request
92            if ( $this->ssl )
93                $host = 'ssl://'.$this->server;
94            else
95                $host = $this->server;
96            if ($this->timeout) {
97                $fp = @fsockopen( $host, $this->port, $errno, $errstr, $this->timeout );
98            } else {
99                $fp = @fsockopen( $host, $this->port, $errno, $errstr );
100            }
101            if (!$fp) {
102                $this->error = new IXR_Error( -32300, "Transport error - could not open socket: $errno $errstr" );
103                return false;
104            }
105            // phpcs:ignore WordPress.WP.AlternativeFunctions.file_system_operations_fwrite -- This is writing a socket, not the filesystem.
106            fwrite( $fp, $request );
107
108            $contents = '';
109            $gotFirstLine = false;
110            $gettingHeaders = true;
111
112            while ( !feof($fp) ) {
113                $line = fgets( $fp, 4096 );
114                if ( !$gotFirstLine ) {
115                    // Check line for '200'
116                    if ( strstr($line, '200') === false ) {
117                        $this->error = new IXR_Error( -32301, 'transport error - HTTP status code was not 200' );
118                        return false;
119                    }
120                    $gotFirstLine = true;
121                }
122                if ( trim($line) == '' ) {
123                    $gettingHeaders = false;
124                }
125                if ( !$gettingHeaders ) {
126                    $contents .= trim( $line );
127                }
128            }
129            // Now parse what we've got back
130            $this->message = new IXR_Message( $contents );
131        }
132        if ( !$this->message->parse() ) {
133            // XML error
134            $this->error = new IXR_Error( -32700, 'parse error. not well formed' );
135            return false;
136        }
137        // Is the message a fault?
138        if ( $this->message->messageType == 'fault' ) {
139            $this->error = new IXR_Error( $this->message->faultCode, $this->message->faultString );
140            return false;
141        }
142        // Message must be OK
143        return true;
144    }
145}