Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit f8081a1

Browse files
author
zhourenjian
committed
Fixed bug that the first Simple RPC requests is not correctly dealt because of the
session problem. And now Simple RPC supports large request even when session cookie is disabled in browsers by using URL ";jsessionid=..." rewrite. If client developers do not like ";jsessionid=...", make sure add a line: window["script.get.session.url"] = false;
1 parent 86dea1a commit f8081a1

File tree

2 files changed

+97
-37
lines changed

2 files changed

+97
-37
lines changed

sources/net.sf.j2s.ajax/ajaxrpc/net/sf/j2s/ajax/SimpleRPCHttpServlet.java

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -384,19 +384,19 @@ private String prepareScriptRequest(HttpServletRequest req, HttpServletResponse
384384
return null;
385385
}
386386

387-
// clean dead session bodies
388-
cleanSession(req);
389-
390-
// store request in session before the request is completed
391-
HttpSession session = req.getSession();
392-
393387
String attrName = "jzn" + scriptRequestID;
394388
String attrTime = "jzt" + scriptRequestID;
395389
String[] parts = null;
396390

397391
boolean badRequest = false;
398392
boolean toContinue = false;
393+
394+
// store request in session before the request is completed
395+
HttpSession session = req.getSession();
399396
synchronized (session) {
397+
// clean dead session bodies
398+
cleanSession(session);
399+
400400
Object attr = session.getAttribute(attrName);
401401
if (attr == null) {
402402
parts = new String[partsCount];
@@ -409,14 +409,12 @@ private String prepareScriptRequest(HttpServletRequest req, HttpServletResponse
409409
}
410410
}
411411
if (!badRequest) {
412-
synchronized (parts) {
413-
parts[curPart - 1] = request;
414-
for (int i = 0; i < parts.length; i++) {
415-
if (parts[i] == null) {
416-
// not completed yet! just response and wait next request.
417-
toContinue = true;
418-
break;
419-
}
412+
parts[curPart - 1] = request;
413+
for (int i = 0; i < parts.length; i++) {
414+
if (parts[i] == null) {
415+
// not completed yet! just response and wait next request.
416+
toContinue = true;
417+
break;
420418
}
421419
}
422420
if (!toContinue) {
@@ -433,7 +431,13 @@ private String prepareScriptRequest(HttpServletRequest req, HttpServletResponse
433431
if (toContinue) {
434432
resp.setContentType("text/javascript");
435433
//resp.setCharacterEncoding("utf-8");
436-
resp.getWriter().write("net.sf.j2s.ajax.SimpleRPCRequest" +
434+
PrintWriter writer = resp.getWriter();
435+
if (curPart == 1) {
436+
// Cookie may be disabled in client side!
437+
writer.write("net.sf.j2s.ajax.SimpleRPCRequest" +
438+
".xssSession(\"" + scriptRequestID + "\", \"" + session.getId() + "\");\r\n");
439+
}
440+
writer.write("net.sf.j2s.ajax.SimpleRPCRequest" +
437441
".xssNotify(\"" + scriptRequestID + "\", \"continue\");");
438442
return null;
439443
}
@@ -446,18 +450,16 @@ private String prepareScriptRequest(HttpServletRequest req, HttpServletResponse
446450
return buf.toString();
447451
}
448452

449-
private void cleanSession(HttpServletRequest req) {
450-
HttpSession ses = req.getSession(false);
451-
if (ses != null) { // try to clean expired request!
452-
Enumeration attrNames = ses.getAttributeNames();
453-
while (attrNames.hasMoreElements()) {
454-
String name = (String) attrNames.nextElement();
455-
if (name.startsWith("jzt")) {
456-
Date dt = (Date) ses.getAttribute(name);
457-
if (new Date().getTime() - dt.getTime() > maxXSSRequestLatency()) {
458-
ses.removeAttribute(name);
459-
ses.removeAttribute("jzn" + name.substring(3));
460-
}
453+
private void cleanSession(HttpSession ses) {
454+
// try to clean expired request!
455+
Enumeration attrNames = ses.getAttributeNames();
456+
while (attrNames.hasMoreElements()) {
457+
String name = (String) attrNames.nextElement();
458+
if (name.startsWith("jzt")) {
459+
Date dt = (Date) ses.getAttribute(name);
460+
if (new Date().getTime() - dt.getTime() > maxXSSRequestLatency()) {
461+
ses.removeAttribute(name);
462+
ses.removeAttribute("jzn" + name.substring(3));
461463
}
462464
}
463465
}

sources/net.sf.j2s.ajax/ajaxrpc/net/sf/j2s/ajax/SimpleRPCRequest.java

Lines changed: 68 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,7 @@ protected static boolean checkXSS(String url, String serialize, SimpleRPCRunnabl
160160
var ua = navigator.userAgent.toLowerCase ();
161161
if (ua.indexOf ("msie")!=-1 && ua.indexOf ("opera") == -1){
162162
limit = 2048;
163+
limit = 2048 - 44; // ;jsessionid=
163164
}
164165
limit -= url.length + 36; // 5 + 6 + 5 + 2 + 5 + 2 + 5;
165166
var contents = [];
@@ -186,11 +187,33 @@ protected static boolean checkXSS(String url, String serialize, SimpleRPCRunnabl
186187
} else {
187188
contents[0] = content;
188189
}
189-
for (var i = 0; i < contents.length; i++) {
190+
g.idSet["x" + rnd] = contents;
191+
// Only send the first request, later server return "continue", and client will get
192+
// the session id and continue later requests.
193+
net.sf.j2s.ajax.SimpleRPCRequest.callByScript(rnd, contents.length, 0, contents[0]);
194+
contents[0] = null;
195+
return true; // cross site script!
196+
}
197+
}
198+
*/ { }
199+
return false;
200+
}
201+
202+
static void callByScript(String rnd, String length, String i, String content) {
203+
/**
204+
* @j2sNative
205+
var g = net.sf.j2s.ajax.SimpleRPCRequest;
206+
var runnable = g.idSet["o" + rnd];
207+
if (runnable == null) return;
208+
var url = runnable.getHttpURL();
209+
var session = g.idSet["s" + rnd];
210+
if (session != null && window["script.get.session.url"] != false) {
211+
url += ";jsessionid=" + session;
212+
}
190213
var script = document.createElement ("SCRIPT");
191214
script.type = "text/javascript";
192-
script.src = url + "?jzn=" + rnd + "&jzp=" + contents.length
193-
+ "&jzc=" + (i + 1) + "&jzz=" + contents[i];
215+
script.src = url + "?jzn=" + rnd + "&jzp=" + length
216+
+ "&jzc=" + (i + 1) + "&jzz=" + content;
194217
if (typeof (script.onreadystatechange) == "undefined") { // W3C
195218
script.onerror = function () {
196219
this.onerror = null;
@@ -223,12 +246,25 @@ protected static boolean checkXSS(String url, String serialize, SimpleRPCRunnabl
223246
}
224247
var head = document.getElementsByTagName ("HEAD")[0];
225248
head.appendChild (script);
226-
}
227-
return true; // cross site script!
228-
}
229-
}
230-
*/ { }
231-
return false;
249+
*/ {}
250+
}
251+
252+
static void sendRestRequests(String nameID) {
253+
/**
254+
* The following codes may be modified to send out requests one by one.
255+
* @j2sNative
256+
* var g = net.sf.j2s.ajax.SimpleRPCRequest;
257+
* var xcontent = g.idSet["x" + nameID];
258+
* if (xcontent != null) {
259+
* for (var i = 0; i < xcontent.length; i++) {
260+
* if (xcontent[i] != null) {
261+
* g.callByScript(nameID, xcontent.length, i, xcontent[i]);
262+
* xcontent[i] = null;
263+
* }
264+
* }
265+
* g.idSet["x" + nameID] = null;
266+
* }
267+
*/ {}
232268
}
233269

234270
/**
@@ -258,13 +294,27 @@ static void xssNotify(String nameID, String response) {
258294
}
259295
}
260296
*/ { }
261-
if (response == "continue") return;
297+
if (response == "continue") {
298+
boolean restNotEmpty = false;
299+
/**
300+
* @j2sNative
301+
* var g = net.sf.j2s.ajax.SimpleRPCRequest;
302+
* if (g.idSet["x" + nameID] != null) {
303+
* restNotEmpty = true;
304+
* }
305+
*/ {}
306+
if (restNotEmpty) sendRestRequests(nameID);
307+
return;
308+
}
262309
SimpleRPCRunnable runnable = null;
263310
/**
264311
* @j2sNative
265312
var g = net.sf.j2s.ajax.SimpleRPCRequest;
266313
runnable = g.idSet["o" + nameID];
267314
g.idSet["o" + nameID] = null;
315+
if (g.idSet["s" + nameID] != null) {
316+
g.idSet["s" + nameID] = null;
317+
}
268318
if (response == null && runnable != null) { // error!
269319
runnable.ajaxFail();
270320
return;
@@ -305,4 +355,12 @@ static void xssNotify(String nameID, String response) {
305355
runnable.ajaxOut();
306356
}
307357
}
358+
359+
static void xssSession(String nameID, String sessionID) {
360+
/**
361+
* @j2sNative
362+
var g = net.sf.j2s.ajax.SimpleRPCRequest;
363+
g.idSet["s" + nameID] = sessionID;
364+
*/ {}
365+
}
308366
}

0 commit comments

Comments
 (0)