/**
  * Prepares the given HTTP-query-string for the HTTP-request.
  *
  * HTTP-query-strings always should be utf8-encoded and urlencoded afterwards.
  * So "/path/file?test=tatütata" will be converted to "/path/file?test=tat%C3%BCtata":
  *
  * @param stirng The quetry-string (like "/path/file?test=tatütata")
  * @return string
  */
 protected function prepareHTTPRequestQuery($query)
 {
     // If string already is a valid URL -> do nothing
     if (PHPCrawlerUtils::isValidUrlString($query)) {
         return $query;
     }
     // Decode query-string (for URLs that are partly urlencoded and partly not)
     $query = rawurldecode($query);
     // if query is already utf-8 encoded -> simply urlencode it,
     // otherwise encode it to utf8 first.
     if (PHPCrawlerEncodingUtils::isUTF8String($query) == true) {
         $query = rawurlencode($query);
     } else {
         $query = rawurlencode(utf8_encode($query));
     }
     // Replace url-specific signs back
     $query = str_replace("%2F", "/", $query);
     $query = str_replace("%3F", "?", $query);
     $query = str_replace("%3D", "=", $query);
     $query = str_replace("%26", "&", $query);
     return $query;
 }
 /**
  * Reconstructs a full qualified and normalized URL from a given link relating to the URL the link was found in.
  *
  * @param string $link                           The link (i.e. "../page.htm")
  * @param PHPCrawlerUrlPartsDescriptor $BaseUrl  The base-URL the link was found in as PHPCrawlerUrlPartsDescriptor-object
  *
  * @return string The rebuild, full qualified and normilazed URL the link is leading to (i.e. "http://www.foo.com/page.htm"),
  *                or NULL if the link couldn't be rebuild correctly.
  */
 public static function buildURLFromLink($link, PHPCrawlerUrlPartsDescriptor $BaseUrl)
 {
     $url_parts = $BaseUrl->toArray();
     // Dedoce HTML-entities
     $link = PHPCrawlerEncodingUtils::decodeHtmlEntities($link);
     // Remove anchor ("#..."), but ONLY at the end, not if # is at the beginning !
     $link = preg_replace("/^(.{1,})#.{0,}\$/", "\\1", $link);
     // Cases
     // Strange link like "//foo.htm" -> make it to "http://foo.html"
     if (substr($link, 0, 2) == "//") {
         $link = "http:" . $link;
     } elseif (substr($link, 0, 1) == "/") {
         $link = $url_parts["protocol"] . $url_parts["host"] . ":" . $url_parts["port"] . $link;
     } elseif (substr($link, 0, 2) == "./") {
         $link = $url_parts["protocol"] . $url_parts["host"] . ":" . $url_parts["port"] . $url_parts["path"] . substr($link, 2);
     } elseif (preg_match("#^[a-z0-9-]{1,}(:\\/\\/)# i", $link)) {
         $link = $link;
     } elseif (preg_match("/^[a-zA-Z]{0,}:[^\\/]{0,1}/", $link)) {
         $link = "";
     } elseif (substr($link, 0, 3) == "../") {
         $new_path = $url_parts["path"];
         while (substr($link, 0, 3) == "../") {
             $new_path = preg_replace('/\\/[^\\/]{0,}\\/$/', "/", $new_path);
             $link = substr($link, 3);
         }
         $link = $url_parts["protocol"] . $url_parts["host"] . ":" . $url_parts["port"] . $new_path . $link;
     } elseif (substr($link, 0, 1) == "#") {
         $link = "";
     } elseif (substr($link, 0, 1) == "?") {
         $link = $url_parts["protocol"] . $url_parts["host"] . ":" . $url_parts["port"] . $url_parts["path"] . $url_parts["file"] . $link;
     } else {
         $link = $url_parts["protocol"] . $url_parts["host"] . ":" . $url_parts["port"] . $url_parts["path"] . $link;
     }
     if ($link == "") {
         return null;
     }
     // Now, at least, replace all HTMLENTITIES with normal text.
     // I.E.: HTML-Code of the link is: <a href="index.php?x=1&amp;y=2">
     // -> Link has to be "index.php?x=1&y=2"
     //$link = PHPCrawlerEncodingUtils::decodeHtmlEntities($link);
     // Replace linebreaks in the link with "" (happens if a link in the sourcecode
     // linebreaks)
     $link = str_replace(array("\n", "\r"), "", $link);
     // "Normalize" URL
     $link = self::normalizeUrl($link);
     return $link;
 }