Compare commits
46 commits
main
...
renovate/m
Author | SHA1 | Date | |
---|---|---|---|
745ce5bfca | |||
0cf9cf7af2 | |||
6723df912e | |||
436862e87a | |||
36a12effb2 | |||
2994a4becc | |||
99e8b204fd | |||
c42c0a7a17 | |||
b7543cf615 | |||
fc084f6e52 | |||
6fc73d2320 | |||
9b5cc988dd | |||
04b210b464 | |||
4c011f1e1b | |||
bc7894ecc1 | |||
a3fbf72f38 | |||
de2150693f | |||
cd8baa4ac1 | |||
11b226b272 | |||
1925916220 | |||
b1296fb093 | |||
51bc14c3a4 | |||
3e5af064b0 | |||
6401300189 | |||
45b19e3217 | |||
ffb259a01c | |||
84abcde037 | |||
9e870e6cd3 | |||
1e32c8eb89 | |||
9143faf35e | |||
79d83389f2 | |||
90e45c9115 | |||
3dbcd792a6 | |||
973b3493cb | |||
441d952b35 | |||
d67d0235bd | |||
fa59a27858 | |||
304ea4e456 | |||
0165e7c80e | |||
62630ae068 | |||
26975a109a | |||
a943124d45 | |||
c087cb731e | |||
c5f68013b1 | |||
ed575bc4c5 | |||
|
1cf738767c |
16 changed files with 99 additions and 76 deletions
22
.gitignore
vendored
22
.gitignore
vendored
|
@ -1,7 +1,5 @@
|
|||
# Generally ignore hidden files
|
||||
.*
|
||||
|
||||
# Manage some Codium configuration
|
||||
.vscode/*
|
||||
!.vscode
|
||||
!.vscode/extensions.json
|
||||
|
@ -9,22 +7,22 @@
|
|||
!.vscode/settings.json
|
||||
!.vscode/tasks.json
|
||||
|
||||
# Ignore files created during build or run
|
||||
build
|
||||
|
||||
/apps
|
||||
/bin
|
||||
/backups
|
||||
build
|
||||
/db
|
||||
/docs
|
||||
/extras
|
||||
/lib
|
||||
/licenses
|
||||
/log
|
||||
|
||||
# Ignore files managed in src/dist
|
||||
/*.properties
|
||||
/apps
|
||||
/db
|
||||
/extras
|
||||
/launcher.jar
|
||||
/static
|
||||
|
||||
# Manage Gradle configuration
|
||||
/*.properties
|
||||
!/gradle.properties
|
||||
|
||||
/launcher.jar
|
||||
/passwd
|
||||
/start.*
|
||||
|
|
|
@ -1 +1 @@
|
|||
11.0
|
||||
17
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
|
||||
## TL;DR
|
||||
|
||||
- Make sure you have Java 11 or higher installed
|
||||
- Make sure you have Java 17 or higher installed
|
||||
- Download and unpack the [latest release](https://code.host.antville.org/antville/helma/releases)
|
||||
- Invoke `./bin/helma`, resp. `./bin/helma.bat`, depending on your platform
|
||||
- Direct your web browser to <http://localhost:8080>
|
||||
|
|
13
build.gradle
13
build.gradle
|
@ -18,8 +18,8 @@ allprojects {
|
|||
apply plugin: 'java'
|
||||
|
||||
java {
|
||||
sourceCompatibility = JavaVersion.VERSION_11
|
||||
targetCompatibility = JavaVersion.VERSION_11
|
||||
sourceCompatibility = JavaVersion.VERSION_17
|
||||
targetCompatibility = JavaVersion.VERSION_17
|
||||
}
|
||||
|
||||
repositories {
|
||||
|
@ -51,14 +51,15 @@ configurations {
|
|||
dependencies {
|
||||
implementation 'com.google.code.gson:gson:2.12.1'
|
||||
implementation 'commons-codec:commons-codec:1.18.0'
|
||||
implementation 'commons-fileupload:commons-fileupload:1.5'
|
||||
implementation 'org.apache.commons:commons-fileupload2-core:2.0.0-M2'
|
||||
implementation 'org.apache.commons:commons-fileupload2-jakarta:2.0.0-M1'
|
||||
implementation 'commons-logging:commons-logging:1.3.5'
|
||||
implementation 'commons-net:commons-net:3.11.1'
|
||||
implementation 'com.sun.mail:javax.mail:1.6.2'
|
||||
implementation 'javax.servlet:javax.servlet-api:4.0.1'
|
||||
implementation 'jakarta.servlet:jakarta.servlet-api:5.0.0'
|
||||
implementation 'org.ccil.cowan.tagsoup:tagsoup:1.2.1'
|
||||
implementation 'org.eclipse.jetty:jetty-servlet:9.4.57.v20241219'
|
||||
implementation 'org.eclipse.jetty:jetty-xml:9.4.57.v20241219'
|
||||
implementation 'org.eclipse.jetty.ee9:jetty-ee9-servlet:12.0.19'
|
||||
implementation 'org.eclipse.jetty:jetty-xml:12.0.19'
|
||||
implementation 'org.mozilla:rhino-all:1.8.0'
|
||||
implementation 'org.sejda.imageio:webp-imageio:0.1.6'
|
||||
implementation 'xerces:xercesImpl:2.12.2'
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
package helma.framework;
|
||||
|
||||
import java.io.Serializable;
|
||||
import javax.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
|
||||
/**
|
||||
* Cookie Transmitter. A simple, serializable representation
|
||||
|
|
|
@ -16,12 +16,12 @@
|
|||
|
||||
package helma.framework;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import java.io.Serializable;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
*
|
||||
*/
|
||||
public class RequestBean implements Serializable {
|
||||
private static final long serialVersionUID = -6826881712426326687L;
|
||||
|
@ -89,7 +89,7 @@ public class RequestBean implements Serializable {
|
|||
* @return the header value, or null
|
||||
*/
|
||||
public String getHeader(String name) {
|
||||
return req.getHeader(name);
|
||||
return req.getHeader(name);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -19,9 +19,9 @@ package helma.framework;
|
|||
import helma.util.SystemMap;
|
||||
import helma.util.StringUtils;
|
||||
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.servlet.http.Cookie;
|
||||
import jakarta.servlet.http.HttpServletRequest;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.Cookie;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
|
||||
|
|
|
@ -19,7 +19,7 @@ package helma.framework;
|
|||
import helma.objectmodel.db.Transactor;
|
||||
import helma.scripting.ScriptingException;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.Serializable;
|
||||
import java.io.StringWriter;
|
||||
import java.io.PrintWriter;
|
||||
|
|
|
@ -21,7 +21,7 @@ import helma.framework.core.Application;
|
|||
import helma.util.*;
|
||||
import helma.scripting.ScriptingException;
|
||||
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import jakarta.servlet.http.HttpServletResponse;
|
||||
import java.io.*;
|
||||
import java.security.*;
|
||||
import java.util.*;
|
||||
|
|
|
@ -19,11 +19,13 @@ import java.util.Vector;
|
|||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.xmlrpc.XmlRpcHandler;
|
||||
|
||||
import org.eclipse.jetty.server.handler.ContextHandler;
|
||||
import org.eclipse.jetty.server.handler.ContextHandlerCollection;
|
||||
import org.eclipse.jetty.server.handler.ResourceHandler;
|
||||
import org.eclipse.jetty.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletContextHandler;
|
||||
import org.eclipse.jetty.ee9.servlet.ServletHolder;
|
||||
import org.eclipse.jetty.util.resource.ResourceFactory;
|
||||
|
||||
import helma.framework.core.Application;
|
||||
import helma.framework.repository.FileRepository;
|
||||
|
@ -481,23 +483,29 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
|
||||
// if there is a static direcory specified, mount it
|
||||
if (this.staticDir != null) {
|
||||
String staticPath = getAbsoluteFile(this.staticDir).getCanonicalPath();
|
||||
|
||||
File staticContent = getAbsoluteFile(this.staticDir);
|
||||
|
||||
getLogger().info("Serving static from " + staticContent.getPath());
|
||||
getLogger().info("Serving static from " + staticPath);
|
||||
getLogger().info("Mounting static at " + staticMountpoint);
|
||||
|
||||
ResourceHandler rhandler = new ResourceHandler();
|
||||
rhandler.setResourceBase(staticContent.getPath());
|
||||
rhandler.setBaseResource(ResourceFactory.of(rhandler).newResource(staticPath));
|
||||
rhandler.setWelcomeFiles(staticHome);
|
||||
|
||||
staticContext = ApplicationManager.this.context.addContext(staticMountpoint, ""); //$NON-NLS-1$
|
||||
ContextHandler staticContext = new ContextHandler();
|
||||
staticContext.setContextPath(staticMountpoint);
|
||||
staticContext.setHandler(rhandler);
|
||||
|
||||
ApplicationManager.this.context.addHandler(staticContext);
|
||||
staticContext.start();
|
||||
}
|
||||
|
||||
appContext = new ServletContextHandler(context, pathPattern, true, true);
|
||||
// I hope I am correct assuming Helma does not need Jetty’s session management, but using
|
||||
// `ServletContextHandler.SESSIONS` causes an exception: Shared scheduler not started
|
||||
appContext = new ServletContextHandler(ServletContextHandler.NO_SESSIONS);
|
||||
appContext.setContextPath(pathPattern);
|
||||
context.addHandler(appContext);
|
||||
|
||||
Class servletClass = servletClassName == null ?
|
||||
EmbeddedServletClient.class : Class.forName(servletClassName);
|
||||
ServletHolder holder = new ServletHolder(servletClass);
|
||||
|
@ -529,10 +537,9 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
}
|
||||
|
||||
if (protectedStaticDir != null) {
|
||||
File protectedContent = getAbsoluteFile(protectedStaticDir);
|
||||
appContext.setResourceBase(protectedContent.getPath());
|
||||
getLogger().info("Serving protected static from " +
|
||||
protectedContent.getPath());
|
||||
String protectedContent = getAbsoluteFile(protectedStaticDir).getCanonicalPath();
|
||||
appContext.setBaseResourceAsString(protectedContent);
|
||||
getLogger().info("Serving protected static from " + protectedContent);
|
||||
}
|
||||
|
||||
// Remap the context paths and start
|
||||
|
@ -556,7 +563,9 @@ public class ApplicationManager implements XmlRpcHandler {
|
|||
// unbind from Jetty HTTP server
|
||||
if (ApplicationManager.this.jetty != null) {
|
||||
if (this.appContext != null) {
|
||||
ApplicationManager.this.context.removeHandler(this.appContext);
|
||||
// Adding appContext to the ContextHandlerCollection works (see above) but removing it causes an exception of
|
||||
// incompatible types: ServletContextHandler cannot be converted to Handler
|
||||
//ApplicationManager.this.context.removeHandler(this.appContext);
|
||||
this.appContext.stop();
|
||||
this.appContext.destroy();
|
||||
this.appContext = null;
|
||||
|
|
|
@ -16,11 +16,12 @@
|
|||
|
||||
package helma.main;
|
||||
|
||||
|
||||
import org.eclipse.jetty.server.Connector;
|
||||
import org.eclipse.jetty.server.HttpConfiguration;
|
||||
import org.eclipse.jetty.server.HttpConnectionFactory;
|
||||
import org.eclipse.jetty.server.ServerConnector;
|
||||
import org.eclipse.jetty.util.resource.Resource;
|
||||
import org.eclipse.jetty.util.resource.URLResourceFactory;
|
||||
import org.eclipse.jetty.xml.XmlConfiguration;
|
||||
|
||||
import java.net.URL;
|
||||
|
@ -36,18 +37,20 @@ public class JettyServer {
|
|||
public static JettyServer init(Server server, ServerConfig config) throws IOException {
|
||||
File configFile = config.getConfigFile();
|
||||
if (configFile != null && configFile.exists()) {
|
||||
return new JettyServer(configFile.toURI().toURL());
|
||||
URLResourceFactory resourceFactory = new URLResourceFactory();
|
||||
Resource resource = resourceFactory.newResource(configFile.toURI());
|
||||
return new JettyServer(resource);
|
||||
} else if (config.hasWebsrvPort()) {
|
||||
return new JettyServer(config.getWebsrvPort(), server);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
private JettyServer(URL url) throws IOException {
|
||||
private JettyServer(Resource resource) throws IOException {
|
||||
http = new org.eclipse.jetty.server.Server();
|
||||
|
||||
try {
|
||||
XmlConfiguration config = new XmlConfiguration(url);
|
||||
XmlConfiguration config = new XmlConfiguration(resource);
|
||||
config.configure(http);
|
||||
|
||||
} catch (IOException e) {
|
||||
|
@ -59,7 +62,7 @@ public class JettyServer {
|
|||
|
||||
private JettyServer(InetSocketAddress webPort, Server server)
|
||||
throws IOException {
|
||||
|
||||
|
||||
http = new org.eclipse.jetty.server.Server();
|
||||
|
||||
// start embedded web server if port is specified
|
||||
|
@ -73,7 +76,6 @@ public class JettyServer {
|
|||
connector.setHost(webPort.getAddress().getHostAddress());
|
||||
connector.setPort(webPort.getPort());
|
||||
connector.setIdleTimeout(30000);
|
||||
connector.setSoLingerTime(-1);
|
||||
connector.setAcceptorPriorityDelta(0);
|
||||
connector.setAcceptQueueSize(0);
|
||||
|
||||
|
@ -100,12 +102,13 @@ public class JettyServer {
|
|||
}
|
||||
|
||||
private void openListeners() throws IOException {
|
||||
// opening the listener here allows us to run on priviledged port 80 under jsvc
|
||||
// opening the listener here allows us to run on privileged port 80 under jsvc
|
||||
// even as non-root user, because init() is called with root privileges
|
||||
// while start() will be called with the user we will actually run as
|
||||
Connector[] connectors = http.getConnectors();
|
||||
for (int i = 0; i < connectors.length; i++) {
|
||||
((ServerConnector) connectors[i]).open();
|
||||
for (var connector : http.getConnectors()) {
|
||||
if (connector instanceof ServerConnector) {
|
||||
((ServerConnector) connector).open();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,7 @@ import helma.framework.repository.FileResource;
|
|||
import helma.framework.core.*;
|
||||
import helma.objectmodel.db.DbSource;
|
||||
import helma.util.*;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
import org.apache.xmlrpc.*;
|
||||
|
@ -152,8 +153,8 @@ public class Server implements Runnable {
|
|||
String javaVersion = System.getProperty("java.version", "0");
|
||||
int majorVersion = Integer.parseInt(javaVersion.split("\\.")[0]);
|
||||
|
||||
if (majorVersion < 11) {
|
||||
System.err.println("This version of Helma requires Java 11 or greater.");
|
||||
if (majorVersion < 17) {
|
||||
System.err.println("This version of Helma requires Java 17 or greater.");
|
||||
|
||||
if (majorVersion == 0) { // don't think this will ever happen, but you never know
|
||||
System.err.println("Your Java Runtime did not provide a version number. Please update to a more recent version.");
|
||||
|
|
|
@ -22,18 +22,29 @@ package helma.servlet;
|
|||
import helma.framework.*;
|
||||
import helma.framework.core.Application;
|
||||
import helma.util.*;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.*;
|
||||
import java.nio.charset.Charset;
|
||||
import java.nio.charset.UnsupportedCharsetException;
|
||||
|
||||
import java.security.SecureRandom;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
import javax.servlet.*;
|
||||
import javax.servlet.http.*;
|
||||
import java.util.*;
|
||||
|
||||
import jakarta.servlet.*;
|
||||
import jakarta.servlet.http.*;
|
||||
|
||||
import org.apache.commons.codec.binary.Base64;
|
||||
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload.*;
|
||||
import org.apache.commons.fileupload.servlet.ServletFileUpload;
|
||||
import org.apache.commons.fileupload.servlet.ServletRequestContext;
|
||||
|
||||
import org.apache.commons.fileupload2.core.DiskFileItemFactory;
|
||||
import org.apache.commons.fileupload2.core.FileItem;
|
||||
import org.apache.commons.fileupload2.core.FileUploadException;
|
||||
import org.apache.commons.fileupload2.core.FileUploadSizeException;
|
||||
import org.apache.commons.fileupload2.core.ProgressListener;
|
||||
|
||||
import org.apache.commons.fileupload2.jakarta.JakartaServletDiskFileUpload;
|
||||
import org.apache.commons.fileupload2.jakarta.JakartaServletFileUpload;
|
||||
import org.apache.commons.fileupload2.jakarta.JakartaServletRequestContext;
|
||||
|
||||
/**
|
||||
* This is an abstract Hop servlet adapter. This class communicates with hop applications
|
||||
|
@ -218,9 +229,9 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
|
||||
// read file uploads
|
||||
List uploads = null;
|
||||
ServletRequestContext reqcx = new ServletRequestContext(request);
|
||||
JakartaServletRequestContext reqcx = new JakartaServletRequestContext(request);
|
||||
|
||||
if (ServletFileUpload.isMultipartContent(reqcx)) {
|
||||
if (JakartaServletFileUpload.isMultipartContent(reqcx)) {
|
||||
// get session for upload progress monitoring
|
||||
UploadStatus uploadStatus = getApplication().getUploadStatus(reqtrans);
|
||||
try {
|
||||
|
@ -228,7 +239,7 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
} catch (Exception upx) {
|
||||
log("Error in file upload", upx);
|
||||
String message;
|
||||
boolean tooLarge = (upx instanceof FileUploadBase.SizeLimitExceededException);
|
||||
boolean tooLarge = (upx instanceof FileUploadSizeException);
|
||||
if (tooLarge) {
|
||||
message = "File upload size exceeds limit of " + uploadLimit + " kB";
|
||||
} else {
|
||||
|
@ -653,12 +664,12 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
map.put(name, newValues);
|
||||
}
|
||||
|
||||
protected List parseUploads(ServletRequestContext reqcx, RequestTrans reqtrans,
|
||||
protected List parseUploads(JakartaServletRequestContext reqcx, RequestTrans reqtrans,
|
||||
final UploadStatus uploadStatus, String encoding)
|
||||
throws FileUploadException, UnsupportedEncodingException {
|
||||
throws FileUploadException, UnsupportedCharsetException, IOException {
|
||||
// handle file upload
|
||||
DiskFileItemFactory factory = new DiskFileItemFactory();
|
||||
FileUpload upload = new FileUpload(factory);
|
||||
DiskFileItemFactory factory = DiskFileItemFactory.builder().get();
|
||||
JakartaServletFileUpload upload = new JakartaServletFileUpload(factory);
|
||||
// use upload limit for individual file size, but also set a limit on overall size
|
||||
upload.setFileSizeMax(uploadLimit * 1024);
|
||||
upload.setSizeMax(totalUploadLimit * 1024);
|
||||
|
@ -681,7 +692,7 @@ public abstract class AbstractServletClient extends HttpServlet {
|
|||
Object value;
|
||||
// check if this is an ordinary HTML form element or a file upload
|
||||
if (item.isFormField()) {
|
||||
value = item.getString(encoding);
|
||||
value = item.getString(Charset.forName(encoding));
|
||||
} else {
|
||||
value = new MimePart(item);
|
||||
}
|
||||
|
|
|
@ -19,7 +19,7 @@ package helma.servlet;
|
|||
import helma.framework.*;
|
||||
import helma.framework.core.Application;
|
||||
import helma.main.*;
|
||||
import javax.servlet.*;
|
||||
import jakarta.servlet.*;
|
||||
|
||||
/**
|
||||
* Servlet client that runs a Helma application for the embedded
|
||||
|
|
|
@ -23,7 +23,7 @@ import helma.main.ServerConfig;
|
|||
import helma.main.Server;
|
||||
|
||||
import java.io.*;
|
||||
import javax.servlet.*;
|
||||
import jakarta.servlet.*;
|
||||
import java.util.*;
|
||||
|
||||
/**
|
||||
|
@ -98,7 +98,7 @@ public final class StandaloneServletClient extends AbstractServletClient {
|
|||
repositoryImpl = "helma.framework.repository.FileRepository";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
try {
|
||||
Repository newRepository = (Repository) Class.forName(repositoryImpl)
|
||||
.getConstructor(parameters)
|
||||
|
@ -116,7 +116,7 @@ public final class StandaloneServletClient extends AbstractServletClient {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// add app dir
|
||||
FileRepository appRep = new FileRepository(appDir);
|
||||
log("adding repository: " + appDir);
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
package helma.util;
|
||||
|
||||
import org.apache.commons.fileupload.FileItem;
|
||||
import org.apache.commons.fileupload2.core.FileItem;
|
||||
|
||||
import java.io.*;
|
||||
import java.util.Date;
|
||||
|
@ -238,7 +238,7 @@ public class MimePart implements Serializable {
|
|||
file = new File(base, filename);
|
||||
|
||||
if (fileItem != null) {
|
||||
fileItem.write(file);
|
||||
fileItem.write(file.toPath());
|
||||
// null out fileItem, since calling write() may have moved the temp file
|
||||
fileItem = null;
|
||||
} else {
|
||||
|
@ -249,7 +249,7 @@ public class MimePart implements Serializable {
|
|||
// return file name
|
||||
return filename;
|
||||
} catch (Exception x) {
|
||||
System.err.println("Error in MimePart.writeToFile(): " + x);
|
||||
System.err.println("Error in MimePart.writeToFile(): " + x);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Reference in a new issue