Andreas Korthaus: HTTP-Proxyserver programmieren

Beitrag lesen

Hi!

Ähm:
Bei PHP _weiß_ der Server von der Langsamkeit. Der Server liefert erst das durch PHP gelaufene HTML via HTTP aus. Der Client merkt von _dieser_ Langsamkeit nichts. Er sieht einen langsamen Server.

Bei einem Proxy denkt der Server, er liefere an einen User-Agent. Der Client meint, er erhielte von einem Server. Keiner der beiden nimmt Rücksicht auf Verzögerungen im Proxy.

Das ist schon klar, ich meinte aber wenn ich mit PHP auf HTTP direkt zugreife, als Client. Nur versteeh ich nicht warum Verzögerungen ein problem sein sollen. Ich habe z.B. folgende Seite geladen: http://www.couponmountain.de/Computer_%26_Software_alles.html, da wurden fast. 200(!) Requests erzeugt, und Java hat so einige Sekunden mit 100% Prozessorauslastung gewerkelt. Das warem aber vor allem Bilder, und die übertrage ich ja eigentlich recht flott. Vielleicht sollte ich dann doch irgendwann über keep-Alive nachdenken, aber das wird dann schon schieriger, mal sehen.

Ich habe es jetzt in Gang bekommen, das ersetzen und umwandeln mit den Strings braucht sehr viele Resourcen. Das würde ich jetzt noch gerne optimieren ;-)

Das Problem lag meiner Meinung nach irgendwo bei den Längenangaben der Bytes, ich verstehe das Problem allerdings noch nicht.

Ich versuche jetzt aber nochmal "methode 2." ;-)
Probiers aus.

Gemacht:

Wenn ich jetzt bei altavista nach "Computer" suche bekomme ich als Ergebnis:

Kaltschrank - PCs und mehr zu Spitzenpreisen von DELL
CCC | Chaos Kaltschrank Club e.V.
[Home] Kaltschrank Zeitung Online
...
 ;-)

Hierzu war auf alle Fälle die Anpassung des Content-Length Headers notwendig, was ich "mal eben" in Quick-and-Dirty Manier gemacht habe :)

Naja, jetzt muss es nur noch schneller gehen. Und das POST-Problem, beheben.

ZUm POST Problem:

char post_data[] = new char[13000];

while ((line = in.readLine()) != null) {

// the header ends at the first blank line
    if (line.length() == 0) {
        if (methode.toLowerCase().equals("post")) {

in.read(post_data, 0, contentLength);
        }
     break;
    }

[...]
}

if (methode.toLowerCase().equals("post")) {
                post_str += new String(post_data);
                client_request += post_str.substring(0, contentLength).trim();
            }

Das Problem, ich habe jetzt einen 13000 Zeiche langen Char-Array, weil ich vorher nicht weiß wie lang die POST Daten sind, ich aber Vorher "post_data" initiieren muss. Ich dachte wenn ich das dann in einen Array übertage und mit trim() bearbeite dann wären die Leerzeichen weg, bei PHP ist das so, bei Java anscheinend nicht.

Wie kann ich das sonst machen?

und das andere Problem:

if (contentType.equals("text/html")) {

while ((data = readLine(from_serv)) != null) {
                            html_data += data.replaceAll("Computer", "Kaltschrank") + "\r\n";
                        }

// add a blank line to terminate the header info
               header.append("Content-Length: " + html_data.length() + "\r\n");
               header.append("Connection: close\r\n");
               header.append("\r\n");

// convert the header to a byte array, and write it to our stream
               out.write(header.toString().getBytes(), 0, header.length());

out.write(html_data.getBytes(), 0, html_data.length());
}

Ich meine, im Prinzip funktioniert das, nur eben nicht so besonders flott. Aber ich denke so viel schneller geht das einfach  nicht, da ich ja nunmal die Daten in den String konvertieren muss, darauf replaceAll() anwenden muss, dann wieder zurück konvertieren, und schreiben. Ich kann mir nur vorstellen das ich noch ein wenig effektiver einlesen kann.

Aber irgend2wei ist da noch der Wurm drin, manche Seite funktionieren, macnhe nicht, und wonach sich das richtet habe ich bisher  noch nicht herausbekommen können. Aber ich glaube es liegt schon vorher das Problem, da der Request manchmal nichtmal den Proxy verlässt. Leider kann ich mit Ethereal nicht localhost belauschen, dann würde ich wissen was da so lokal genau abläuft.

Irgebdwie ist da noch ein dicker Fehler drin. Das was mich nur wundert, alle Seiten die im Mozilla nicht funkitonieren, funktionieren dafür mit Telnet,  das heißt wenn ich da manuelel Requests an den proxy schicke funktiniert das immer wunderbar. Und mit Telnet kann ich wenigstens sehen was Mozilla empfängt, aber da kann ich keine Fehler entdecken. Ich tippe trotzdem auf ein Problem mit Content-Length, da wenn das nicht stimmt Mozilla gart nichst anzeigt. Kann sein das es sich auch um Caching-Probleme handelt, das vermute ich fast.

Naja, wenn das denn endlich komplett läuft, werde ich den Code verschönern ;-) Und dann werde ich eine Liste mit zu ersetzenden Wörtern aus einer Datei einlesen, wobei das ganze dann natürlich  noch langsamer wird, wenn ich z.B. 10 mal replaceAll drüberlaufen lasse, daher will ich das irgendwie schneller bekommen. Weißt Du vielleicht einen Ansatz wie ich das machen könnte?

Auf jeden Fall vielen Dank Euch beiden! Schön dass man hier auch zu Java gute Hilfe bekommt ;-)

Grüße
Andreas