diff --git a/src/helma/servlet/AbstractServletClient.java b/src/helma/servlet/AbstractServletClient.java
index 61fcb7f8..67b90db1 100644
--- a/src/helma/servlet/AbstractServletClient.java
+++ b/src/helma/servlet/AbstractServletClient.java
@@ -71,8 +71,9 @@ public abstract class AbstractServletClient extends HttpServlet {
}
- protected void execute (HttpServletRequest request, HttpServletResponse response, byte method) {
- String protocol = request.getProtocol ();
+ protected void execute (HttpServletRequest request,
+ HttpServletResponse response,
+ byte method) {
Cookie[] cookies = request.getCookies();
RequestTrans reqtrans = new RequestTrans (method);
@@ -111,13 +112,11 @@ public abstract class AbstractServletClient extends HttpServlet {
}
}
} catch (Exception upx) {
- response.setStatus (HttpServletResponse.SC_REQUEST_ENTITY_TOO_LARGE);
- writeError (response, "Sorry, upload size exceeds limit of "+uploadLimit+"kB.");
+ sendError (
+ response,
+ response.SC_REQUEST_ENTITY_TOO_LARGE,
+ "Sorry, upload size exceeds limit of "+uploadLimit+"kB.");
return;
- /* String uploadErr = upx.getMessage ();
- if (uploadErr == null || uploadErr.length () == 0)
- uploadErr = upx.toString ();
- reqtrans.set ("uploadError", uploadErr); */
}
}
@@ -178,20 +177,33 @@ public abstract class AbstractServletClient extends HttpServlet {
String pathInfo = request.getPathInfo ();
ResponseTrans restrans = execute (reqtrans, pathInfo);
- writeResponse (response, restrans, cookies, protocol);
+ writeResponse (request, response, restrans, cookies);
} catch (Exception x) {
- // invalidateApp (appID);
- response.setStatus (HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
- if (debug)
- writeError (response, "Error:
" +x);
- else
- writeError (response, "This server is temporarily unavailable. Please check back later.");
+ try {
+ if (debug)
+ sendError (
+ response,
+ response.SC_INTERNAL_SERVER_ERROR,
+ "Error in request handler:" +x);
+ else
+ sendError (
+ response,
+ response.SC_INTERNAL_SERVER_ERROR,
+ "The server encountered an error while processing your request. "+
+ "Please check back later.");
+ log ("Exception in execute: "+x);
+ } catch (IOException io_e) {
+ log ("Exception in sendError: "+io_e);
+ }
}
}
- void writeResponse (HttpServletResponse res, ResponseTrans trans, Cookie[] cookies, String protocol) {
+ void writeResponse (HttpServletRequest req,
+ HttpServletResponse res,
+ ResponseTrans trans,
+ Cookie[] cookies) {
for (int i = 0; i < trans.countCookies(); i++) try {
Cookie c = new Cookie(trans.getKeyAt(i), trans.getValueAt(i));
@@ -205,19 +217,20 @@ public abstract class AbstractServletClient extends HttpServlet {
} catch (Exception ign) {}
if (trans.getRedirect () != null) {
- try {
- res.sendRedirect(trans.getRedirect ());
- } catch(Exception io_e) {}
+ sendRedirect(req, res, trans.getRedirect ());
} else if (trans.getNotModified ()) {
res.setStatus (HttpServletResponse.SC_NOT_MODIFIED);
} else {
if (!trans.cache || ! caching) {
// Disable caching of response.
- if (protocol == null || !protocol.endsWith ("1.1"))
- res.setHeader ("Pragma", "no-cache"); // for HTTP 1.0
- else
- res.setHeader ("Cache-Control", "no-cache"); // for HTTP 1.1
+ if (isOneDotOne (req.getProtocol ())) {
+ // for HTTP 1.0
+ res.setHeader ("Pragma", "no-cache");
+ } else {
+ // for HTTP 1.1
+ res.setHeader ("Cache-Control", "no-cache");
+ }
}
if ( trans.realm!=null )
res.setHeader( "WWW-Authenticate", "Basic realm=\"" + trans.realm + "\"" );
@@ -239,7 +252,7 @@ public abstract class AbstractServletClient extends HttpServlet {
try {
OutputStream out = res.getOutputStream ();
out.write (trans.getContent ());
- out.close ();
+ out.flush ();
} catch(Exception io_e) {
log ("Exception in writeResponse: "+io_e);
}
@@ -247,30 +260,62 @@ public abstract class AbstractServletClient extends HttpServlet {
}
- void writeError (HttpServletResponse res, String message) {
- try {
- res.setContentType ("text/html");
- Writer out = res.getWriter ();
- out.write (message);
- out.flush ();
- } catch (Exception io_e) {
- // ignore
+ void sendError (HttpServletResponse response, int code, String message)
+ throws IOException {
+ response.reset ();
+ response.setStatus (code);
+ response.setContentType ("text/html");
+ Writer writer = response.getWriter ();
+ writer.write (message);
+ writer.flush ();
+ }
+
+ void sendRedirect (HttpServletRequest req, HttpServletResponse res, String url) {
+ String location = url;
+ if (url.indexOf ("://") == -1)
+ {
+ // need to transform a relative URL into an absolute one
+ String scheme = req.getScheme ();
+ StringBuffer loc = new StringBuffer(scheme);
+ loc.append ("://");
+ loc.append (req.getServerName ());
+ int p = req.getServerPort ();
+ // check if we need to include server port
+ if (p > 0 &&
+ (("http".equals(scheme) && p != 80) ||
+ ("https".equals(scheme) && p != 443)))
+ {
+ loc.append (":");
+ loc.append (p);
+ }
+ if (!url.startsWith ("/"))
+ {
+ String requri = req.getRequestURI ();
+ int lastSlash = requri.lastIndexOf ("/");
+ if (lastSlash == requri.length()-1)
+ loc.append (requri);
+ else if (lastSlash > -1)
+ loc.append (requri.substring (0, lastSlash+1));
+ else
+ loc.append ("/");
+ }
+ loc.append (url);
+ location = loc.toString ();
}
+ res.reset ();
+ // send status code 303 for HTTP 1.1, 302 otherwise
+ if (isOneDotOne (req.getProtocol ()))
+ res.setStatus (res.SC_SEE_OTHER);
+ else
+ res.setStatus (res.SC_MOVED_TEMPORARILY);
+ res.setContentType ("text/html");
+ res.setHeader ("Location", location);
}
FileUpload getUpload (HttpServletRequest request) throws Exception {
int contentLength = request.getContentLength ();
BufferedInputStream in = new BufferedInputStream (request.getInputStream ());
if (contentLength > uploadLimit*1024) {
- // consume all input to make Apache happy
- /* byte b[] = new byte[4096];
- int read = 0;
- int sum = 0;
- while (read > -1 && sum < contentLength) {
- read = in.read (b, 0, 4096);
- if (read > 0)
- sum += read;
- } */
throw new RuntimeException ("Upload exceeds limit of "+uploadLimit+" kb.");
}
String contentType = request.getContentType ();
@@ -424,6 +469,14 @@ public abstract class AbstractServletClient extends HttpServlet {
return 0;
}
+ boolean isOneDotOne (String protocol) {
+ if (protocol == null)
+ return false;
+ if (protocol.endsWith ("1.1"))
+ return true;
+ return false;
+ }
+
public String getServletInfo(){
return new String("Helma Servlet Client");
}