# HttpRequest + HttpResponse



## D.v (10. Mai 2012)

Hallo zusammen,

ich muss für die Hochschule was in Java programmieren und weiss nicht weiter.
Wäre echt nett wenn mir jemand helfen könnte. Ich denke nicht dass dies allzu große Probleme sind, nur komm ich echt nicht weiter. Das was ich nicht weiss is so gekennzeichnet: /* Fill in */


```
public class HttpRequest {
    /** Help variables */
    final static String CRLF = "\r\n";
    final static int HTTP_PORT = 80;
    /** Store the request parameters */
    String method;
    String URI;
    String version;
    String headers = "";
    /** Server and port */
    private String host;
    private int port;

    /** Create HttpRequest by reading it from the client socket */
    public HttpRequest(BufferedReader from) {
	String firstLine = "";
	try {
	    firstLine = from.readLine();
	} catch (IOException e) {
	    System.out.println("Error reading request line: " + e);
	}

	String[] tmp = firstLine.split(" ");
	method = /* Fill in */;
	URI = /* Fill in */;
	version = /* Fill in */;

	System.out.println("URI is: " + URI);

	if (!method.equals("GET")) {
	    System.out.println("Error: Method not GET");
	}
	try {
	    String line = from.readLine();
	    while (line.length() != 0) {
		headers += line + CRLF;
		/* We need to find host header to know which server to
		 * contact in case the request URI is not complete. */
		if (line.startsWith("Host:")) {
		    tmp = line.split(" ");
		    if (tmp[1].indexOf(':') > 0) {
			String[] tmp2 = tmp[1].split(":");
			host = tmp2[0];
			port = Integer.parseInt(tmp2[1]);
		    } else {
			host = tmp[1];
			port = HTTP_PORT;
		    }
		}
		line = from.readLine();
	    }
	} catch (IOException e) {
	    System.out.println("Error reading from socket: " + e);
	    return;
	}
	System.out.println("Host to contact is: " + host + " at port " + port);
    }

    /** Return host for which this request is intended */
    public String getHost() {
	return host;
    }

    /** Return port for server */
    public int getPort() {
	return port;
    }

    /**
     * Convert request into a string for easy re-sending.
     */
    public String toString() {
	String req = "";

	req = method + " " + URI + " " + version + CRLF;
	req += headers;
	/* This proxy does not support persistent connections */
	req += "Connection: close" + CRLF;
	req += CRLF;
	
	return req;
    }
}
```


und der Response noch

```
public class HttpResponse {
    final static String CRLF = "\r\n";
    /** How big is the buffer used for reading the object */
    final static int BUF_SIZE = 8192;
    /** Maximum size of objects that this proxy can handle. For the
     * moment set to 100 KB. You can adjust this as needed. */
    final static int MAX_OBJECT_SIZE = 100000;
    /** Reply status and headers */
    String version;
    int status;
    String statusLine = "";
    String headers = "";
    /* Body of reply */
    byte[] body = new byte[MAX_OBJECT_SIZE];

    /** Read response from server. */
    public HttpResponse(DataInputStream fromServer) {
	/* Length of the object */
	int length = -1;
	boolean gotStatusLine = false;

	/* First read status line and response headers */
	try {
	    String line = /* Fill in */;
	    while (line.length() != 0) {
		if (!gotStatusLine) {
		    statusLine = line;
		    gotStatusLine = true;
		} else {
		    headers += line + CRLF;
		}

		/* Get length of content as indicated by
		 * Content-Length header. Unfortunately this is not
		 * present in every response. Some servers return the
		 * header "Content-Length", others return
		 * "Content-length". You need to check for both
		 * here. */
		if (line.startsWith(/* Fill in */) ||
		    line.startsWith(/* Fill in */)) {
		    String[] tmp = line.split(" ");
		    length = Integer.parseInt(tmp[1]);
		}
		line = fromServer.readLine();
	    }
	} catch (IOException e) {
	    System.out.println("Error reading headers from server: " + e);
	    return;
	}

	try {
	    int bytesRead = 0;
	    byte buf[] = new byte[BUF_SIZE];
	    boolean loop = false;

	    /* If we didn't get Content-Length header, just loop until
	     * the connection is closed. */
	    if (length == -1) {
		loop = true;
	    }
	    
	    /* Read the body in chunks of BUF_SIZE and copy the chunk
	     * into body. Usually replies come back in smaller chunks
	     * than BUF_SIZE. The while-loop ends when either we have
	     * read Content-Length bytes or when the connection is
	     * closed (when there is no Connection-Length in the
	     * response. */
	    while (bytesRead < length || loop) {
		/* Read it in as binary data */
		int res = /* Fill in */;
		if (res == -1) {
		    break;
		}
		/* Copy the bytes into body. Make sure we don't exceed
		 * the maximum object size. */
		for (int i = 0; 
		     i < res && (i + bytesRead) < MAX_OBJECT_SIZE; 
		     i++) {
		    /* Fill in */
		}
		bytesRead += res;
	    }
 	} catch (IOException e) {
 	    System.out.println("Error reading response body: " + e);
 	    return;
 	}


    }

    /**
     * Convert response into a string for easy re-sending. Only
     * converts the response headers, body is not converted to a
     * string.
     */
    public String toString() {
	String res = "";

	res = statusLine + CRLF;
	res += headers;
	res += CRLF;
	
	return res;
    }
}
```

Vielen Dank für Eure Hilfe


----------



## HimBromBeere (11. Mai 2012)

Ich kann mit deiner Frage zwar absolut überhaupt nichts anfangen, aber ich hole mal meine Kristallkugel raus, um damit ein wenig Bowling zu spielen.

Du versuchst, eine eigene Serverbehandlung zu schreiben (obwohl es die beiden von dir beschriebenen Klassen bereits auf jedem handelsüblichen Tomcat gibt). Dabei werden Antwort und Anfrage über einen BufferedReader erstellt. So weit so gut. Aber wo das Problem ist, will mir nicht einleuchten. Du musst doch nur den übergeben Reader zeile für Zeile auslesen. Wenn du da irgendsowas findest, was wie eine URL aussieht, speicherst du die in der Variable URL, wenn du ´nen Host findest, dann da rein.
Sollen wir dir helfen beim Finden der jeweiligen Zeilen mit einem Suchmuster (Regex) oder woran hängt´s?


----------



## D.v (11. Mai 2012)

Hallo, erstmal vielen Dank für deine Antwort.

Das Problem ist halt echt icht muss die Codezeilen vervollständigen und hab echt kein Plan wie, oder was da rein muss.

Wie finde ich denn die Klassen im Tomcat?


----------



## Marcinek (11. Mai 2012)

Beispiel:


```
/* Get length of content as indicated by
         * Content-Length header. Unfortunately this is not
         * present in every response. Some servers return the
         * header "Content-Length", others return
         * "Content-length". You need to check for both
         * here. */
         if (line.startsWith(/* Fill in */) ||
            line.startsWith(/* Fill in */)) {
            String[] tmp = line.split(" ");
            length = Integer.parseInt(tmp[1]);
        }
```

Wo ist hier das Problem?

Die Lösung steht im Kommentar dadrüber.


----------



## D.v (11. Mai 2012)

Naja ich wüsste jetzt nicht was ich da reinschreiben soll.

Wie gesagt ich bin totaler Anfänger


----------



## Marcinek (11. Mai 2012)

```
if (line.startsWith("Content-Length") ||
            line.startsWith(/* Fill in */)) {
            String[] tmp = line.split(" ");
            length = Integer.parseInt(tmp[1]);
        }
```

Jetzt du.

Wenn du aber ein Anfänger bist, dann wirst du das kaum schaffen =(


----------



## HimBromBeere (11. Mai 2012)

> Wie finde ich denn die Klassen im Tomcat?


Guckste hier
Das Kapitel Servlet dürfte das interessante hier für dich sein. Du musst deine Klasse nur von 
	
	
	
	





```
HttpServlet
```
 ableiten und dann für jede Methode (get, Post) eine eigene Funktion mit Namen do[Get/Post/...] schreiben. Da drin schreibst du dann alles, was der Server auf deine Anfrage hin machen soll.

Aber wie bereits von meinem Vorrdener angedeutet: Als Anfänger eher ungeeignet. Entweder du hast die ganzen letzten Vorlesungen durch die Bank weg geschlafen (im wahrsten Sinne des Wortes), oder dein Lehrer ist ein wenig anspruchsvoll...


----------



## D.v (13. Mai 2012)

Ok hey Danke,
leider darf ich die Klasse nicht von der Servlet ableiten. Ich muss "einfach" nur diese Fill in ausfüllen.
Wäre nett wenn mir jemand helfen könnte.


----------



## Marcinek (13. Mai 2012)

D.v hat gesagt.:


> Wäre nett wenn mir jemand helfen könnte.



Wie sollen wir helfen? 

Hilft dir ein Link um HTTP Protokoll?


----------



## HimBromBeere (14. Mai 2012)

Lass dir mal die ganze Antwort vom Server irgendwo (z.B. sysout) ausgeben, dann weist du erstmal, wie die aussieht und nach welchen Zeilen du tatsächlich suchen musst.

EDIT: Den Ansatz von Marczinek (
	
	
	
	





```
11.05.2012, 08:36
```
) haste geflissentlich ignoriert, oder wie sieht´s damit aus?


----------

