init_response(); $url = $args['url'] ?? null; $headers = $args['headers'] ?? array(); $body = $args['body'] ?? array(); $method = $args['method'] ?? 'GET'; $response = $this->process_request( $url, $headers, $body, $method ); if ( is_wp_error( $response ) ) { $this->response->set_status( 500 ); $this->response->set_data( $response->get_error_message() ); } else { $this->response->set_status( $response['code'] ?? 500 ); $this->response->set_data( $response['body'] ?? null ); } return $this->get_response(); } /** * Initializes the response property to WP_HTTP_Response object. * * @param array $args * * @return void */ protected function init_response( array $args = array() ) { $this->response = new WP_HTTP_Response(); } /** * @param string $url * @param array $headers * @param array $body * @param string $method * * @return array|WP_Error */ private function process_request( ?string $url = null, array $headers = array(), array $body = array(), string $method = 'GET' ) { if ( empty( $url ) ) { return new WP_Error( 'invalid_request_data', __( 'Missing url.', 'broken-link-checker' ) ); } if ( ! in_array( $method, array( 'GET', 'POST', 'PATCH' ) ) ) { $method = 'GET'; } $response = null; $args = apply_filters( 'wpmudev_blc_http_request_args', array( 'headers' => $headers, 'body' => wp_json_encode( is_array( $body ) ? $body : array() ), ), $url, $headers, $body, $method ); // Logging request args. Only if wp debugging is active. Sensitive // headers are masked so secrets are never written to the log. Utilities::log( "Processing request with following params : \nURL: {$url} \nArgs:" . var_export( self::mask_sensitive_headers( $args ), true ) ); switch ( $method ) { case 'POST' : $response = wp_remote_post( $url, $args ); break; case 'PATCH': $response = wp_remote_request( $url, $args ); break; case 'GET': $response = wp_remote_get( $url, array( 'headers' => $headers, ) ); break; } return array( 'code' => wp_remote_retrieve_response_code( $response ), 'body' => wp_remote_retrieve_body( $response ), ); } /** * Returns a copy of the request args with sensitive header values masked, * safe to be written to the debug log. * * @param array $args Request args. * * @return array */ public static function mask_sensitive_headers( array $args ): array { if ( isset( $args['headers']['Authorization'] ) && is_string( $args['headers']['Authorization'] ) ) { $args['headers']['Authorization'] = self::mask_key( $args['headers']['Authorization'] ); } return $args; } /** * Masks a key, keeping only its first and last four characters. * * @param string $key The key to mask. * * @return string */ private static function mask_key( string $key ): string { $length = strlen( $key ); if ( $length <= 8 ) { return str_repeat( '*', $length ); } return substr( $key, 0, 4 ) . str_repeat( '*', $length - 8 ) . substr( $key, -4 ); } /** * Returns the response param. * * @return WP_HTTP_Response */ public function get_response() { return $this->response; } /** * Returns the response status. * * @return int */ public function get_status() { return $this->response->get_status(); } /** * Returns the response data. * * @return mixed Response data */ public function get_data() { return $this->response->get_data(); } public function set_status( int $code = 200 ) { $this->response->set_status( absint( $code ) ); } public function set_data( $data = null ) { $this->response->set_status( $data ); } }