# Connection Reset bei Webserver, Java WebStart als Client



## sparrow (1. Mrz 2008)

Hallo Forum,

ich möchte ein Programm mit einem kleinen Webserver ausstatten um es mit WebStart verteilen zu können.

Der Server lauscht also auf einen Port wie ein Webserver und übermittelt bei Anfrage nach der entsprechenden URL die .jnlp-Datei zum Client die dann dort von WebStart geöffnet wird.
Soweit kein Problem, wenn ich die entsprechenden Resourcen des Programms aus Firefox heraus aufrufe kann ich diese "downloaden", und die übertragenen Daten sind vollständig und korrekt. Der Webserver scheint also zu funktionieren.
Wenn nun aber WebStart die entsprechenden Anfragen stellt kommt es während der Übertragung zu einem Connection Reset. Der kann aber nicht vom Server ausgelöst werden, wie gesagt: mit Firefox funktioniert es problemlos und der Socket wird auch nicht versehentlich geschlossen.


Die Anfrage von Firefox für die Datei sieht wie folgt aus:
	
	
	
	





```
GET /client/lib/hibernate3.jar HTTP/1.1
Host: 127.0.0.1:14000
User-Agent: Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.8.1.12) Gecko/20080207 Ubuntu/7.10 (gutsy) Firefox/2.0.0.12
Accept: text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
Accept-Language: de-de,de;q=0.8,en-us;q=0.5,en;q=0.3
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
```

Die Anfrage von WebStart:
	
	
	
	





```
GET /client/lib/hibernate3.jar HTTP/1.1
content-type: application/x-java-archive
accept-encoding: pack200-gzip,gzip
User-Agent: JNLP/6.0 javaws/1.6.0_03 (b05) Java/1.6.0_03
UA-Java-Version: 1.6.0_03
Host: 127.0.0.1:14000
Cache-Control: no-cache
Pragma: no-cache
Accept: text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2
Connection: keep-alive
If-Modified-Since: Wed, 31 Dec 1969 23:59:59 GMT
```

Das meiste davon ignoriere ich im Augenblick noch.
Auswerten tu ich die _Get_- und die _Host_-Zeile.
Darauf antworte ich wie folgt:

```
HTTP/1.0 200 OK
Server: TestServer
Content-type: application/x-java-archive

+daten
```


Mache ich hier einen Fehler im Protokoll?


Ich danke euch schonmal.


Gruß
Sparrow


----------



## maki (2. Mrz 2008)

> Mache ich hier einen Fehler im Protokoll?


Kann sein das ich mich irre, aber hat der IE nicht die eine oder andere "unschärfe" wenn es um gezippte Datenströme geht?


----------



## Murray (2. Mrz 2008)

Welche HTTP-Header setzt Du im Response? Auch Content-Encoding?


----------



## sparrow (2. Mrz 2008)

Bisher schicke ich nur:
	
	
	
	





```
HTTP/1.0 200 OK
Server: TestServer
Content-type: application/x-java-archive

+daten
```


----------



## Murray (2. Mrz 2008)

Du solltest auf jeden Fall noch den Last-Modified-Header setzen.


----------



## sparrow (2. Mrz 2008)

Ich sende nun:
	
	
	
	





```
HTTP/1.0 200 OK
server: TestServer
date: Sun, 2 Mar 2008 13:45:36 +0100
last-modified: Sun, 2 Mar 2008 13:45:36 +0100
cache-control: no-cache
pragma: no-cache
connection: close
content-type: application/x-java-archive
content-length: 2255753
```

Leider ändert das am Problem nichts.
Ich habe nun auch mal mitzählen lassen um vielleicht zu sehen ob er immer nach gleichvielen übertragenen Bytes aussteigt. Dem ist  aber nicht so, der Ausstieg erfolgt immer an verschiedenen Stellen.


----------



## Murray (2. Mrz 2008)

Ich nehme an, Content-Length ist dann auch die Länge der Jar-Datei in Bytes.

Warum schreibst Du eigentlich HTTP/1.0? Hast Du es schon mit HTTP/1.1 versucht?


----------



## sparrow (2. Mrz 2008)

Eigentlich wollte ich ja gar keine HTTP 1.1 Funktionalitäten zur Verfügung stellen, deshalb beantworte ich den Request auch nur mit der Angabe von HTTP 1.0.
Aber auch das ändern nutzt leider nichts 


```
HTTP/1.1 302 Found
server: TestServer
date: Sun, 2 Mar 2008 14:31:13 +0100
last-modified: Sun, 2 Mar 2008 14:31:13 +0100
cache-control: no-cache
pragma: no-cache
connection: close
content-type: application/x-java-archive
content-length: 2255753
```

Die Länge von content-length stimmt. Wenn ich mit Firefox auf die URL der Resource zugreife sendet der Server den Header und 2255753 Bytes bevor er den Socket schließt.

Das seltsame ist, und da komm ich jetzt erst drauf: WebStart selber gibt gar keinen Fehler aus. Das macht aber keinen Sinn, denn die Resourcen kommen nicht vollständig auf dem Client an.


----------



## sparrow (4. Mrz 2008)

Hmm.. mich wurmt es irgendwie, dass meine Lösung nicht funktioniert.

Hier mal der entsprechende Code meiner Methode auf dem Server


```
private void sendClientData(OutputStream os,String requestedPage, String host) {
		String page = requestedPage.substring(8);
		int bytesSend = 0;
		try {
			// Looking for the requested name in the pluings
			Vector<String> pluginnames = Main.getClientPluginNames();
			boolean sidefound = false;
			for (int i = 0; i < pluginnames.size(); i++) {
				if (pluginnames.get(i).equals(page)) {
					Main.getLogger().info("Conhandler: " + handlerid + " SEND client resource: " + page);
					sidefound = true;
					File localfile = null;
					if (page.startsWith("lib/")) {
						localfile = new File("./lib/client/" + page.substring(4));
					} else {
						localfile = new File("./plugins/" + page);
					}
					InputStream is = localfile.toURI().toURL().openStream();
					// Setting optional Header-Information for http response
					ArrayList<String> optionalHeaderLines = new ArrayList<String>();
					optionalHeaderLines.add("Content-Length: " + localfile.length());
					sendHeader(os, localfile.toURI().toURL(), optionalHeaderLines);
					// Sending data to client
					int in;
					while ((in = is.read()) > -1) {
						os.write(in);
						bytesSend++;
					}
					Main.getLogger().debug("Conhandler: " + handlerid + ": " + bytesSend + " bytes send to client");
					break;
				}
			}
			if (!sidefound) {
				Main.getLogger().warn("Conhandler: " + handlerid + " WARN no such resource: " + page);
				writeStringToStream(httpError(404, "Page not found"), os);
			}
		} catch (IOException e) {
			Main.getLogger().error("Conhandler: " + handlerid + " ERROR while SENDING RESOURCE to the client: " + page + " : "+ e.getMessage());
			Main.getLogger().debug("Conhandler: " + handlerid + ": " + bytesSend + " bytes send to client");
			e.printStackTrace();
		}
}
```


----------



## sparrow (4. Mrz 2008)

Ich habe den Tipp bekommen nicht direkt an den Client zu senden sondern ein Byte-Array zu füllen welches dann übertragen wird. Leider ändert das nichts am Problem.
Inzwischen habe ich die Vermutung, dass es irgend etwas mit dem Cache von JavaWS zu tun hat. Der Client also meint, dass das Archiv nicht erneuert werden muss und deshalb die Übertragung abbricht.
Nach vielen Versuchen meine ich nun zu wissen, dass der Client die Übertragung im Laufe der Ausführung noch einmal aufnimmt wenn das Archiv fehlerhaft ist. Sicher bin ich mir da allerdings nicht.


```
private void sendClientData(OutputStream os,String requestedPage, String host) {
		String page = requestedPage.substring(8);
		int bytesSend = 0;
		try {
			// Looking for the requested name in the pluings
			Vector<String> pluginnames = Main.getClientPluginNames();
			boolean sidefound = false;
			for (int i = 0; i < pluginnames.size(); i++) {
				if (pluginnames.get(i).equals(page)) {
					Main.getLogger().info("Conhandler: " + handlerid + " SEND client resource: " + page);
					sidefound = true;
					File localfile = null;
					if (page.startsWith("lib/")) {
						localfile = new File("./lib/client/" + page.substring(4));
					} else {
						localfile = new File("./plugins/" + page);
					}
					InputStream is = localfile.toURI().toURL().openStream();
					// Setting optional Header-Information for http response
					ArrayList<String> optionalHeaderLines = new ArrayList<String>();
					optionalHeaderLines.add("Content-Length: " + localfile.length());
					this.sendHeader(os, localfile.toURI().toURL(), optionalHeaderLines);
					// sendint the data to the client
					int in = 0;
					int bufferCounter = 0;
					byte[] sendBuffer = new byte[SEND_BUFFER_SIZE];
					while ((in = is.read()) > -1) {
						sendBuffer[bufferCounter] = (byte) in;
						bufferCounter++;
						if (bufferCounter >= sendBuffer.length) {
							os.write(sendBuffer);
							os.flush();
							sendBuffer = new byte[SEND_BUFFER_SIZE];
							bufferCounter = 0;
						}
						bytesSend++;
					}
					os.write(sendBuffer);
					os.flush();
					os.close();
					Marmota.getLogger().debug("Conhandler: " + handlerid + ": " + bytesSend + " bytes send to client");
					break;
				}
			}
			if (!sidefound) {
				Main.getLogger().warn("Conhandler: " + handlerid + " WARN no such resource: " + page);
				writeStringToStream(httpError(404, "Page not found"), os);
			}
		} catch (IOException e) {
			Main.getLogger().error("Conhandler: " + handlerid + " ERROR while SENDING RESOURCE to the client: " + page + " : "+ e.getMessage());
			Main.getLogger().debug("Conhandler: " + handlerid + ": " + bytesSend + " bytes send to client");
			e.printStackTrace();
		}
	}
```


----------

