, error: string} */ protected function http_get( string $url, string $label, array &$evidence, array $args = array(), string $outcome = '', string $summary = '' ): array { // Self-scan must survive local/staging certs when probing our OWN // origin — but external requests (e.g. DNS-over-HTTPS resolvers) keep // full TLS verification. $url_host = wp_parse_url( $url, PHP_URL_HOST ); $origin_host = wp_parse_url( home_url( '/' ), PHP_URL_HOST ); $same_origin = is_string( $url_host ) && is_string( $origin_host ) && 0 === strcasecmp( $url_host, $origin_host ); $defaults = array( 'timeout' => 10, 'redirection' => 3, 'user-agent' => 'AJACO-Scanner/' . AJACO_VERSION . ' (+' . home_url( '/' ) . ')', // TLS verification stays ON for external requests (e.g. DNS-over- // HTTPS resolvers). It is relaxed ONLY for probes of the site's own // origin, so a scan still works on a local/staging site behind a // self-signed certificate; the filter re-enables it if desired. 'sslverify' => $same_origin ? apply_filters( 'ajaco_scan_sslverify', false ) : true, ); $response = wp_remote_get( $url, array_merge( $defaults, $args ) ); $evidence[] = Evidence::fetch( $label, $url, $response, $outcome, $summary ); if ( is_wp_error( $response ) ) { return array( 'code' => 0, 'body' => '', 'headers' => array(), 'error' => $response->get_error_message(), ); } $headers = array(); $raw = wp_remote_retrieve_headers( $response ); if ( is_object( $raw ) && method_exists( $raw, 'getAll' ) ) { foreach ( $raw->getAll() as $name => $value ) { $headers[ strtolower( (string) $name ) ] = is_array( $value ) ? implode( ', ', $value ) : (string) $value; } } return array( 'code' => (int) wp_remote_retrieve_response_code( $response ), 'body' => (string) wp_remote_retrieve_body( $response ), 'headers' => $headers, 'error' => '', ); } /** * Shorthand: pass result. * * @param string $message Result message. * @param array $evidence Evidence steps (conclusion appended). * @param array|null $details Structured details. * @return Check_Result */ protected function pass( string $message, array $evidence = array(), $details = null ): Check_Result { $evidence[] = Evidence::conclude( 'positive', $message ); return new Check_Result( Check_Result::STATUS_PASS, $message, $evidence, $details ); } /** * Shorthand: fail result. * * @param string $message Result message. * @param array $evidence Evidence steps (conclusion appended). * @param array|null $details Structured details. * @return Check_Result */ protected function fail( string $message, array $evidence = array(), $details = null ): Check_Result { $evidence[] = Evidence::conclude( 'negative', $message ); return new Check_Result( Check_Result::STATUS_FAIL, $message, $evidence, $details ); } /** * Shorthand: neutral / not-applicable result. * * @param string $message Result message. * @param array $evidence Evidence steps (conclusion appended). * @param array|null $details Structured details. * @return Check_Result */ protected function neutral( string $message, array $evidence = array(), $details = null ): Check_Result { $evidence[] = Evidence::conclude( 'neutral', $message ); return new Check_Result( Check_Result::STATUS_NEUTRAL, $message, $evidence, $details ); } /** * Shorthand: unable-to-check result (network failure etc.). * * @param string $message Result message. * @param array $evidence Evidence steps (conclusion appended). * @return Check_Result */ protected function unable( string $message, array $evidence = array() ): Check_Result { $evidence[] = Evidence::conclude( 'neutral', $message ); return new Check_Result( Check_Result::STATUS_UNABLE, $message, $evidence ); } }