class-wp-http-ixr-client.php 3.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127
  1. <?php
  2. /**
  3. * WP_HTTP_IXR_Client
  4. *
  5. * @package WordPress
  6. * @since 3.1.0
  7. */
  8. #[AllowDynamicProperties]
  9. class WP_HTTP_IXR_Client extends IXR_Client {
  10. public $scheme;
  11. /**
  12. * @var IXR_Error
  13. */
  14. public $error;
  15. /**
  16. * @param string $server
  17. * @param string|false $path
  18. * @param int|false $port
  19. * @param int $timeout
  20. */
  21. public function __construct( $server, $path = false, $port = false, $timeout = 15 ) {
  22. if ( ! $path ) {
  23. // Assume we have been given a URL instead.
  24. $bits = parse_url( $server );
  25. $this->scheme = $bits['scheme'];
  26. $this->server = $bits['host'];
  27. $this->port = isset( $bits['port'] ) ? $bits['port'] : $port;
  28. $this->path = ! empty( $bits['path'] ) ? $bits['path'] : '/';
  29. // Make absolutely sure we have a path.
  30. if ( ! $this->path ) {
  31. $this->path = '/';
  32. }
  33. if ( ! empty( $bits['query'] ) ) {
  34. $this->path .= '?' . $bits['query'];
  35. }
  36. } else {
  37. $this->scheme = 'http';
  38. $this->server = $server;
  39. $this->path = $path;
  40. $this->port = $port;
  41. }
  42. $this->useragent = 'The Incutio XML-RPC PHP Library';
  43. $this->timeout = $timeout;
  44. }
  45. /**
  46. * @since 3.1.0
  47. * @since 5.5.0 Formalized the existing `...$args` parameter by adding it
  48. * to the function signature.
  49. *
  50. * @return bool
  51. */
  52. public function query( ...$args ) {
  53. $method = array_shift( $args );
  54. $request = new IXR_Request( $method, $args );
  55. $xml = $request->getXml();
  56. $port = $this->port ? ":$this->port" : '';
  57. $url = $this->scheme . '://' . $this->server . $port . $this->path;
  58. $args = array(
  59. 'headers' => array( 'Content-Type' => 'text/xml' ),
  60. 'user-agent' => $this->useragent,
  61. 'body' => $xml,
  62. );
  63. // Merge Custom headers ala #8145.
  64. foreach ( $this->headers as $header => $value ) {
  65. $args['headers'][ $header ] = $value;
  66. }
  67. /**
  68. * Filters the headers collection to be sent to the XML-RPC server.
  69. *
  70. * @since 4.4.0
  71. *
  72. * @param string[] $headers Associative array of headers to be sent.
  73. */
  74. $args['headers'] = apply_filters( 'wp_http_ixr_client_headers', $args['headers'] );
  75. if ( false !== $this->timeout ) {
  76. $args['timeout'] = $this->timeout;
  77. }
  78. // Now send the request.
  79. if ( $this->debug ) {
  80. echo '<pre class="ixr_request">' . htmlspecialchars( $xml ) . "\n</pre>\n\n";
  81. }
  82. $response = wp_remote_post( $url, $args );
  83. if ( is_wp_error( $response ) ) {
  84. $errno = $response->get_error_code();
  85. $errorstr = $response->get_error_message();
  86. $this->error = new IXR_Error( -32300, "transport error: $errno $errorstr" );
  87. return false;
  88. }
  89. if ( 200 !== wp_remote_retrieve_response_code( $response ) ) {
  90. $this->error = new IXR_Error( -32301, 'transport error - HTTP status code was not 200 (' . wp_remote_retrieve_response_code( $response ) . ')' );
  91. return false;
  92. }
  93. if ( $this->debug ) {
  94. echo '<pre class="ixr_response">' . htmlspecialchars( wp_remote_retrieve_body( $response ) ) . "\n</pre>\n\n";
  95. }
  96. // Now parse what we've got back.
  97. $this->message = new IXR_Message( wp_remote_retrieve_body( $response ) );
  98. if ( ! $this->message->parse() ) {
  99. // XML error.
  100. $this->error = new IXR_Error( -32700, 'parse error. not well formed' );
  101. return false;
  102. }
  103. // Is the message a fault?
  104. if ( 'fault' === $this->message->messageType ) {
  105. $this->error = new IXR_Error( $this->message->faultCode, $this->message->faultString );
  106. return false;
  107. }
  108. // Message must be OK.
  109. return true;
  110. }
  111. }