/*
* copy the data into a bucket now,
* before we go into the redirect loop
*/
Bucket data;
boolean methodIsConfigurable = true;
String slen = headers.get("content-length");
if (METHODS_MUST_HAVE_DATA.contains(method)) {
// <method> must have data
methodIsConfigurable = false;
if (slen == null) {
ctx.shouldDisconnect = true;
ctx.sendReplyHeaders(400, "Bad Request", null, null, -1);
return;
}
} else if (METHODS_CANNOT_HAVE_DATA.contains(method)) {
// <method> can not have data
methodIsConfigurable = false;
if (slen != null) {
ctx.shouldDisconnect = true;
ctx.sendReplyHeaders(400, "Bad Request", null, null, -1);
return;
}
}
if (slen != null) {
long len;
try {
len = Integer.parseInt(slen);
if(len < 0) throw new NumberFormatException("content-length less than 0");
} catch (NumberFormatException e) {
ctx.shouldDisconnect = true;
ctx.sendReplyHeaders(400, "Bad Request", null, null, -1);
return;
}
if(allowPost && ((!container.publicGatewayMode()) || ctx.isAllowedFullAccess())) {
data = bf.makeBucket(len);
BucketTools.copyFrom(data, is, len);
} else {
FileUtil.skipFully(is, len);
if (method.equals("POST")) {
ctx.sendMethodNotAllowed("POST", true);
} else {
sendError(sock.getOutputStream(), 403, "Forbidden", "Content not allowed in this configuration", true, null);
}
ctx.close();
return;
}
} else {
// we're not doing to use it, but we have to keep
// the compiler happy
data = null;
}
if (!container.enableExtendedMethodHandling()) {
if (!METHODS_RESTRICTED_MODE.contains(method)) {
sendError(sock.getOutputStream(), 403, "Forbidden", "Method not allowed in this configuration", true, null);
return;
}
}
// Handle it.
try {
boolean redirect = true;
while (redirect) {
// don't go around the loop unless set explicitly
redirect = false;
Toadlet t;
try {
t = container.findToadlet(uri);
} catch (PermanentRedirectException e) {
Toadlet.writePermanentRedirect(ctx, "Found elsewhere", e.newuri.toASCIIString());
break;
}
if(t == null) {
ctx.sendNoToadletError(ctx.shouldDisconnect);
break;
}
// if the Toadlet does not support the method, we don't need to parse the data
// also due this pre check a 'NoSuchMethodException' should never appear
if (!(t.findSupportedMethods().contains(method))) {
ctx.sendMethodNotAllowed(method, ctx.shouldDisconnect);
break;
}
HTTPRequestImpl req = new HTTPRequestImpl(uri, data, ctx, method);
// require form password if it's a POST, unless the toadlet requests otherwise
if (method.equals("POST") && !t.allowPOSTWithoutPassword()) {
if (!ctx.checkFormPassword(req, t.path())) {
break;
}
}
if(ctx.isAllowedFullAccess()) {
ctx.getPageMaker().parseMode(req, container);
}
try {
callToadletMethod(t, method, uri, req, ctx, data, sock, redirect);
} catch (RedirectException re) {
uri = re.newuri;
redirect = true;
} finally {
req.freeParts();
}
}
if(ctx.shouldDisconnect) {
sock.close();
return;
}
} finally {
if(data != null) data.free();
}
}
} catch (ParseException e) {
try {