Reworked much of the helma servlet code.
Parameter parsing is now done by the servlet itself since we know best about the encoding used by an application. AcmeServletClient is gone, the new EmbeddedServletClient is a subclass of AbstractServletClient, so no more duplicate code here.
This commit is contained in:
parent
14a6f0840e
commit
202575d801
8 changed files with 293 additions and 368 deletions
|
@ -108,11 +108,11 @@ public class ApplicationManager {
|
||||||
if (server.websrv == null) {
|
if (server.websrv == null) {
|
||||||
Naming.rebind ("//:"+port+"/"+appName, app);
|
Naming.rebind ("//:"+port+"/"+appName, app);
|
||||||
} else {
|
} else {
|
||||||
AcmeServletClient servlet = new AcmeServletClient (app);
|
boolean isRoot = "base".equalsIgnoreCase (appName);
|
||||||
if ("base".equalsIgnoreCase (appName))
|
EmbeddedServletClient servlet = new EmbeddedServletClient (appName, isRoot);
|
||||||
|
if (isRoot)
|
||||||
server.websrv.setDefaultServlet (servlet);
|
server.websrv.setDefaultServlet (servlet);
|
||||||
else {
|
else {
|
||||||
// server.websrv.addServlet ("/"+appName+"/", servlet);
|
|
||||||
server.websrv.addServlet ("/"+appName+"/*", servlet);
|
server.websrv.addServlet ("/"+appName+"/*", servlet);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -147,12 +147,15 @@ public class ApplicationManager {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get an enumeration of all currently running applications.
|
* Get an array containing all currently running applications.
|
||||||
*/
|
*/
|
||||||
public Object[] getApplications () {
|
public Object[] getApplications () {
|
||||||
return applications.values ().toArray ();
|
return applications.values ().toArray ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get an application by name.
|
||||||
|
*/
|
||||||
public Application getApplication(String name) {
|
public Application getApplication(String name) {
|
||||||
return (Application)applications.get(name);
|
return (Application)applications.get(name);
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,12 +22,21 @@ import helma.util.*;
|
||||||
|
|
||||||
public abstract class AbstractServletClient extends HttpServlet {
|
public abstract class AbstractServletClient extends HttpServlet {
|
||||||
|
|
||||||
|
// host on which Helma app is running
|
||||||
String host = null;
|
String host = null;
|
||||||
|
// port of Helma RMI server
|
||||||
int port = 0;
|
int port = 0;
|
||||||
int uploadLimit; // limit to HTTP uploads in kB
|
// limit to HTTP uploads in kB
|
||||||
|
int uploadLimit;
|
||||||
|
// RMI url of Helma app
|
||||||
String hopUrl;
|
String hopUrl;
|
||||||
|
// cookie domain to use
|
||||||
String cookieDomain;
|
String cookieDomain;
|
||||||
|
// default encoding for requests
|
||||||
|
String defaultEncoding;
|
||||||
|
// allow caching of responses
|
||||||
boolean caching;
|
boolean caching;
|
||||||
|
// enable debug output
|
||||||
boolean debug;
|
boolean debug;
|
||||||
|
|
||||||
static final byte HTTP_GET = 0;
|
static final byte HTTP_GET = 0;
|
||||||
|
@ -49,6 +58,8 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
|
|
||||||
hopUrl = "//" + host + ":" + port + "/";
|
hopUrl = "//" + host + ":" + port + "/";
|
||||||
|
|
||||||
|
defaultEncoding = init.getInitParameter ("charset");
|
||||||
|
|
||||||
debug = ("true".equalsIgnoreCase (init.getInitParameter ("debug")));
|
debug = ("true".equalsIgnoreCase (init.getInitParameter ("debug")));
|
||||||
|
|
||||||
caching = ! ("false".equalsIgnoreCase (init.getInitParameter ("caching")));
|
caching = ! ("false".equalsIgnoreCase (init.getInitParameter ("caching")));
|
||||||
|
@ -88,13 +99,15 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
try {
|
try {
|
||||||
|
|
||||||
// read and set http parameters
|
// read and set http parameters
|
||||||
for (Enumeration e = request.getParameterNames(); e.hasMoreElements(); ) {
|
Map parameters = parseParameters (request);
|
||||||
String nextKey = (String)e.nextElement();
|
for (Iterator i=parameters.entrySet().iterator(); i.hasNext(); ) {
|
||||||
String[] paramValues = request.getParameterValues(nextKey);
|
Map.Entry entry = (Map.Entry) i.next ();
|
||||||
if (paramValues != null) {
|
String key = (String) entry.getKey ();
|
||||||
reqtrans.set (nextKey, paramValues[0]); // set to single string value
|
String[] values = (String[]) entry.getValue ();
|
||||||
if (paramValues.length > 1)
|
if (values != null && values.length > 0) {
|
||||||
reqtrans.set (nextKey+"_array", paramValues); // set string array
|
reqtrans.set (key, values[0]); // set to single string value
|
||||||
|
if (values.length > 1)
|
||||||
|
reqtrans.set (key+"_array", values); // set string array
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,13 +115,13 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
String contentType = request.getContentType();
|
String contentType = request.getContentType();
|
||||||
if (contentType != null && contentType.indexOf("multipart/form-data")==0) {
|
if (contentType != null && contentType.indexOf("multipart/form-data")==0) {
|
||||||
// File Upload
|
// File Upload
|
||||||
Uploader up;
|
|
||||||
try {
|
try {
|
||||||
if ((up = getUpload (request)) != null) {
|
FileUpload upload = getUpload (request);
|
||||||
Hashtable upload = up.getParts ();
|
if (upload != null) {
|
||||||
for (Enumeration e = upload.keys(); e.hasMoreElements(); ) {
|
Hashtable parts = upload.getParts ();
|
||||||
|
for (Enumeration e = parts.keys(); e.hasMoreElements(); ) {
|
||||||
String nextKey = (String) e.nextElement ();
|
String nextKey = (String) e.nextElement ();
|
||||||
Object nextPart = upload.get (nextKey);
|
Object nextPart = parts.get (nextKey);
|
||||||
reqtrans.set (nextKey, nextPart);
|
reqtrans.set (nextKey, nextPart);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -226,6 +239,13 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
res.setHeader( "WWW-Authenticate", "Basic realm=\"" + trans.realm + "\"" );
|
res.setHeader( "WWW-Authenticate", "Basic realm=\"" + trans.realm + "\"" );
|
||||||
if (trans.status > 0)
|
if (trans.status > 0)
|
||||||
res.setStatus (trans.status);
|
res.setStatus (trans.status);
|
||||||
|
// if we don't know which charset to use for parsing HTTP params,
|
||||||
|
// take the one from the response. This usually works because
|
||||||
|
// browsers send parrameters in the same encoding as the page
|
||||||
|
// containing the form has. Problem is we can do this only per servlet,
|
||||||
|
// not per session or even per page, which would produce too much overhead
|
||||||
|
if (defaultEncoding == null)
|
||||||
|
defaultEncoding = trans.charset;
|
||||||
res.setContentLength (trans.getContentLength ());
|
res.setContentLength (trans.getContentLength ());
|
||||||
res.setContentType (trans.getContentType ());
|
res.setContentType (trans.getContentType ());
|
||||||
try {
|
try {
|
||||||
|
@ -245,10 +265,10 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Uploader getUpload (HttpServletRequest request) throws Exception {
|
public FileUpload getUpload (HttpServletRequest request) throws Exception {
|
||||||
int contentLength = request.getContentLength ();
|
int contentLength = request.getContentLength ();
|
||||||
BufferedInputStream in = new BufferedInputStream (request.getInputStream ());
|
BufferedInputStream in = new BufferedInputStream (request.getInputStream ());
|
||||||
Uploader up = null;
|
FileUpload upload = null;
|
||||||
try {
|
try {
|
||||||
if (contentLength > uploadLimit*1024) {
|
if (contentLength > uploadLimit*1024) {
|
||||||
// consume all input to make Apache happy
|
// consume all input to make Apache happy
|
||||||
|
@ -259,42 +279,165 @@ public abstract class AbstractServletClient extends HttpServlet {
|
||||||
throw new RuntimeException ("Upload exceeds limit of "+uploadLimit+" kb.");
|
throw new RuntimeException ("Upload exceeds limit of "+uploadLimit+" kb.");
|
||||||
}
|
}
|
||||||
String contentType = request.getContentType ();
|
String contentType = request.getContentType ();
|
||||||
up = new Uploader(uploadLimit);
|
upload = new FileUpload(uploadLimit);
|
||||||
up.load (in, contentType, contentLength);
|
upload.load (in, contentType, contentLength);
|
||||||
} finally {
|
} finally {
|
||||||
try { in.close (); } catch (Exception ignore) {}
|
try {
|
||||||
|
in.close ();
|
||||||
|
} catch (Exception ignore) {}
|
||||||
}
|
}
|
||||||
return up;
|
return upload;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
public Object getUploadPart(Uploader up, String name) {
|
public Object getUploadPart(FileUpload upload, String name) {
|
||||||
return up.getParts().get(name);
|
return upload.getParts().get(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Put name value pair in map.
|
||||||
|
*
|
||||||
|
* @param b the character value byte
|
||||||
|
*
|
||||||
|
* Put name and value pair in map. When name already exist, add value
|
||||||
|
* to array of values.
|
||||||
|
*/
|
||||||
|
private static void putMapEntry( Map map, String name, String value) {
|
||||||
|
String[] newValues = null;
|
||||||
|
String[] oldValues = (String[]) map.get(name);
|
||||||
|
if (oldValues == null) {
|
||||||
|
newValues = new String[1];
|
||||||
|
newValues[0] = value;
|
||||||
|
} else {
|
||||||
|
newValues = new String[oldValues.length + 1];
|
||||||
|
System.arraycopy(oldValues, 0, newValues, 0, oldValues.length);
|
||||||
|
newValues[oldValues.length] = value;
|
||||||
|
}
|
||||||
|
map.put(name, newValues);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
protected Map parseParameters (HttpServletRequest request) {
|
||||||
|
|
||||||
|
String encoding = request.getCharacterEncoding ();
|
||||||
|
if (encoding == null)
|
||||||
|
// no encoding from request, use standard one
|
||||||
|
encoding = defaultEncoding;
|
||||||
|
if (encoding == null)
|
||||||
|
encoding = "ISO-8859-1";
|
||||||
|
|
||||||
|
HashMap parameters = new HashMap ();
|
||||||
|
// Parse any query string parameters from the request
|
||||||
|
try {
|
||||||
|
parseParameters (parameters, request.getQueryString().getBytes(), encoding);
|
||||||
|
} catch (Exception e) {
|
||||||
|
}
|
||||||
|
|
||||||
|
// Parse any posted parameters in the input stream
|
||||||
|
if ("POST".equals(request.getMethod()) &&
|
||||||
|
"application/x-www-form-urlencoded".equals(request.getContentType())) {
|
||||||
|
try {
|
||||||
|
int max = request.getContentLength();
|
||||||
|
int len = 0;
|
||||||
|
byte buf[] = new byte[max];
|
||||||
|
ServletInputStream is = request.getInputStream();
|
||||||
|
while (len < max) {
|
||||||
|
int next = is.read(buf, len, max - len);
|
||||||
|
if (next < 0 ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
len += next;
|
||||||
|
}
|
||||||
|
// is.close();
|
||||||
|
parseParameters(parameters, buf, encoding);
|
||||||
|
} catch (IllegalArgumentException e) {
|
||||||
|
} catch (IOException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return parameters;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append request parameters from the specified String to the specified
|
||||||
|
* Map. It is presumed that the specified Map is not accessed from any
|
||||||
|
* other thread, so no synchronization is performed.
|
||||||
|
* <p>
|
||||||
|
* <strong>IMPLEMENTATION NOTE</strong>: URL decoding is performed
|
||||||
|
* individually on the parsed name and value elements, rather than on
|
||||||
|
* the entire query string ahead of time, to properly deal with the case
|
||||||
|
* where the name or value includes an encoded "=" or "&" character
|
||||||
|
* that would otherwise be interpreted as a delimiter.
|
||||||
|
*
|
||||||
|
* NOTE: byte array data is modified by this method. Caller beware.
|
||||||
|
*
|
||||||
|
* @param map Map that accumulates the resulting parameters
|
||||||
|
* @param data Input string containing request parameters
|
||||||
|
* @param encoding Encoding to use for converting hex
|
||||||
|
*
|
||||||
|
* @exception UnsupportedEncodingException if the data is malformed
|
||||||
|
*/
|
||||||
|
public static void parseParameters (Map map, byte[] data, String encoding)
|
||||||
|
throws UnsupportedEncodingException {
|
||||||
|
|
||||||
|
if (data != null && data.length > 0) {
|
||||||
|
int pos = 0;
|
||||||
|
int ix = 0;
|
||||||
|
int ox = 0;
|
||||||
|
String key = null;
|
||||||
|
String value = null;
|
||||||
|
while (ix < data.length) {
|
||||||
|
byte c = data[ix++];
|
||||||
|
switch ((char) c) {
|
||||||
|
case '&':
|
||||||
|
value = new String(data, 0, ox, encoding);
|
||||||
|
if (key != null) {
|
||||||
|
putMapEntry(map, key, value);
|
||||||
|
key = null;
|
||||||
|
}
|
||||||
|
ox = 0;
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
key = new String(data, 0, ox, encoding);
|
||||||
|
ox = 0;
|
||||||
|
break;
|
||||||
|
case '+':
|
||||||
|
data[ox++] = (byte)' ';
|
||||||
|
break;
|
||||||
|
case '%':
|
||||||
|
data[ox++] = (byte)((convertHexDigit(data[ix++]) << 4)
|
||||||
|
+ convertHexDigit(data[ix++]));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
data[ox++] = c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
//The last value does not end in '&'. So save it now.
|
||||||
|
if (key != null) {
|
||||||
|
value = new String(data, 0, ox, encoding);
|
||||||
|
putMapEntry(map, key, value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Convert a byte character value to hexidecimal digit value.
|
||||||
|
*
|
||||||
|
* @param b the character value byte
|
||||||
|
*/
|
||||||
|
private static byte convertHexDigit( byte b ) {
|
||||||
|
if ((b >= '0') && (b <= '9')) return (byte)(b - '0');
|
||||||
|
if ((b >= 'a') && (b <= 'f')) return (byte)(b - 'a' + 10);
|
||||||
|
if ((b >= 'A') && (b <= 'F')) return (byte)(b - 'A' + 10);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
public String getServletInfo(){
|
public String getServletInfo(){
|
||||||
return new String("Hop Servlet Client");
|
return new String("Helma Servlet Client");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,271 +0,0 @@
|
||||||
// AcmeServletClient.java
|
|
||||||
// Copyright (c) Hannes Wallnoefer, 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.util.*;
|
|
||||||
import helma.framework.*;
|
|
||||||
import helma.framework.core.Application;
|
|
||||||
import helma.util.Uploader;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* This is the Hop servlet adapter that uses the Acme servlet API clone and communicates
|
|
||||||
* directly with hop applications instead of using RMI.
|
|
||||||
*/
|
|
||||||
|
|
||||||
public class AcmeServletClient extends HttpServlet {
|
|
||||||
|
|
||||||
private int uploadLimit; // limit to HTTP uploads in kB
|
|
||||||
private Hashtable apps;
|
|
||||||
private Application app;
|
|
||||||
private String cookieDomain;
|
|
||||||
private boolean debug;
|
|
||||||
|
|
||||||
static final byte HTTP_GET = 0;
|
|
||||||
static final byte HTTP_POST = 1;
|
|
||||||
|
|
||||||
public AcmeServletClient (Application app) {
|
|
||||||
this.app = app;
|
|
||||||
this.uploadLimit = 1024; // generous 1mb upload limit
|
|
||||||
}
|
|
||||||
|
|
||||||
public void init (ServletConfig config) throws ServletException {
|
|
||||||
super.init (config);
|
|
||||||
// do nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void execute (HttpServletRequest request, HttpServletResponse response, byte method) {
|
|
||||||
String protocol = request.getProtocol ();
|
|
||||||
Cookie[] cookies = request.getCookies();
|
|
||||||
try {
|
|
||||||
RequestTrans reqtrans = new RequestTrans (method);
|
|
||||||
|
|
||||||
// read and set http parameters
|
|
||||||
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
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// check for MIME file uploads
|
|
||||||
String contentType = request.getContentType();
|
|
||||||
if (contentType != null && contentType.indexOf("multipart/form-data")==0) {
|
|
||||||
// File Upload
|
|
||||||
Uploader up;
|
|
||||||
try {
|
|
||||||
if ((up = getUpload (uploadLimit, 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// HACK - sessions not fully supported in Acme.Serve
|
|
||||||
// Thats ok, we dont need the session object, just the id.
|
|
||||||
reqtrans.session = request.getRequestedSessionId();
|
|
||||||
|
|
||||||
// get Cookies
|
|
||||||
if (cookies != null) {
|
|
||||||
for (int i=0; i < cookies.length;i++) try {
|
|
||||||
String nextKey = cookies[i].getName ();
|
|
||||||
String nextPart = cookies[i].getValue ();
|
|
||||||
reqtrans.set (nextKey, nextPart);
|
|
||||||
} catch (Exception badCookie) {}
|
|
||||||
}
|
|
||||||
|
|
||||||
// get optional path info
|
|
||||||
String pathInfo = request.getServletPath ();
|
|
||||||
if (pathInfo != null) {
|
|
||||||
if (pathInfo.indexOf (app.getName()) == 1)
|
|
||||||
pathInfo = pathInfo.substring (app.getName().length()+1);
|
|
||||||
reqtrans.path = trim (pathInfo);
|
|
||||||
} else
|
|
||||||
reqtrans.path = "";
|
|
||||||
|
|
||||||
// do standard HTTP variables
|
|
||||||
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);
|
|
||||||
|
|
||||||
String authorization = request.getHeader("authorization");
|
|
||||||
if ( authorization != null )
|
|
||||||
reqtrans.set ("authorization", authorization );
|
|
||||||
|
|
||||||
ResponseTrans restrans = null;
|
|
||||||
restrans = app.execute (reqtrans);
|
|
||||||
writeResponse (response, restrans, cookies, protocol);
|
|
||||||
|
|
||||||
} catch (Exception x) {
|
|
||||||
x.printStackTrace ();
|
|
||||||
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) {
|
|
||||||
// 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.realm!=null )
|
|
||||||
res.setHeader( "WWW-Authenticate", "Basic realm=\"" + trans.realm + "\"" );
|
|
||||||
if (trans.status > 0)
|
|
||||||
res.setStatus (trans.status);
|
|
||||||
res.setContentLength (trans.getContentLength ());
|
|
||||||
res.setContentType (trans.getContentType ());
|
|
||||||
try {
|
|
||||||
OutputStream out = res.getOutputStream ();
|
|
||||||
out.write (trans.getContent ());
|
|
||||||
out.close ();
|
|
||||||
} catch(Exception io_e) { System.out.println ("Error in writeResponse: "+io_e); }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void redirectResponse (HttpServletRequest request, HttpServletResponse res, ResponseTrans trans, String url) {
|
|
||||||
try {
|
|
||||||
res.sendRedirect(url);
|
|
||||||
} catch (Exception e) {
|
|
||||||
System.err.println ("Exception in redirect: " + e + e.getMessage());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Uploader getUpload (HttpServletRequest request) throws Exception {
|
|
||||||
return getUpload (500, request);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Uploader getUpload (int maxKbytes, HttpServletRequest request) throws Exception {
|
|
||||||
int contentLength = request.getContentLength ();
|
|
||||||
BufferedInputStream in = new BufferedInputStream (request.getInputStream ());
|
|
||||||
Uploader up = null;
|
|
||||||
if (contentLength > maxKbytes*1024) {
|
|
||||||
throw new RuntimeException ("Upload exceeds limit of "+maxKbytes+" kb.");
|
|
||||||
}
|
|
||||||
String contentType = request.getContentType ();
|
|
||||||
up = new Uploader(maxKbytes);
|
|
||||||
up.load (in, contentType, contentLength);
|
|
||||||
return up;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public Object getUploadPart(Uploader up, String name) {
|
|
||||||
return up.getParts().get(name);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
public String getServletInfo (){
|
|
||||||
return new String("Hop ServletClient");
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
private String trim (String str) {
|
|
||||||
|
|
||||||
if (str == null)
|
|
||||||
return null;
|
|
||||||
char[] val = str.toCharArray ();
|
|
||||||
int len = val.length;
|
|
||||||
int st = 0;
|
|
||||||
|
|
||||||
while ((st < len) && (val[st] <= ' ' || val[st] == '/')) {
|
|
||||||
st++;
|
|
||||||
}
|
|
||||||
while ((st < len) && (val[len - 1] <= ' ' || val[len - 1] == '/')) {
|
|
||||||
len--;
|
|
||||||
}
|
|
||||||
return ((st > 0) || (len < val.length)) ? new String (val, st, len-st) : str;
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
78
src/helma/servlet/EmbeddedServletClient.java
Normal file
78
src/helma/servlet/EmbeddedServletClient.java
Normal file
|
@ -0,0 +1,78 @@
|
||||||
|
// EmbeddedServletClient.java
|
||||||
|
// Copyright (c) Hannes Wallnöfer, 2002
|
||||||
|
|
||||||
|
package helma.servlet;
|
||||||
|
|
||||||
|
import javax.servlet.*;
|
||||||
|
import java.io.*;
|
||||||
|
import java.util.*;
|
||||||
|
import helma.framework.*;
|
||||||
|
import helma.framework.core.Application;
|
||||||
|
import helma.main.*;
|
||||||
|
import helma.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Servlet client that runs a Helma application for the embedded
|
||||||
|
* web server
|
||||||
|
*/
|
||||||
|
|
||||||
|
public final class EmbeddedServletClient extends AbstractServletClient {
|
||||||
|
|
||||||
|
private Application app = null;
|
||||||
|
private String appName;
|
||||||
|
|
||||||
|
// tells us whether the application is mounted as root or by its name
|
||||||
|
// depending on this we know whether we have to transform the request path
|
||||||
|
boolean root;
|
||||||
|
|
||||||
|
public EmbeddedServletClient (String appName, boolean isRoot) {
|
||||||
|
this.appName = appName;
|
||||||
|
this.root = isRoot;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
IRemoteApp getApp (String appID) {
|
||||||
|
if (app == null)
|
||||||
|
app = Server.getServer().getApplication (appName);
|
||||||
|
return app;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void invalidateApp (String appID) {
|
||||||
|
// do nothing
|
||||||
|
}
|
||||||
|
|
||||||
|
String getAppID (String path) {
|
||||||
|
return appName;
|
||||||
|
}
|
||||||
|
|
||||||
|
String getRequestPath (String path) {
|
||||||
|
if (path == null)
|
||||||
|
return "";
|
||||||
|
if (root)
|
||||||
|
return trim (path);
|
||||||
|
int appInPath = path.indexOf (appName);
|
||||||
|
if (appInPath > 0)
|
||||||
|
return trim (path.substring (appInPath+appName.length()));
|
||||||
|
else
|
||||||
|
return trim (path);
|
||||||
|
}
|
||||||
|
|
||||||
|
String trim (String str) {
|
||||||
|
char[] val = str.toCharArray ();
|
||||||
|
int len = val.length;
|
||||||
|
int st = 0;
|
||||||
|
|
||||||
|
while ((st < len) && (val[st] <= ' ' || val[st] == '/'))
|
||||||
|
st++;
|
||||||
|
|
||||||
|
while ((st < len) && (val[len - 1] <= ' ' || val[len - 1] == '/'))
|
||||||
|
len--;
|
||||||
|
|
||||||
|
return ((st > 0) || (len < val.length)) ? new String (val, st, len-st) : str;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -70,17 +70,17 @@ public class MultiServletClient extends AbstractServletClient {
|
||||||
int len = val.length;
|
int len = val.length;
|
||||||
int st = 0;
|
int st = 0;
|
||||||
|
|
||||||
// advance to start of path
|
// advance to start of path, eating up any slashes
|
||||||
while ((st < len) && (val[st] <= ' ' || val[st] == '/'))
|
while ((st < len) && (val[st] <= ' ' || val[st] == '/'))
|
||||||
st++;
|
st++;
|
||||||
|
|
||||||
// eat characters of first path element
|
// advance until slash ending the first path element
|
||||||
while (st < len && val[st] != '/')
|
while (st < len && val[st] != '/')
|
||||||
st++;
|
st++;
|
||||||
if (st < len && val[st] == '/')
|
if (st < len && val[st] == '/')
|
||||||
st++;
|
st++;
|
||||||
|
|
||||||
// eat away noise at end of path
|
// eat away spaces and slashes at end of path
|
||||||
while ((st < len) && (val[len - 1] <= ' ' || val[len - 1] == '/'))
|
while ((st < len) && (val[len - 1] <= ' ' || val[len - 1] == '/'))
|
||||||
len--;
|
len--;
|
||||||
|
|
||||||
|
|
|
@ -1,44 +1,36 @@
|
||||||
// ServletClient.java
|
// ServletClient.java
|
||||||
// Copyright (c) Hannes Wallnöfer, Raphael Spannocchi 1998-2000
|
// Copyright (c) Hannes Wallnöfer, Raphael Spannocchi 1998-2002
|
||||||
|
|
||||||
/* Portierung von helma.asp.AspClient auf Servlets */
|
|
||||||
/* Author: Raphael Spannocchi Datum: 27.11.1998 */
|
|
||||||
|
|
||||||
package helma.servlet;
|
package helma.servlet;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
import javax.servlet.http.*;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.rmi.Naming;
|
import java.rmi.Naming;
|
||||||
import java.rmi.RemoteException;
|
import java.rmi.RemoteException;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.util.*;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the HOP servlet adapter. This class communicates with just
|
* This is the standard Helma servlet adapter. This class represents a servlet
|
||||||
* one Hop application.
|
* that is dedicated to one Helma application over RMI.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class ServletClient extends AbstractServletClient {
|
public class ServletClient extends AbstractServletClient {
|
||||||
|
|
||||||
private IRemoteApp app = null;
|
private IRemoteApp app = null;
|
||||||
private String appName;
|
private String appName = null;
|
||||||
|
|
||||||
public void init (ServletConfig init) throws ServletException {
|
public void init (ServletConfig init) throws ServletException {
|
||||||
super.init (init);
|
super.init (init);
|
||||||
|
|
||||||
appName = init.getInitParameter ("application");
|
appName = init.getInitParameter ("application");
|
||||||
if (appName == null)
|
|
||||||
appName = "base";
|
|
||||||
|
|
||||||
super.init (init);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
IRemoteApp getApp (String appID) throws Exception {
|
IRemoteApp getApp (String appID) throws Exception {
|
||||||
if (app != null)
|
if (app != null)
|
||||||
return app;
|
return app;
|
||||||
|
if (appName == null)
|
||||||
|
throw new ServletException ("Helma application name not specified for helma.servlet.ServletClient");
|
||||||
app = (IRemoteApp) Naming.lookup (hopUrl + appName);
|
app = (IRemoteApp) Naming.lookup (hopUrl + appName);
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
@ -76,7 +68,7 @@ public class ServletClient extends AbstractServletClient {
|
||||||
// for testing
|
// for testing
|
||||||
public static void main (String args[]) {
|
public static void main (String args[]) {
|
||||||
AbstractServletClient client = new ServletClient ();
|
AbstractServletClient client = new ServletClient ();
|
||||||
String path = "///appname/do/it/for/me///";
|
String path = "///appname/some/random/path///";
|
||||||
System.out.println (client.getAppID (path));
|
System.out.println (client.getAppID (path));
|
||||||
System.out.println (client.getRequestPath (path));
|
System.out.println (client.getRequestPath (path));
|
||||||
}
|
}
|
||||||
|
@ -85,20 +77,3 @@ public class ServletClient extends AbstractServletClient {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -4,16 +4,15 @@
|
||||||
package helma.servlet;
|
package helma.servlet;
|
||||||
|
|
||||||
import javax.servlet.*;
|
import javax.servlet.*;
|
||||||
import javax.servlet.http.*;
|
|
||||||
import java.io.*;
|
import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import helma.framework.*;
|
import helma.framework.*;
|
||||||
import helma.framework.core.Application;
|
import helma.framework.core.Application;
|
||||||
import helma.objectmodel.*;
|
|
||||||
import helma.util.*;
|
import helma.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is a standalone Hop servlet client, running a Hop application by itself.
|
* Standalone servlet client that runs a Helma application all by itself
|
||||||
|
* in embedded mode without relying on helma.main.Server.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public final class StandaloneServletClient extends AbstractServletClient {
|
public final class StandaloneServletClient extends AbstractServletClient {
|
||||||
|
@ -105,13 +104,11 @@ public final class StandaloneServletClient extends AbstractServletClient {
|
||||||
// for testing
|
// for testing
|
||||||
public static void main (String args[]) {
|
public static void main (String args[]) {
|
||||||
AbstractServletClient client = new ServletClient ();
|
AbstractServletClient client = new ServletClient ();
|
||||||
String path = "///appname/do/it/for/me///";
|
String path = "///appname/some/random/path///";
|
||||||
System.out.println (client.getAppID (path));
|
System.out.println (client.getAppID (path));
|
||||||
System.out.println (client.getRequestPath (path));
|
System.out.println (client.getRequestPath (path));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
// Uploader.java
|
// FileUpload.java
|
||||||
// Copyright (c) Hannes Wallnöfer 1996-2000
|
// Copyright (c) Hannes Wallnöfer 1996-2000
|
||||||
|
|
||||||
package helma.util;
|
package helma.util;
|
||||||
|
@ -8,19 +8,19 @@ import java.io.*;
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Utility class for file uploads via HTTP POST.
|
* Utility class for MIME file uploads via HTTP POST.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
public class Uploader {
|
public class FileUpload {
|
||||||
|
|
||||||
public Hashtable parts;
|
public Hashtable parts;
|
||||||
int maxKbytes;
|
int maxKbytes;
|
||||||
|
|
||||||
public Uploader () {
|
public FileUpload () {
|
||||||
maxKbytes = 500;
|
maxKbytes = 1024;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Uploader (int max) {
|
public FileUpload (int max) {
|
||||||
maxKbytes = max;
|
maxKbytes = max;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue