Skip to content

Commit 1601986

Browse files
author
jossonsmith
committed
Update HttpRequest according to http://www.w3.org/TR/XMLHttpRequest/
1 parent ddacb00 commit 1601986

File tree

9 files changed

+377
-156
lines changed

9 files changed

+377
-156
lines changed

sources/net.sf.j2s.ajax/.j2s

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
#Java2Script Configuration
2-
#Fri Oct 13 01:55:41 CST 2006
2+
#Sun Oct 15 00:35:31 CST 2006
33
j2s.abandoned.resources.list=bin/net/sf/j2s/ajax/AjaxPlugin.js,bin/net/sf/j2s/ajax/AJAXVariableInitializer.js
44
j2s.compiler.abbreviation=true
55
j2s.compiler.status=enable
66
j2s.compiler.abbreviation.prefix=$_
77
j2s.compiler.mode=debug
8-
j2s.resources.list=bin/net/sf/j2s/ajax/XHRCallbackSWTAdapter.js,bin/net/sf/j2s/ajax/XHRCallbackAdapter.js,bin/net/sf/j2s/ajax/IXHRCallback.js,bin/net/sf/j2s/ajax/HttpRequest.js,bin/net/sf/j2s/ajax/AClass.js,bin/net/sf/j2s/ajax/ASWTClass.js,bin/net/sf/j2s/ajax/ARunnable.js,bin/net/sf/j2s/ajax/AJAXServletRequest.js,bin/net/sf/j2s/ajax/AJAXServletSWTRequest.js,bin/net/sf/j2s/ajax/Base64.js,bin/net/sf/j2s/ajax/SimpleSerializable.js,bin/net/sf/j2s/ajax/SimpleRPCRunnable.js,bin/net/sf/j2s/ajax/SimpleRPCHttpServlet.js
8+
j2s.resources.list=../../plugins/net.sf.j2s.lib_1.0.0/j2slib/java.runtime.j2x,bin/net/sf/j2s/ajax/XHRCallbackSWTAdapter.js,bin/net/sf/j2s/ajax/XHRCallbackAdapter.js,bin/net/sf/j2s/ajax/IXHRCallback.js,bin/net/sf/j2s/ajax/HttpRequest.js,bin/net/sf/j2s/ajax/AClass.js,bin/net/sf/j2s/ajax/ASWTClass.js,bin/net/sf/j2s/ajax/ARunnable.js,bin/net/sf/j2s/ajax/Base64.js,bin/net/sf/j2s/ajax/SimpleSerializable.js,bin/net/sf/j2s/ajax/SimpleRPCRunnable.js,bin/net/sf/j2s/ajax/SimpleRPCHttpServlet.js,bin/net/sf/j2s/ajax/SimpleRPCRequest.js,bin/net/sf/j2s/ajax/SimpleRPCSWTRequest.js,bin/net/sf/j2s/ajax/Base64Auth.js
99
j2s.compiler.whitespace=false
1010
j2s.output.path=bin
1111
j2s.compiler.linebreak=\r\n

sources/net.sf.j2s.ajax/ajaxcore/net/sf/j2s/ajax/HttpRequest.java

Lines changed: 220 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
import java.io.DataOutputStream;
1919
import java.io.IOException;
2020
import java.io.InputStream;
21+
import java.io.OutputStream;
2122
import java.net.HttpURLConnection;
2223
import java.net.URL;
2324
import java.util.HashMap;
@@ -39,7 +40,83 @@
3940
* 2006-2-11
4041
*/
4142
public final class HttpRequest {
43+
/*
44+
* @(#)Base64.java 1.4 03/01/23
45+
*
46+
* Copyright 2003 Sun Microsystems, Inc. All rights reserved.
47+
* SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
48+
*/
49+
50+
/**
51+
* Static methods for translating Base64 encoded strings to byte arrays
52+
* and vice-versa.
53+
*
54+
* @author Josh Bloch
55+
* @version 1.4, 01/23/03
56+
* @see Preferences
57+
* @since 1.4
58+
*/
59+
static class Base64 {
60+
/**
61+
* Translates the specified byte array into a Base64 string as per
62+
* Preferences.put(byte[]).
63+
*/
64+
static String byteArrayToBase64(byte[] a) {
65+
int aLen = a.length;
66+
int numFullGroups = aLen/3;
67+
int numBytesInPartialGroup = aLen - 3*numFullGroups;
68+
int resultLen = 4*((aLen + 2)/3);
69+
StringBuffer result = new StringBuffer(resultLen);
70+
char[] intToAlpha = intToBase64;
71+
72+
// Translate all full groups from byte array elements to Base64
73+
int inCursor = 0;
74+
for (int i=0; i<numFullGroups; i++) {
75+
int byte0 = a[inCursor++] & 0xff;
76+
int byte1 = a[inCursor++] & 0xff;
77+
int byte2 = a[inCursor++] & 0xff;
78+
result.append(intToAlpha[byte0 >> 2]);
79+
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
80+
result.append(intToAlpha[(byte1 << 2)&0x3f | (byte2 >> 6)]);
81+
result.append(intToAlpha[byte2 & 0x3f]);
82+
}
83+
84+
// Translate partial group if present
85+
if (numBytesInPartialGroup != 0) {
86+
int byte0 = a[inCursor++] & 0xff;
87+
result.append(intToAlpha[byte0 >> 2]);
88+
if (numBytesInPartialGroup == 1) {
89+
result.append(intToAlpha[(byte0 << 4) & 0x3f]);
90+
result.append("==");
91+
} else {
92+
// assert numBytesInPartialGroup == 2;
93+
int byte1 = a[inCursor++] & 0xff;
94+
result.append(intToAlpha[(byte0 << 4)&0x3f | (byte1 >> 4)]);
95+
result.append(intToAlpha[(byte1 << 2)&0x3f]);
96+
result.append('=');
97+
}
98+
}
99+
// assert inCursor == a.length;
100+
// assert result.length() == resultLen;
101+
return result.toString();
102+
}
103+
104+
/**
105+
* This array is a lookup table that translates 6-bit positive integer
106+
* index values into their "Base64 Alphabet" equivalents as specified
107+
* in Table 1 of RFC 2045.
108+
*/
109+
private static final char intToBase64[] = {
110+
'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M',
111+
'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z',
112+
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm',
113+
'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
114+
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '+', '/'
115+
};
116+
}
117+
42118
private int status;
119+
private String statusText;
43120
private int readyState;
44121

45122
private String responseText;
@@ -51,10 +128,17 @@ public final class HttpRequest {
51128
private HttpURLConnection connection;
52129
private String url;
53130
private String method;
131+
private String user;
132+
private String password;
54133

55134
private Map headers = new HashMap();
56135
private String content;
57136

137+
private boolean toAbort = false;
138+
private boolean isDisconnected = false;
139+
private OutputStream activeOS;
140+
private InputStream activeIS;
141+
58142
/**
59143
* Return read state of XMLHttpRequest.
60144
* @return int ready state
@@ -79,28 +163,41 @@ public Document getResponseXML() {
79163
if (responseXML != null) {
80164
return responseXML;
81165
}
82-
if (responseText != null && responseText.length() != 0) {
83-
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
84-
dbf.setNamespaceAware(true);
85-
dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
86-
try {
87-
DocumentBuilder db = dbf.newDocumentBuilder();
88-
ByteArrayInputStream biStream = new ByteArrayInputStream(responseText.getBytes());
89-
responseXML = db.parse(biStream);
90-
} catch (Exception e) {
91-
e.printStackTrace();
92-
}
166+
String type = connection.getHeaderField("Content-Type");
167+
if (type != null && (type.indexOf("/xml") != -1 || type.indexOf("+xml") != -1)) {
168+
if (responseText != null && responseText.length() != 0) {
169+
DocumentBuilderFactory dbf = DocumentBuilderFactory.newInstance();
170+
dbf.setNamespaceAware(true);
171+
dbf.setAttribute("http://xml.org/sax/features/namespaces", Boolean.TRUE);
172+
try {
173+
DocumentBuilder db = dbf.newDocumentBuilder();
174+
ByteArrayInputStream biStream = new ByteArrayInputStream(responseText.getBytes());
175+
responseXML = db.parse(biStream);
176+
} catch (Exception e) {
177+
e.printStackTrace();
178+
}
179+
}
180+
return responseXML;
181+
} else {
182+
return null;
93183
}
94-
return responseXML;
95184
}
96185
/**
97186
* Return respose code.
98187
* @return int response code. For more information please read about
99188
* HTTP protocol.
100189
*/
101-
public int getResponseCode() {
190+
public int getStatus() {
102191
return status;
103192
}
193+
/**
194+
* Return respose code related text.
195+
* @return int response code. For more information please read about
196+
* HTTP protocol.
197+
*/
198+
public String getStatusText() {
199+
return statusText;
200+
}
104201
/**
105202
* Register XMLHttpRequest callback.
106203
*
@@ -118,6 +215,29 @@ public void registerOnReadyStateChange(IXHRCallback onreadystatechange) {
118215
public void setRequestHeader(String key, String value) {
119216
headers.put(key, value);
120217
}
218+
/**
219+
* Get all response heades.
220+
* @return String the all reponse header value.
221+
*/
222+
public String getAllResponseHeaders() {
223+
StringBuffer buffer = new StringBuffer();
224+
int i = 1;
225+
while (true) {
226+
String key = connection.getHeaderFieldKey(i);
227+
if (key != null) {
228+
String value = connection.getHeaderField(i);
229+
buffer.append(key);
230+
buffer.append(": ");
231+
buffer.append(value);
232+
buffer.append("\r\n");
233+
} else {
234+
break;
235+
}
236+
i++;
237+
}
238+
buffer.append("\r\n");
239+
return buffer.toString();
240+
}
121241
/**
122242
* Get response header with given key.
123243
* @param key String header keyword. For more information please
@@ -135,7 +255,7 @@ public String getResponseHeader(String key) {
135255
* @param url String remote URL. Should always be absolute URL.
136256
*/
137257
public void open(String method, String url) {
138-
open(method, url, false);
258+
open(method, url, false, null, null);
139259
}
140260
/**
141261
* Open connection for HTTP request with given method, URL and mode.
@@ -145,14 +265,42 @@ public void open(String method, String url) {
145265
* @param async boolean whether send request asynchronously or not.
146266
*/
147267
public void open(String method, String url, boolean async) {
268+
open(method, url, async, null, null);
269+
}
270+
/**
271+
* Open connection for HTTP request with given method, URL and mode.
272+
*
273+
* @param method String "POST" or "GET" usually.
274+
* @param url String remote URL. Should always be absolute URL.
275+
* @param async boolean whether send request asynchronously or not.
276+
* @param user String user name
277+
*/
278+
public void open(String method, String url, boolean async, String user) {
279+
open(method, url, async, user, null);
280+
}
281+
/**
282+
* Open connection for HTTP request with given method, URL and mode.
283+
*
284+
* @param method String "POST" or "GET" usually.
285+
* @param url String remote URL. Should always be absolute URL.
286+
* @param async boolean whether send request asynchronously or not.
287+
* @param user String user name
288+
* @param password String user password
289+
*/
290+
public void open(String method, String url, boolean async, String user, String password) {
148291
this.asynchronous = async;
149292
this.method = method;
150293
this.url = url;
294+
this.user = user;
295+
this.password = password;
151296
responseText = null;
152297
responseXML = null;
153298
readyState = 1;
299+
status = 200; // default OK
300+
statusText = null;
301+
toAbort = false;
154302
if (onreadystatechange != null) {
155-
onreadystatechange.onLoading();
303+
onreadystatechange.onOpen();
156304
}
157305
}
158306

@@ -171,13 +319,47 @@ public void send(String str) {
171319
if (asynchronous) {
172320
new Thread(new Runnable() {
173321
public void run() {
174-
request();
322+
if (!toAbort) {
323+
request();
324+
}
175325
}
176326
}).start();
177327
} else {
178328
request();
179329
}
180330
}
331+
/**
332+
* Abort the sending or receiving data process.
333+
*/
334+
public void abort() {
335+
toAbort = true;
336+
isDisconnected = false;
337+
checkAbort();
338+
}
339+
private boolean checkAbort() {
340+
if (!toAbort) return false;
341+
if (activeOS != null) {
342+
try {
343+
activeOS.close();
344+
} catch (IOException e) {
345+
e.printStackTrace();
346+
}
347+
activeOS = null;
348+
}
349+
if (activeIS != null) {
350+
try {
351+
activeIS.close();
352+
} catch (IOException e) {
353+
e.printStackTrace();
354+
}
355+
activeIS = null;
356+
}
357+
if (!isDisconnected && connection != null) {
358+
connection.disconnect();
359+
isDisconnected = true;
360+
}
361+
return true;
362+
}
181363
/*
182364
* Try setup the real connection and send the request over HTTP protocol.
183365
*/
@@ -193,44 +375,59 @@ private void request() {
193375
connection.setRequestProperty("Content-Type",
194376
"application/x-www-form-urlencoded");
195377
}
378+
if (user != null) {
379+
String auth = user + ":" + (password != null ? password : "");
380+
String base64Auth = HttpRequest.Base64.byteArrayToBase64(auth.getBytes());
381+
connection.setRequestProperty("Authorization", "Basic " + base64Auth);
382+
}
196383
for (Iterator iter = headers.keySet().iterator(); iter.hasNext();) {
197384
String key = (String) iter.next();
198385
connection.setRequestProperty(key, (String) headers.get(key));
199386
}
200387
connection.setUseCaches(false);
388+
if (checkAbort()) return; // not yet send out a byte
201389
if ("post".equalsIgnoreCase(method)) {
202390
DataOutputStream dos = new DataOutputStream(connection.getOutputStream());
391+
activeOS = dos;
203392
if (content != null) {
204393
dos.writeBytes(content);
205394
}
395+
if (checkAbort()) return; // do not flush anything and close the connection
206396
dos.flush();
207397
dos.close();
398+
activeOS = null;
208399
}
400+
if (checkAbort()) return; // just disconnect without receiving anything
209401
InputStream is = connection.getInputStream();
402+
activeIS = is;
210403
ByteArrayOutputStream baos = new ByteArrayOutputStream();
211404
byte[] buffer = new byte[1024];
212405
int read;
213-
while ((read = is.read(buffer)) != -1) {
406+
while (!toAbort && (read = is.read(buffer)) != -1) {
407+
if (checkAbort()) return; // stop receiving anything
214408
if (readyState < 2) {
215409
readyState = 2;
410+
status = connection.getResponseCode();
411+
statusText = connection.getResponseMessage();
216412
if (onreadystatechange != null) {
217-
onreadystatechange.onLoaded();
413+
onreadystatechange.onSent();
218414
}
219415
}
220416
baos.write(buffer, 0, read);
221417
if (readyState != 3) {
222418
readyState = 3;
223419
if (onreadystatechange != null) {
224-
onreadystatechange.onInteractive();
420+
onreadystatechange.onReceiving();
225421
}
226422
}
227423
}
424+
if (checkAbort()) return; // stop receiving anything
228425
is.close();
426+
activeIS = null;
229427
responseText = baos.toString();
230-
status = connection.getResponseCode();
231428
readyState = 4;
232429
if (onreadystatechange != null) {
233-
onreadystatechange.onComplete();
430+
onreadystatechange.onLoaded();
234431
}
235432
connection.disconnect();
236433
readyState = 0;
@@ -240,10 +437,11 @@ private void request() {
240437
}
241438
*/
242439
} catch (IOException e) {
440+
if (checkAbort()) return; // exception caused by abort action
243441
e.printStackTrace();
244442
readyState = 4;
245443
if (onreadystatechange != null) {
246-
onreadystatechange.onComplete();
444+
onreadystatechange.onLoaded();
247445
}
248446
connection = null;
249447
readyState = 0;

0 commit comments

Comments
 (0)