|
1 <?php |
|
2 |
|
3 /** |
|
4 * IXR_Client |
|
5 * |
|
6 * @package IXR |
|
7 * @since 1.5.0 |
|
8 * |
|
9 */ |
|
10 class IXR_Client |
|
11 { |
|
12 var $server; |
|
13 var $port; |
|
14 var $path; |
|
15 var $useragent; |
|
16 var $response; |
|
17 var $message = false; |
|
18 var $debug = false; |
|
19 var $timeout; |
|
20 var $headers = array(); |
|
21 |
|
22 // Storage place for an error message |
|
23 var $error = false; |
|
24 |
|
25 /** |
|
26 * PHP5 constructor. |
|
27 */ |
|
28 function __construct( $server, $path = false, $port = 80, $timeout = 15 ) |
|
29 { |
|
30 if (!$path) { |
|
31 // Assume we have been given a URL instead |
|
32 $bits = parse_url($server); |
|
33 $this->server = $bits['host']; |
|
34 $this->port = isset($bits['port']) ? $bits['port'] : 80; |
|
35 $this->path = isset($bits['path']) ? $bits['path'] : '/'; |
|
36 |
|
37 // Make absolutely sure we have a path |
|
38 if (!$this->path) { |
|
39 $this->path = '/'; |
|
40 } |
|
41 |
|
42 if ( ! empty( $bits['query'] ) ) { |
|
43 $this->path .= '?' . $bits['query']; |
|
44 } |
|
45 } else { |
|
46 $this->server = $server; |
|
47 $this->path = $path; |
|
48 $this->port = $port; |
|
49 } |
|
50 $this->useragent = 'The Incutio XML-RPC PHP Library'; |
|
51 $this->timeout = $timeout; |
|
52 } |
|
53 |
|
54 /** |
|
55 * PHP4 constructor. |
|
56 */ |
|
57 public function IXR_Client( $server, $path = false, $port = 80, $timeout = 15 ) { |
|
58 self::__construct( $server, $path, $port, $timeout ); |
|
59 } |
|
60 |
|
61 function query() |
|
62 { |
|
63 $args = func_get_args(); |
|
64 $method = array_shift($args); |
|
65 $request = new IXR_Request($method, $args); |
|
66 $length = $request->getLength(); |
|
67 $xml = $request->getXml(); |
|
68 $r = "\r\n"; |
|
69 $request = "POST {$this->path} HTTP/1.0$r"; |
|
70 |
|
71 // Merged from WP #8145 - allow custom headers |
|
72 $this->headers['Host'] = $this->server; |
|
73 $this->headers['Content-Type'] = 'text/xml'; |
|
74 $this->headers['User-Agent'] = $this->useragent; |
|
75 $this->headers['Content-Length']= $length; |
|
76 |
|
77 foreach( $this->headers as $header => $value ) { |
|
78 $request .= "{$header}: {$value}{$r}"; |
|
79 } |
|
80 $request .= $r; |
|
81 |
|
82 $request .= $xml; |
|
83 |
|
84 // Now send the request |
|
85 if ($this->debug) { |
|
86 echo '<pre class="ixr_request">'.htmlspecialchars($request)."\n</pre>\n\n"; |
|
87 } |
|
88 |
|
89 if ($this->timeout) { |
|
90 $fp = @fsockopen($this->server, $this->port, $errno, $errstr, $this->timeout); |
|
91 } else { |
|
92 $fp = @fsockopen($this->server, $this->port, $errno, $errstr); |
|
93 } |
|
94 if (!$fp) { |
|
95 $this->error = new IXR_Error(-32300, 'transport error - could not open socket'); |
|
96 return false; |
|
97 } |
|
98 fputs($fp, $request); |
|
99 $contents = ''; |
|
100 $debugContents = ''; |
|
101 $gotFirstLine = false; |
|
102 $gettingHeaders = true; |
|
103 while (!feof($fp)) { |
|
104 $line = fgets($fp, 4096); |
|
105 if (!$gotFirstLine) { |
|
106 // Check line for '200' |
|
107 if (strstr($line, '200') === false) { |
|
108 $this->error = new IXR_Error(-32300, 'transport error - HTTP status code was not 200'); |
|
109 return false; |
|
110 } |
|
111 $gotFirstLine = true; |
|
112 } |
|
113 if (trim($line) == '') { |
|
114 $gettingHeaders = false; |
|
115 } |
|
116 if (!$gettingHeaders) { |
|
117 // merged from WP #12559 - remove trim |
|
118 $contents .= $line; |
|
119 } |
|
120 if ($this->debug) { |
|
121 $debugContents .= $line; |
|
122 } |
|
123 } |
|
124 if ($this->debug) { |
|
125 echo '<pre class="ixr_response">'.htmlspecialchars($debugContents)."\n</pre>\n\n"; |
|
126 } |
|
127 |
|
128 // Now parse what we've got back |
|
129 $this->message = new IXR_Message($contents); |
|
130 if (!$this->message->parse()) { |
|
131 // XML error |
|
132 $this->error = new IXR_Error(-32700, 'parse error. not well formed'); |
|
133 return false; |
|
134 } |
|
135 |
|
136 // Is the message a fault? |
|
137 if ($this->message->messageType == 'fault') { |
|
138 $this->error = new IXR_Error($this->message->faultCode, $this->message->faultString); |
|
139 return false; |
|
140 } |
|
141 |
|
142 // Message must be OK |
|
143 return true; |
|
144 } |
|
145 |
|
146 function getResponse() |
|
147 { |
|
148 // methodResponses can only have one param - return that |
|
149 return $this->message->params[0]; |
|
150 } |
|
151 |
|
152 function isError() |
|
153 { |
|
154 return (is_object($this->error)); |
|
155 } |
|
156 |
|
157 function getErrorCode() |
|
158 { |
|
159 return $this->error->code; |
|
160 } |
|
161 |
|
162 function getErrorMessage() |
|
163 { |
|
164 return $this->error->message; |
|
165 } |
|
166 } |