/** * Gets the Pingback endpoint URI provided by a web page specified by URL * * @return string|boolean Returns the Pingback endpoint URI if found or false */ function get_endpoint_uri($url) { // First check for an X-pingback header if (!($response = nxt_remote_head($url))) { return false; } if (!($content_type = nxt_remote_retrieve_header($response, 'content-type'))) { return false; } if (preg_match('#(image|audio|video|model)/#is', $content_type)) { return false; } if ($x_pingback = nxt_remote_retrieve_header($response, 'x-pingback')) { return trim($x_pingback); } // Fall back to extracting it from the HTML link if (!($response = nxt_remote_get($url))) { return false; } if (200 !== nxt_remote_retrieve_response_code($response)) { return false; } if ('' === ($response_body = nxt_remote_retrieve_body($response))) { return false; } if (!preg_match_all('@<link([^>]+)>@im', $response_body, $response_links)) { return false; } foreach ($response_links[1] as $response_link_attributes) { $_link = array('rel' => false, 'href' => false); $response_link_attributes = preg_split('@\\s+@im', $response_link_attributes, -1, PREG_SPLIT_NO_EMPTY); foreach ($response_link_attributes as $response_link_attribute) { if ($_link['rel'] == 'pingback' && $_link['href']) { return $_link['href']; } if (strpos($response_link_attribute, '=', 1) !== false) { list($_key, $_value) = explode('=', $response_link_attribute, 2); $_link[strtolower($_key)] = trim($_value, "'\""); } } } // Fail return false; }
/** * Retrieve HTTP Headers from URL. * * @since 1.5.1 * * @param string $url * @param bool $deprecated Not Used. * @return bool|string False on failure, headers on success. */ function nxt_get_http_headers($url, $deprecated = false) { if (!empty($deprecated)) { _deprecated_argument(__FUNCTION__, '2.7'); } $response = nxt_remote_head($url); if (is_nxt_error($response)) { return false; } return nxt_remote_retrieve_headers($response); }
/** * Finds a pingback server URI based on the given URL. * * Checks the HTML for the rel="pingback" link and x-pingback headers. It does * a check for the x-pingback headers first and returns that, if available. The * check for the rel="pingback" has more overhead than just the header. * * @since 1.5.0 * * @param string $url URL to ping. * @param int $deprecated Not Used. * @return bool|string False on failure, string containing URI on success. */ function discover_pingback_server_uri($url, $deprecated = '') { if (!empty($deprecated)) { _deprecated_argument(__FUNCTION__, '2.7'); } $pingback_str_dquote = 'rel="pingback"'; $pingback_str_squote = 'rel=\'pingback\''; /** @todo Should use Filter Extension or custom preg_match instead. */ $parsed_url = parse_url($url); if (!isset($parsed_url['host'])) { // Not an URL. This should never happen. return false; } //Do not search for a pingback server on our own uploads $uploads_dir = nxt_upload_dir(); if (0 === strpos($url, $uploads_dir['baseurl'])) { return false; } $response = nxt_remote_head($url, array('timeout' => 2, 'httpversion' => '1.0')); if (is_nxt_error($response)) { return false; } if (nxt_remote_retrieve_header($response, 'x-pingback')) { return nxt_remote_retrieve_header($response, 'x-pingback'); } // Not an (x)html, sgml, or xml page, no use going further. if (preg_match('#(image|audio|video|model)/#is', nxt_remote_retrieve_header($response, 'content-type'))) { return false; } // Now do a GET since we're going to look in the html headers (and we're sure its not a binary file) $response = nxt_remote_get($url, array('timeout' => 2, 'httpversion' => '1.0')); if (is_nxt_error($response)) { return false; } $contents = nxt_remote_retrieve_body($response); $pingback_link_offset_dquote = strpos($contents, $pingback_str_dquote); $pingback_link_offset_squote = strpos($contents, $pingback_str_squote); if ($pingback_link_offset_dquote || $pingback_link_offset_squote) { $quote = $pingback_link_offset_dquote ? '"' : '\''; $pingback_link_offset = $quote == '"' ? $pingback_link_offset_dquote : $pingback_link_offset_squote; $pingback_href_pos = @strpos($contents, 'href=', $pingback_link_offset); $pingback_href_start = $pingback_href_pos + 6; $pingback_href_end = @strpos($contents, $quote, $pingback_href_start); $pingback_server_url_len = $pingback_href_end - $pingback_href_start; $pingback_server_url = substr($contents, $pingback_href_start, $pingback_server_url_len); // We may find rel="pingback" but an incomplete pingback URL if ($pingback_server_url_len > 0) { // We got it! return $pingback_server_url; } } return false; }