290 lines
8.6 KiB
Java
290 lines
8.6 KiB
Java
// ServletClient.java
|
|
// Copyright (c) Hannes Wallnöfer, Raphael Spannocchi 1998-2000
|
|
|
|
/* Portierung von helma.asp.AspClient auf Servlets */
|
|
/* Author: Raphael Spannocchi Datum: 27.11.1998 */
|
|
|
|
package helma.servlet;
|
|
|
|
import javax.servlet.*;
|
|
import javax.servlet.http.*;
|
|
import java.io.*;
|
|
import java.rmi.Naming;
|
|
import java.rmi.RemoteException;
|
|
import java.util.*;
|
|
import helma.framework.*;
|
|
import helma.util.*;
|
|
|
|
/**
|
|
* This is an abstract Hop servlet adapter. This class communicates with hop applications
|
|
* via RMI. Subclasses are either one servlet per app, or one servlet that handles multiple apps
|
|
*/
|
|
|
|
public abstract class AbstractServletClient extends HttpServlet {
|
|
|
|
String host = null;
|
|
int port = 0;
|
|
int uploadLimit; // limit to HTTP uploads in kB
|
|
String hopUrl;
|
|
String cookieDomain;
|
|
boolean caching;
|
|
boolean debug;
|
|
|
|
static final byte HTTP_GET = 0;
|
|
static final byte HTTP_POST = 1;
|
|
|
|
public void init (ServletConfig init) throws ServletException {
|
|
super.init (init);
|
|
|
|
host = init.getInitParameter ("host");
|
|
if (host == null) host = "localhost";
|
|
|
|
String portstr = init.getInitParameter ("port");
|
|
port = portstr == null ? 5055 : Integer.parseInt (portstr);
|
|
|
|
String upstr = init.getInitParameter ("uploadLimit");
|
|
uploadLimit = upstr == null ? 1024 : Integer.parseInt (upstr);
|
|
|
|
cookieDomain = init.getInitParameter ("cookieDomain");
|
|
|
|
hopUrl = "//" + host + ":" + port + "/";
|
|
|
|
debug = ("true".equalsIgnoreCase (init.getInitParameter ("debug")));
|
|
|
|
caching = ! ("false".equalsIgnoreCase (init.getInitParameter ("caching")));
|
|
}
|
|
|
|
|
|
abstract IRemoteApp getApp (String appID) throws Exception;
|
|
|
|
abstract void invalidateApp (String appID);
|
|
|
|
abstract String getAppID (String reqpath);
|
|
|
|
abstract String getRequestPath (String reqpath);
|
|
|
|
|
|
public void doGet (HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
execute (request, response, HTTP_GET);
|
|
}
|
|
|
|
public void doPost (HttpServletRequest request, HttpServletResponse response)
|
|
throws ServletException, IOException {
|
|
execute (request, response, HTTP_POST);
|
|
}
|
|
|
|
|
|
protected void execute (HttpServletRequest request, HttpServletResponse response, byte method) {
|
|
String protocol = request.getProtocol ();
|
|
Cookie[] cookies = request.getCookies();
|
|
|
|
// get app and path from original request path
|
|
String pathInfo = request.getPathInfo ();
|
|
String appID = getAppID (pathInfo);
|
|
RequestTrans reqtrans = new RequestTrans (method);
|
|
reqtrans.path = getRequestPath (pathInfo);
|
|
|
|
try {
|
|
|
|
if (cookies != null) {
|
|
for (int i=0; i < cookies.length;i++) try { // get Cookies
|
|
String nextKey = cookies[i].getName ();
|
|
String nextPart = cookies[i].getValue ();
|
|
if ("HopSession".equals (nextKey))
|
|
reqtrans.session = nextPart;
|
|
else
|
|
reqtrans.set (nextKey, nextPart);
|
|
} catch (Exception badCookie) {}
|
|
}
|
|
|
|
// check if we need to create a session id
|
|
if (reqtrans.session == null) {
|
|
reqtrans.session = Long.toString (Math.round (Math.random ()*Long.MAX_VALUE), 16);
|
|
reqtrans.session += "@"+Long.toString (System.currentTimeMillis (), 16);
|
|
Cookie c = new Cookie("HopSession", reqtrans.session);
|
|
c.setPath ("/");
|
|
if (cookieDomain != null)
|
|
c.setDomain (cookieDomain);
|
|
response.addCookie(c);
|
|
}
|
|
|
|
String host = request.getHeader ("Host");
|
|
if (host != null) {
|
|
host = host.toLowerCase();
|
|
reqtrans.set ("http_host", host);
|
|
}
|
|
|
|
String referer = request.getHeader ("Referer");
|
|
if (referer != null)
|
|
reqtrans.set ("http_referer", referer);
|
|
|
|
String remotehost = request.getRemoteAddr ();
|
|
if (remotehost != null)
|
|
reqtrans.set ("http_remotehost", remotehost);
|
|
|
|
String browser = request.getHeader ("User-Agent");
|
|
if (browser != null)
|
|
reqtrans.set ("http_browser", browser);
|
|
|
|
for (Enumeration e = request.getParameterNames(); e.hasMoreElements(); ) {
|
|
// Params parsen
|
|
String nextKey = (String)e.nextElement();
|
|
String[] paramValues = request.getParameterValues(nextKey);
|
|
if (paramValues != null) {
|
|
reqtrans.set (nextKey, paramValues[0]); // set to single string value
|
|
if (paramValues.length > 1)
|
|
reqtrans.set (nextKey+"_array", paramValues); // set string array
|
|
}
|
|
}
|
|
|
|
String contentType = request.getContentType();
|
|
if (contentType != null && contentType.indexOf("multipart/form-data")==0) {
|
|
// File Upload
|
|
Uploader up;
|
|
try {
|
|
if ((up = getUpload (request)) != null) {
|
|
Hashtable upload = up.getParts ();
|
|
for (Enumeration e = upload.keys(); e.hasMoreElements(); ) {
|
|
String nextKey = (String) e.nextElement ();
|
|
Object nextPart = upload.get (nextKey);
|
|
reqtrans.set (nextKey, nextPart);
|
|
}
|
|
}
|
|
} catch (Exception upx) {
|
|
String uploadErr = upx.getMessage ();
|
|
if (uploadErr == null || uploadErr.length () == 0)
|
|
uploadErr = upx.toString ();
|
|
reqtrans.set ("uploadError", uploadErr);
|
|
}
|
|
}
|
|
|
|
// get RMI ref to application and execute request
|
|
IRemoteApp app = getApp (appID);
|
|
ResponseTrans restrans = null;
|
|
try {
|
|
restrans = app.execute (reqtrans);
|
|
} catch (RemoteException cnx) {
|
|
invalidateApp (appID);
|
|
app = getApp (appID);
|
|
app.ping ();
|
|
restrans = app.execute (reqtrans);
|
|
}
|
|
writeResponse (response, restrans, cookies, protocol);
|
|
|
|
} catch (Exception x) {
|
|
invalidateApp (appID);
|
|
try {
|
|
response.setContentType ("text/html");
|
|
Writer out = response.getWriter ();
|
|
if (debug)
|
|
out.write ("<b>Error:</b><br>" +x);
|
|
else
|
|
out.write ("This server is temporarily unavailable. Please check back later.");
|
|
out.flush ();
|
|
} catch (Exception io_e) {}
|
|
}
|
|
}
|
|
|
|
|
|
private void writeResponse (HttpServletResponse res, ResponseTrans trans, Cookie[] cookies, String protocol) {
|
|
|
|
for (int i = 0; i < trans.countCookies(); i++) try {
|
|
Cookie c = new Cookie(trans.getKeyAt(i), trans.getValueAt(i));
|
|
c.setPath ("/");
|
|
if (cookieDomain != null)
|
|
c.setDomain (cookieDomain);
|
|
int expires = trans.getDaysAt(i);
|
|
if (expires > 0)
|
|
c.setMaxAge(expires * 60*60*24); // Cookie time to live, days -> seconds
|
|
res.addCookie(c);
|
|
} catch (Exception ign) {}
|
|
|
|
if (trans.getRedirect () != null) {
|
|
try {
|
|
res.sendRedirect(trans.getRedirect ());
|
|
} catch(Exception io_e) {}
|
|
|
|
} 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 (trans.status > 0)
|
|
res.setStatus (trans.status);
|
|
res.setContentLength (trans.getContentLength ());
|
|
res.setContentType (trans.contentType);
|
|
try {
|
|
OutputStream out = res.getOutputStream ();
|
|
out.write (trans.getContent ());
|
|
out.close ();
|
|
} catch(Exception io_e) {}
|
|
}
|
|
}
|
|
|
|
private void redirectResponse (HttpServletRequest request, HttpServletResponse res, ResponseTrans trans, String url) {
|
|
try {
|
|
res.sendRedirect(url);
|
|
} catch (Exception e) {
|
|
System.err.println ("Exception at redirect: " + e + e.getMessage());
|
|
}
|
|
}
|
|
|
|
|
|
public Uploader getUpload (HttpServletRequest request) throws Exception {
|
|
int contentLength = request.getContentLength ();
|
|
BufferedInputStream in = new BufferedInputStream (request.getInputStream ());
|
|
Uploader up = null;
|
|
try {
|
|
if (contentLength > uploadLimit*1024) {
|
|
// consume all input to make Apache happy
|
|
byte b[] = new byte[1024];
|
|
int read = 0;
|
|
while (read > -1)
|
|
read = in.read (b, 0, 1024);
|
|
throw new RuntimeException ("Upload exceeds limit of "+uploadLimit+" kb.");
|
|
}
|
|
String contentType = request.getContentType ();
|
|
up = new Uploader(uploadLimit);
|
|
up.load (in, contentType, contentLength);
|
|
} finally {
|
|
try { in.close (); } catch (Exception ignore) {}
|
|
}
|
|
return up;
|
|
}
|
|
|
|
|
|
public Object getUploadPart(Uploader up, String name) {
|
|
return up.getParts().get(name);
|
|
}
|
|
|
|
|
|
public String getServletInfo(){
|
|
return new String("Hop Servlet Client");
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|