@@ -95,6 +95,9 @@ static String getClassNameURL(SimpleRPCRunnable runnable) {
95
95
96
96
private static void ajaxRequest (final SimpleRPCRunnable runnable ) {
97
97
String url = runnable .getHttpURL ();
98
+ if (url == null ) {
99
+ url = "" ;
100
+ }
98
101
String method = runnable .getHttpMethod ();
99
102
String serialize = runnable .serialize ();
100
103
if (method == null ) {
@@ -331,28 +334,25 @@ protected static boolean checkXSS(String url, String serialize, SimpleRPCRunnabl
331
334
* @j2sNative
332
335
return function () {
333
336
var g = net.sf.j2s.ajax.SimpleRPCRequest;
334
- var hKey = "h" + rnd;
335
- if (g.idSet[hKey] != null) {
336
- window.clearTimeout (g.idSet[hKey]);
337
- delete g.idSet[hKey];
338
- }
339
- if (window["net"] != null && !net.sf.j2s.ajax.SimpleRPCRequest.cleanUp(oScript)) {
337
+ if (!g.cleanUp(script)) {
340
338
return; // IE, not completed yet
341
339
}
342
- var src = oScript.src;
343
- var idx = src.indexOf ("jzn=");
344
- var rid = src.substring (idx + 4, src.indexOf ("&", idx));
345
- net.sf.j2s.ajax.SimpleRPCRequest.xssNotify (rid, null);
346
- if (oScript.onerror != null) { // W3C
347
- oScript.onerror = oScript.onload = null;
340
+ if (error) {
341
+ var src = script.src;
342
+ var idx = src.indexOf ("jzn=");
343
+ var rid = src.substring (idx + 4, src.indexOf ("&", idx));
344
+ net.sf.j2s.ajax.SimpleRPCRequest.xssNotify (rid, null);
345
+ }
346
+ if (script.onerror != null) { // W3C
347
+ script.onerror = script.onload = null;
348
348
} else { // IE
349
- oScript .onreadystatechange = null;
349
+ script .onreadystatechange = null;
350
350
}
351
- document.getElementsByTagName ("HEAD")[0].removeChild (oScript );
352
- oScript = null;
351
+ document.getElementsByTagName ("HEAD")[0].removeChild (script );
352
+ script = null;
353
353
};
354
354
*/
355
- native static Object generateCallback4Script (Object oScript , String rnd );
355
+ native static Object generateCallback4Script (Object script , String rnd , boolean error );
356
356
357
357
/**
358
358
* @j2sNative
@@ -368,19 +368,28 @@ protected static boolean checkXSS(String url, String serialize, SimpleRPCRunnabl
368
368
script.type = "text/javascript";
369
369
script.src = url + "?jzn=" + rnd + "&jzp=" + length
370
370
+ "&jzc=" + (i + 1) + "&jzz=" + content;
371
- var fun = g.generateCallback4Script (script, rnd);
371
+ var okFun = g.generateCallback4Script (script, rnd, false);
372
+ var errFun = g.generateCallback4Script (script, rnd, true);
372
373
var userAgent = navigator.userAgent.toLowerCase ();
373
374
var isOpera = (userAgent.indexOf ("opera") != -1);
374
375
var isIE = (userAgent.indexOf ("msie") != -1) && !isOpera;
375
376
script.defer = true;
376
377
if (typeof (script.onreadystatechange) == "undefined" || !isIE) { // W3C
377
- script.onerror = script.onload = fun;
378
- } else { // IE
379
- script.onreadystatechange = fun;
378
+ script.onerror = errFun;
379
+ script.onload = okFun;
380
+ } else { // IE, IE won't detect script loading error until timeout!
381
+ script.onreadystatechange = okFun;
380
382
}
381
383
var head = document.getElementsByTagName ("HEAD")[0];
382
384
head.appendChild (script);
383
- g.idSet["h" + rnd] = window.setTimeout (fun, 30000); // 30s timeout // TODO: Expose to configuration
385
+ var timeout = 30000;
386
+ if (window["j2s.ajax.reqeust.timeout"] != null) {
387
+ timeout = window["j2s.ajax.reqeust.timeout"];
388
+ }
389
+ if (timeout < 1000) {
390
+ timeout = 1000; // at least 1s for timeout
391
+ }
392
+ g.idSet["h" + rnd] = window.setTimeout (errFun, timeout);
384
393
*/
385
394
native static void callByScript (String rnd , String length , String i , String content );
386
395
@@ -409,11 +418,17 @@ static void xssNotify(String nameID, String response, String session) {
409
418
var ss = document.getElementsByTagName ("SCRIPT");
410
419
for (var i = 0; i < ss.length; i++) {
411
420
var s = ss[i];
412
- if (s.src != null && s.src.indexOf ("jzn=" + nameID) != -1
421
+ if (s.src != null && s.src.indexOf ("jzn=" + nameID) != -1 // FIXME: Not totally safe
413
422
&& s.readyState == "interactive") {
414
423
s.onreadystatechange = net.sf.j2s.ajax.SimpleRPCRequest.ieScriptCleanup;
415
424
}
416
425
}
426
+ }
427
+ var hKey = "h" + nameID;
428
+ var g = net.sf.j2s.ajax.SimpleRPCRequest;
429
+ if (g.idSet[hKey] != null) {
430
+ window.clearTimeout (g.idSet[hKey]);
431
+ delete g.idSet[hKey];
417
432
}
418
433
*/ { }
419
434
if (response == "continue" ) {
@@ -425,16 +440,27 @@ static void xssNotify(String nameID, String response, String session) {
425
440
}
426
441
var k = "x" + nameID;
427
442
var xcontent = g.idSet[k];
428
- // TODO: The following codes should be modified to send out requests one by one.
429
443
if (xcontent != null) {
444
+ // Send out requests one by one.
430
445
for (var i = 0; i < xcontent.length; i++) {
431
446
if (xcontent[i] != null) {
432
447
g.callByScript(nameID, xcontent.length, i, xcontent[i]);
433
448
xcontent[i] = null;
449
+ break;
434
450
}
435
- }
436
- g.idSet[k] = null;
437
- delete g.idSet[k];
451
+ }
452
+
453
+ var more = false;
454
+ for (var i = xcontent.length - 1; i >= 0; i--) {
455
+ if (xcontent[i] != null) {
456
+ more = true;
457
+ break;
458
+ }
459
+ }
460
+ if (!more) { // all contents are sent
461
+ g.idSet[k] = null;
462
+ delete g.idSet[k];
463
+ }
438
464
}
439
465
*/ {}
440
466
return ;
0 commit comments