Andreas Korthaus: HTTP-Proxyserver programmieren

Beitrag lesen

Hi!

hmm, die einfachen Probleme hast du ja schon gelöst...

;-)

Wenn du es schaffst HTTP POST zu implementieren wäre der Proxy wohl ganz brauchbar; ich hätte auch interesse daran :-)

Naja, aber vertrauen würde ich dem nicht, aber da ist ja gerade das lustige dran, ich parse alle Request Header einzelnd und kann dann entscheiden ob ich die weiterleite, verwerfe oder verändere.

Post klappt inzwischen auch, aber leider kann ich da snur mit einem char Array mit fester Länge machen udn ich bekomme den String nicht auf die richtige Länge gekürzt, also schicke ich andauernd 13 KB durchs netz mit fast nur Leerzeichen. Naja.

String Funktionen sind relativ langsam, am besten du nimmst immer wenn du viele (spätestens ab einigen 100) Stringoperationen durchführst StringBuffer. In deinem Fall würde es die Sache wohl aber nicht beschleunigen, weil du immer neue String Objekte erzeugst und nicht viele Operationen auf einem Objekt ausführst.

Werde ich Berücksichtigen.

Ich bin mir nicht ganz sicher warum es nicht klappt. Ich vermute es liegt daran, dass Java Unicode benutzt und ein Zeichen immer zwei Byte belegt. Ich denke der write Befehl schreibt dann nur die erste Hälfte des Strings raus... Lag ich richtig?

ich glaube nicht. Byte ist ein Byte, Char sind 2 Byte. Das ist irgendwie sehr diffus, ich habe es jetzt anders probiert indem ich eien 2. byte-Buffer für den veränderten String verwende, aber das geht genauso schlecht.

Naja, ich habe das komplette Programm mal angehängt, vielleicht verstehst Du ja warum das so nicht geht, so wie es ist funktioniert das ganze bis auf das kleien POST-Problem und das Austauschen der Wörter wunderbar, letzteres habe ich unten auskommentiert, das müsste dann so lauten(nur erzeugt diese Variante nur noch Kauderwelsch, liegt vermutlich an der Konvertierung in Bytes?!):

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");                           buf2 = str.getBytes();

out.write(buf2, 0, buf2.length);           byteCount += bytesIn;

}      }

So, hier das Programm, ist noch sehr durcheinander, liegt vor allem daran dass ich wild rumprobiert habe das Problem auf verschiedenen Wegen zu lösen ;-)

Grüße Andreas

import java.io.; import java.net.; import java.util.*;

public class proxy2 {

public static void main(String args[]) {

int anz = 1;         try {             ServerSocket ss = new ServerSocket(7788);             while(true) {                 Socket sverb = ss.accept();                 System.out.println(" Verbindung " + anz);                 new ServerThread(sverb,anz).start();                 anz++;             }         }         catch (Exception e) {             System.out.println(e);         }     } }

class ServerThread extends Thread {     Socket sverb;     int    nverb;

ServerThread(Socket s , int n) {         this.sverb = s;         this.nverb = n;     }

public void run () {

try {

BufferedReader in =        new BufferedReader(new InputStreamReader(sverb.getInputStream()));

//PrintStream out =             //    new PrintStream(sverb.getOutputStream());

//BufferedInputStream clientIn = new BufferedInputStream(sverb.getInputStream());             BufferedOutputStream out = new BufferedOutputStream(sverb.getOutputStream());

boolean weiter = true;             String retline = "";             String line = "";             String methode = "";             String url = "";             String host = "";             String path = "";             String query = "";             String proto = "";             String client_request = "";             String post_str = "";             char post_data[] = new char[13000];             int pos = -1;             int contentLength = 0;

StringTokenizer tokenizer = new StringTokenizer( in.readLine() );             methode = tokenizer.nextToken();             url = tokenizer.nextToken();             proto = tokenizer.nextToken();

URL u = new URL( url );             host = u.getHost();             path = u.getPath();             query = u.getQuery();

client_request = methode + " " + path ;             if (query != null) {                 client_request += "?" + query ;             }             // client_request += " " + proto + "\r\n";             client_request += " HTTP/1.0\r\n";

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

// the header ends at the first blank line     if (line.length() == 0) {         if (methode.toLowerCase().equals("post")) {             //post_data = in.read ()             //System.out.println("POST");             //post_data.length = contentLength;             //char post_data[] = new char[contentLength];             in.read(post_data, 0, contentLength);             //System.out.println(post_data);         }      break;                 }

pos = line.toLowerCase().indexOf("host:");     if (pos >= 0) {      //host = line.substring(pos + 5).trim());      //request += "host: " + host + "\r\n";      client_request += line + "\r\n";     }

pos = line.toLowerCase().indexOf("content-length:");     if (pos >= 0) {         contentLength = Integer.parseInt(line.substring(pos + 15).trim());      client_request += line + "\r\n";     }

pos = line.toLowerCase().indexOf("user-agent:");     if (pos >= 0) {      client_request += line + "\r\n";     }

pos = line.toLowerCase().indexOf("authorization:");     if (pos >= 0) {      client_request += line + "\r\n";     }

pos = line.toLowerCase().indexOf("accept-encoding:");     if (pos >= 0) {      client_request += line + "\r\n";     } /*     pos = line.toLowerCase().indexOf("accept-language:");     if (pos >= 0) {      client_request += line + "\r\n";     }

pos = line.toLowerCase().indexOf("accept-charset:");     if (pos >= 0) {      client_request += line + "\r\n";     }

pos = line.toLowerCase().indexOf("cookie:");     if (pos >= 0) {      client_request += line + "\r\n";     }

pos = line.toLowerCase().indexOf("referer:");     if (pos >= 0) {      client_request += line + "\r\n";     } */             }             client_request += "Connection: close\r\n";             client_request += "\r\n";             if (methode.toLowerCase().equals("post")) {                 post_str += new String(post_data);                 client_request += post_str.substring(0, contentLength).trim();             }

try {              // Öffne Socket-Verbindung zum Webserver                 Socket t = new Socket( host, 80 );

//BufferedReader from_serv = new BufferedReader(                 //    new InputStreamReader( t.getInputStream()));                 BufferedInputStream from_serv = new BufferedInputStream(t.getInputStream());

PrintStream to_serv = new PrintStream( t.getOutputStream() );

// Sende Request weiter an Webserver                 to_serv.print( client_request );                 System.out.print( post_str );                 /*                 String client_response = "";

while (( retline = from_serv.readLine()) != null) {                     client_response += retline + "\r\n";                 }                 out.print( client_response );                 //System.out.print( client_response );                 */           StringBuffer header = new StringBuffer("");           String data = "";           String firstline = "";           String contentType = "";           int responseCode = -1;           contentLength = 0;           int byteCount = 0;

firstline = readLine(from_serv);           System.out.print( firstline );           pos = firstline.toLowerCase().indexOf(" ");     if (pos >= 0) {      responseCode = Integer.parseInt(firstline.substring(pos, pos + 4).trim());     }     header.append(firstline + "\r\n");        while ((data = readLine(from_serv)) != null) {         // the header ends at the first blank line         if (data.length() == 0)          break;         header.append(data + "\r\n");

// check for the Content-Length header         pos = data.toLowerCase().indexOf("content-length:");         if (pos >= 0)          contentLength = Integer.parseInt(data.substring(pos + 15).trim());         pos = data.toLowerCase().indexOf("content-type:");         if (pos >= 0) {             if(data.length() <= 24) {                 contentType = data.substring(pos + 14).trim();             }             else {              contentType = data.substring(pos + 14, pos + 23).trim();          }          System.out.println( "contentType:" + contentType );}        }

// add a blank line to terminate the header info        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());

if ((responseCode != 200) && (contentLength == 0)) {      out.flush();      sverb.close();      t.close();      System.out.println ("  Status: " + responseCode );      //System.out.println (header );      return;     }                 boolean waitForDisconnect = true;                 if (contentLength > 0)      waitForDisconnect = false;                 try {      byte[] buf = new byte[4096];      byte[] buf2 = new byte[5000];      int bytesIn = 0;      //String str_buf = "";      if (contentType.equals("text/html")) {          while ( ((byteCount < contentLength) || (waitForDisconnect))            && ((bytesIn = from_serv.read(buf)) >= 0) )          {              /out.write(buf, 0, bytesIn);              String str = new String(buf);              str = str.replaceAll("Computer", "Kaltschrank");              //System.out.println(str.length());              buf2 = str.getBytes();              System.out.println(buf2.length);           out.write(buf2, 0, buf2.length);           byteCount += bytesIn;/           out.write(buf, 0, bytesIn);           byteCount += bytesIn;          }      }      else {          while ( ((byteCount < contentLength) || (waitForDisconnect))            && ((bytesIn = from_serv.read(buf)) >= 0) )          {           out.write(buf, 0, bytesIn);           byteCount += bytesIn;          }      }     }     catch (Exception e)  {      String errMsg = "Error getting HTTP body: " + e;       System.out.println(errMsg);       System.out.println(host + path);     }

t.close();                 //flush the OutputStream and return     try  {  out.flush();  }  catch (Exception e)  {}             }             catch (IOException e) {                 System.out.println("1" + e);             }             sverb.close();         }         catch (IOException e) {             System.out.println("2" + e);         }     }

private String readLine (InputStream in)  {   // reads a line of text from an InputStream   StringBuffer data = new StringBuffer("");   int c;

try   {    // if we have nothing to read, just return null    in.mark(1);    if (in.read() == -1)     return null;    else     in.reset();

while ((c = in.read()) >= 0)    {     // check for an end-of-line character     if ((c == 0) || (c == 10) || (c == 13))      break;     else      data.append((char)c);    }

// deal with the case where the end-of-line terminator is \r\n    if (c == 13)    {     in.mark(1);     if (in.read() != 10)      in.reset();    }   }   catch (Exception e)  {     System.out.println("Error getting header: " + e);   }

// and return what we have   return data.toString();  } }