Andreas Korthaus: HTTP-Proxyserver programmieren

Beitrag lesen

Hallo!

du solltest wohl nur die Header einschließlich Content-Type mit readline einlesen (am Ende des Headers sind wohl zwei Newline Zeichen statt eins, daran sollte man das erkennen. Bei meinen Versuchen war Content Type immer der letzte Header Eintrag, keine Ahnung ob das immer so sein muss).
den Rest kannst du z.B. mit int read(byte[] b), also NICHT als Text, lesen - und mit write beim OutputStream wieder schreiben.
Die Einzelheiten wie immer im Sun JavaDoc.

Ja, so mache ich das inzwischen auch, und es funktioniert im Prinzip super. Ich kann den Proxy schon fürs alltägliche Surfen nehmen nur kann ich noch keine Daten per POST verschicken, aber das werde ich auch noch einbauen ;-)
Aber jetzt habe ich ein anderes Problem, und zwar würde ich gerne den HTML-Quelltext verändern können. Das heißt ich will z.B. jeden enthaltenen String "Computer" gegen "Kaltschrank" ersetzen. Nur ist das dann wieder komplizierter als ich vermutet hätte.

So funktioniert es wunderbar, indem ich die Bytes direkt vom Server an den Client weiterreiche:

byte[] buf = new byte[4096];
int bytesIn = 0;
while ( ((byteCount < contentLength) || (waitForDisconnect))
                         && ((bytesIn = from_serv.read(buf)) >= 0) )
{
    out.write(buf, 0, bytesIn);
    byteCount += bytesIn;
}

Nur so funktioniert es nicht mehr richtig:

byte[] buf = new byte[4096];
int bytesIn = 0;
String str_buf = "";
if (contentType.equals("text/html")) {
    while ( ((byteCount < contentLength) || (waitForDisconnect))
                         && ((bytesIn = from_serv.read(buf)) >= 0) )
    {
        String str = new String(buf);
        str = str.replaceAll("Computer", "Kaltschrank");
        out.write(str.getBytes(), 0, str.length());
        byteCount += bytesIn;
    }
}

Hierbei wandele ich in jedem Durchlauf den Puffer-Array(Bytes) in einen String um, wende die Methode replaceAll() drauf an, ermottel dei Stringlenge, wandle es wieder in einen Byte-Array um und schreibe diesen mit der Länge des Strings in den Stream zum Client.

Es wird auch ersetzt, aber leider hat die Seite dann viele Fehler und wird meist nicht zu Ende übertragen. Ich stelle auch sicher dass es sich bei dem hereinkommenden Stream um unkomprimierten HTML-Quellcode handelt, nur muss ich den ja dann in Strings umwandeln um replaceAll verwenden zu können, und vermutlich stimmt dann irgendwas mit der Länge der Bytes nicht mehr. Ist nicht jedes Zeichen im String ein Byte? Oder wie ermittele ich die Länge des Byte-Array?

Ein Problem ist auch, dass ich ja willkürlich den Code zerteile. Daher sollte ich wohl lieber alle bytes in einen Puffer schreiben, nur ist das so besonders effektiv? Das können nämlich schonmal ein paar Bytes mehr werden. Naja, dann könnte ich im Sonderfall von HTML-Daten ja doch per readline einlesen und schreiben, dann könnte ich wenigstens direkt auf String-Ebene arbeiten, ohne die Konvertierungen. Nur war das mit den Strings _sehr_ viel langsamer als jetzt mit den bytes.

Wie würdest Du das machen?

Viele Grüße
Andreas