Index: classes/linktype/class.tx_linkvalidator_linktype_external.php
===================================================================
--- classes/linktype/class.tx_linkvalidator_linktype_external.php	(Revision 44948)
+++ classes/linktype/class.tx_linkvalidator_linktype_external.php	(Arbeitskopie)
@@ -47,6 +47,14 @@
 	protected $urlErrorParams = array();
 
 	/**
+	 * List of headers to be used for metching an URL for the current processing
+	 *
+	 * @var array
+	 */
+	protected $additionalHeaders = array();
+
+
+	/**
 	 * Checks a given URL + /path/filename.ext for validity
 	 *
 	 * @param	string		$url: url to check
@@ -56,6 +64,9 @@
 	 */
 	public function checkLink($url, $softRefEntry, $reference) {
 		$errorParams = array();
+		$report = array();
+		$additionalHeaders['User-Agent'] = 'User-Agent: Mozilla/5.0 TYPO3-linkvalidator';
+
 		if (isset($this->urlReports[$url])) {
 			if(!$this->urlReports[$url]) {
 				if(is_array($this->urlErrorParams[$url])) {
@@ -71,23 +82,59 @@
 		}
 
 			// try to fetch the content of the URL (headers only)
-		$report = array();
+		$content = t3lib_div::getURL($url, 2, $additionalHeaders, $report);
 
-			// try fetching the content of the URL (just fetching the headers does not work correctly)
-		$content = '';
-		$content = t3lib_div::getURL($url, 1, FALSE, $report);
-
 		$tries = 0;
+		$currentUrl = $url;
+		$haveNewUrl = FALSE;
+		$location = array();
+		$cookie = array();
 		while (($report['http_code'] == 301 || $report['http_code'] == 302
 			|| $report['http_code'] == 303 || $report['http_code'] == 307)
 			&& ($tries < 5)) {
-				$isCodeRedirect = preg_match('/Location: (.*)/', $content, $location);
-				if (isset($location[1])) {
-					$content = t3lib_div::getURL($location[1], 2, FALSE, $report);
+
+				// split header into lines and parse them
+			$responseHeaders = t3lib_div::trimExplode(chr(10), $content, TRUE);
+			$cookies = '';
+
+			foreach($responseHeaders as $line) {
+
+				if (preg_match('/Location: ([^\r\n]+)/', $line, $location)) {
+					if (isset($location[1])) {
+						$parsedUrl = parse_url($location[1]);
+						if (!isset($parsedUrl['host'])) {
+								// the location did not contain a complete URI, build it!
+							$parsedUrl = parse_url($lastUrl);
+							$newUrl = $parsedUrl['scheme'].'://'.(isset($parsedUrl['user'])?$parsedUrl['user'].(isset($parsedUrl['pass'])?':'.$parsedUrl['pass']:''):'').$parsedUrl['host'].(isset($parsedUrl['port'])?':'.$parsedUrl['port']:'').$location[1];
+						}
+						else {
+							$newUrl = $location[1];
+						}
+
+						if ($currentUrl === $newUrl) break 2;
+						$currentUrl = $newUrl;
+						$haveNewUrl = TRUE;
+					} else break 2;
 				}
+					// find cookies
+				if (preg_match('/Set-Cookie: (.*); path=(.+)/', $line, $cookie)) {
+					$cookies .= (isset($cookie[1]) ? $cookie[1] : '') . '; ';
+				}
+			}
+
+				// add cookies if we have some
+			if (!empty($cookies)) $additionalHeaders['Cookie'] = 'Cookie: ' . $cookies;
+
+
+				// now try to fetch again
+			if ($haveNewUrl) {
+				$content = t3lib_div::getURL($currentUrl, 2, $additionalHeaders, $report);
 				$tries++;
+			} else break;
 		}
 
+
+		
 		$response = TRUE;
 
 			// analyze the response
@@ -118,15 +165,10 @@
 		if (($report['http_code'] == 301) || ($report['http_code'] == 302)
 			|| ($report['http_code'] == 303) || ($report['http_code'] == 307)) {
 				$errorParams['errorType'] = $report['http_code'];
-				$errorParams['location'] = $location[1];
+				$errorParams['location'] = $currentUrl;
 				$response = FALSE;
 		}
 
-		if ($report['http_code'] == 404 || $report['http_code'] == 403) {
-			$errorParams['errorType'] = $report['http_code'];
-			$response = FALSE;
-		}
-
 		if ($report['http_code'] >= 300 && $response) {
 			$errorParams['errorType'] = $report['http_code'];
 			$response = FALSE;
@@ -162,14 +204,14 @@
 				$response = sprintf($GLOBALS['LANG']->getLL('list.report.redirectloop'), $errorType, $errorParams['location']);
 				break;
 
+			case 403:
+				$response = $GLOBALS['LANG']->getLL('list.report.pageforbidden403');
+				break;
+
 			case 404:
 				$response = $GLOBALS['LANG']->getLL('list.report.pagenotfound404');
 				break;
 
-			case 403:
-				$response = $GLOBALS['LANG']->getLL('list.report.pageforbidden403');
-				break;
-
 			case 500:
 				$response = $GLOBALS['LANG']->getLL('list.report.internalerror500');
 				break;
