Selbsterstellte 404-Seiten bestimmen, die sich als 200 ausgeben

alphaChill

Aktives Mitglied
Hallo an alle,

habe folgendes Problem:
ich möchte einen LinkChecker schreiben, der auch selbsterstellte 404-Seiten erkennt.

Beispiel:
Ich besuche die Webseite
HTML:
https://www.bs-card-service.com/de/home/adsfasdf
die es nicht gibt. Der Server gibt mir erst eine 303 für die Weiterleitung nach "https://www.bs-card-service.com/de/error/" und dann eine 200 für eigentliche Error-Seite.

Nun ist die Error-Seite aber eine selbsterstellte 404-Seite. Gibt es eine Möglichkeit die Seite "https://www.bs-card-service.com/de/error/" als 404-Seite zu identifizieren?

Aktuell nutze ich "htmlunit" um mir die Statuscodes zu holen:
Code:
WebClient webClient = new WebClient();
// Nicht sicheren SSL-Verbindungen trauen?
webClient.setUseInsecureSSL(true);
// Seitenweiterleitung folgen?
webClient.setRedirectEnabled(true);
// Fehler werfen, wenn ein "unschöner" StatusCode zurückkommt?
webClient.setThrowExceptionOnFailingStatusCode(false);
// Webseite holen
HtmlPage page = webClient.getPage("https://www.bs-card-service.com/de/home/adsfasdf");
// StatusCode der Webseite holen:
System.out.println(page.getWebResponse().getStatusCode());

Wenn die Seitenweiterleitung aktiv (true) ist, bekomme ich, wie oben geschrieben, den Code "200" zurück und wenn diese inaktiv (false) ist, bekomme ich den Code "303" zurück 🙁
Über
Code:
System.out.println(page.getWebResponse().getStatusMessage());
kann ich mir noch die Status-Message ausgeben lassen. Bringt mir allerdings nicht viel, da diese nur "OK" oder "See other" heißt. Also eine Übersetztung der Codes 🙁

Also ich bin jetzt nich zwingend auf htmlunit angewiesen. Nutzte diese Bibliothek nur, weil sie auf anderen Gebieten (z.B. das Holen aller Links von Webseiten) gute Dienste tut.
Andere Techniken, mit denen ich allerdings nicht die besten Erfahrungen gemacht (weil ggf. nicht richtig angewandt!?) habe wäre "httpunit" und über das Java-eigene "URLConnection"-Objekt.

Ein Lösungsansatz, der mir allerdings etwas kompliziert und nicht sehr sicher erscheint wäre:
Ich hole mir die Base-URL, provoziere dann mit der Endung "0123456789.html" eine 404-Seite, speichere das Page-Objekt ab und vergleiche das dann mit der eigentlich zuprüfenden Seite.
Problem: Bei Seiten mit Länderumschalter z.b. "http://www.xyz.com/de" bzw "http://www.xyz.com/en" habe ich die 404-Seite in einer eigenen Sprache, da würde das provozieren eine 404-Seite und dem anschließenden Abgleich schon nicht mehr funktionieren 🙁

Ich hoffe, dass mir jemand helfen kann.

Beste Grüße
Thomas
 
Ich bin mir nicht sicher, hab' solche Fehlercodes auf der Clientseite noch nie ausgelesen geschweige denn nachvollzogen.
Aber von der Logik her, leitet man doch serverseitig auf eine vorhandene Seite um, welche dann an den Client geschickt wird. Wenn der Client stattdessen den Fehlercode bekommen würde, wäre er ja gezwungen, die entsprechende Standardseite des Browsers anzuzeigen. Von der Funktion her also in etwa mit Exceptions (catch or throw Regel) vergleichbar.
 
Kaum hat man einen Standard, schon macht ihn einer kaputt - die genannte Fehlerseite auszuliefern und einen 404 zu setzen wäre einfacher gewesen als der Krampf über einen Redirect.

Wenn Du sowas erkennen möchtest, bleibt nicht mehr als der Vergleich mit einer willkürlich erzeugten 404 Seite - wenn da aber selbst bei der Fehlermeldung serverseitig wechselnder Content (zb. Werbung) direkt in den Quelltext eingefummelt wird hast Du ganz schlechte Chancen.

Bernd
 
Mist, das habe ich fast beführchtet.

Wenn's so ist, dann ist es wohl so 🙁

Sonst nehem ich aber kreative Ideen (und auch alle anderen ;-) ) gerne entgegen 🙂
 
jeden server-admin der so was macht sollte man eigentlich schlagen ...
es wurden extra status-codes für http definiert ... und wenn man mit 302 und dann 200 seine eigene fehlerseite ausliefert muss man sich nicht wundern wenn einem angemängelt wird das man gegen den standard arbeitet ...

btw : nur weil der server 404 schickt heißt das nicht das der browser zu seiner standard-error-site gezwungen wird ...
wenn man content mitschickt wird diser auch normalerweise angezeigt ...
 
Heisst das etwa, ich liege mit meiner Logik daneben? Wenn das so ist...
Setverseitig wechselnder Content lässt sich clientseitig per Ajax in statischen Content nachladen. Das bedeutet, die eigentlich statische Seite beinhaltet ein Script, welches den dynamischen Content per erneutem (gezielten und vorhandenen, sonst Endlos-Rekursion!) Ajax-HTTPRequest in z.B. ein leeres DIV lädt. Denke mal, das sollte auch bei Fehlerseiten funktionieren.

Das man 1995 auf so etwas nicht kam, ist klar, aber in heutigen Zeiten... Hmmm. Evtl. verstehe ich ja auch das Problem, für welches ich so händeringend eine Lösung sucht nicht.
 
Irgendwie kann ich deinen Gedanken, Spacerat, nicht ganz nach vollziehen. Oder wolltest du mir jetzt mit deinem Post mitteilen, dass ich das Ajax-Objekt abfangen und auslesens soll?

Habe nun folgende Lösung zusammengebastelt:
Diese Funktion prüft selbsterstelle 404-Seiten, in dem einen 404-Seite provoziert wird und gespeichert wird. Ich gehe davon aus, dass die Länderunterscheidung immer nach dem ersten Slash in der URL kommt also z.B.:
Kostenlose E-Mail Adresse mit Gratis-SMS bei freenet Mail
Zudem prüfe ich, ob bei Fehlerhaften URLs nicht einfach auf die Startseite geleitet wird (dann bekommt man den Code -2).

Java:
public int getStatus(String internetURL)
	{
		int statusCode = -1;
		
		try
		{
			WebClient webClient = new WebClient();
			 
		// Wenn Cookies verfügbar sind, sollen diese auch gesetzt / genutzt werden
			if(CookieModel.createModel().getCookieMan() != null)
			{
				webClient.setCookieManager(CookieModel.createModel().getCookieMan());
			}
		// JavaScript abschalten, SSL-Verbindungen immer vertrauen, Weiterleitung akzeptieren, bei "unschönen" StatusCodes nicht stoppen.
			webClient.setJavaScriptEnabled(false);
			webClient.setUseInsecureSSL(true);
			webClient.setRedirectEnabled(true);
			webClient.setThrowExceptionOnFailingStatusCode(false);
		// Evtl. weitergeleitete Webseite aufrufen.
			HtmlPage rePage = webClient.getPage(internetURL);
		// StatusCode dieser Seite abfangen
			statusCode = rePage.getWebResponse().getStatusCode();
		//404-Seite generieren, damit diese mit der eigentlichen zu prüfenden Seite abgeglichen werden kann.
			String baseURL = rePage.getUrl().getProtocol()+"://"+rePage.getUrl().getHost();
			String[] splittedURL = internetURL.split("/");
			String url404;
			if(splittedURL.length >= 4)
			{
				url404 = baseURL+"/"+splittedURL[3]+"/123456789.html";
			}
			else
			{
				url404 = baseURL+"/123456789.html";
			}
			HtmlPage page404 = webClient.getPage(url404);
			
			if(page404.getUrl().toString().equals(rePage.getUrl().toString()))
			{
				statusCode = 404;
			}
		// Homepage zum Abgleich abfangen
			HtmlPage homePage = webClient.getPage(baseURL);
			webClient = new WebClient();
			webClient.setJavaScriptEnabled(false);
			webClient.setUseInsecureSSL(true);
			webClient.setRedirectEnabled(false);
			webClient.setThrowExceptionOnFailingStatusCode(false);
			
			HtmlPage internetPage = webClient.getPage(internetURL);
			
			if(!internetPage.getUrl().toString().equals(homePage.getUrl().toString()) && rePage.getUrl().toString().equals(homePage.getUrl().toString()))
			{
				// Weiterleitung von Ursprünglicher-Adresse auf Homepage
				statusCode = -2;
			}
		}
		catch(Exception ex)
		{
			ex.printStackTrace();
		}
		
		return statusCode;
	}
 
Ich gehe davon aus, dass die Länderunterscheidung immer nach dem ersten Slash in der URL kommt...
Davon sollte man aber nicht ausehen. Es mag vllt. sein, dass die meisten Webinhalte multilingualen Content in verschiedenen Verzeichnissen verwalten, wenn sie jedoch anschliessend mit URL-Rewriting diesen Umstand verschleiern, passt die URL evtl. nicht mehr zur Verzeichnisstruktur.
Eine 404-Seite kann man in der Regel direkt aus einer vorhandenen funktionierenden URL erstellen ([c]URL url404 = new URL(realPage.getURL(), "failingContent.xyz");[/c]).
Java:
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLConnection;


public class URLChecker {
	private static final URL functional;

	static {
		URL f = null;
		try {
//			f = new URL("http://www.java-forum.org/netzwerkprogrammierung/");
			f = new URL("http://www.google.de/");
		} catch(MalformedURLException e) {
			e.printStackTrace();
		}
		functional = f;
	}

	public static void main(String[] args) {
		try {
			URLConnection uc = functional.openConnection();
			System.out.println(functional);
			if(uc instanceof HttpURLConnection) {
				System.out.println("Status: " + ((HttpURLConnection) uc).getResponseCode());
			}
			URL disfunctional = new URL(functional, "noContent.xyz");
			uc = disfunctional.openConnection();
			System.out.println(disfunctional);
			if(uc instanceof HttpURLConnection) {
				int status = ((HttpURLConnection) uc).getResponseCode();
				System.out.println("Status: " + status);
				if(status != 404) {
					System.out.println("Redirected to: " + uc.getURL());
				}
			}
		} catch(IOException e) {
			e.printStackTrace();
		}
	}
}
Eine serverinterne Weiterleitung, auf welche Seite auch immer (Wie man z.B. durch "www.xyz.de/LAND" auf Freenet kommt...) und welchen Status er dabei sendet, ist halt Syche des Servers.
Meinen Beitrag über Ajax kannst du dann getrost vergessen, ich wusste ja nicht genau, was du vorhast, ob du 'nen eigenen Server testen willst oder einen fremden zu fehlerhaften Verhalten zwingen willst, wobei letzteres recht suspekt wäre.
 

Neue Themen


Zurück
Oben