diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml index c534153c..e7113e88 100644 --- a/.github/workflows/maven.yml +++ b/.github/workflows/maven.yml @@ -8,7 +8,7 @@ on: env: # Default versions for canonical release build - DEFAULT_JAVA_VERSION: '11' + DEFAULT_JAVA_VERSION: '8' DEFAULT_JRUBY_VERSION: '9.4.13.0' # Should match pom.xml property (AND a version inside the test matrix) jobs: @@ -19,8 +19,10 @@ jobs: strategy: matrix: jruby_version: [ '9.4.13.0', '10.0.2.0' ] - java_version: [ '11', '17', '21' ] + java_version: [ '8', '11', '17', '21' ] exclude: + - jruby_version: '10.0.2.0' + java_version: '8' # JRuby 10 requires Java 21 - jruby_version: '10.0.2.0' java_version: '11' # JRuby 10 requires Java 21 - jruby_version: '10.0.2.0' @@ -53,11 +55,13 @@ jobs: strategy: matrix: jruby_version: [ '9.4.13.0', '10.0.2.0' ] - java_version: [ '11', '17', '21' ] + java_version: [ '8', '11', '17', '21' ] appraisal: [ 'rails50', 'rails52', 'rails60', 'rails61', 'rails70', 'rails71', 'rails72', 'rails80' ] exclude: - jruby_version: '9.4.13.0' appraisal: 'rails80' # Requires Ruby 3.4 compatibility, which JRuby 9.4 does not support + - jruby_version: '10.0.2.0' + java_version: '8' # JRuby 10 requires Java 21 - jruby_version: '10.0.2.0' java_version: '11' # JRuby 10 requires Java 21 - jruby_version: '10.0.2.0' diff --git a/Gemfile.lock b/Gemfile.lock index 9c96077f..9193ef5f 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -24,6 +24,7 @@ GEM thor (1.4.0) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/History.md b/History.md index abe812de..7892f691 100644 --- a/History.md +++ b/History.md @@ -1,6 +1,5 @@ ## 1.3.0 (UNRELEASED) -- Require Java 11 or later - Support Javax Servlet API 4.0 (JEE 8) - Adds basic compatibility with JRuby 10.0 - Drop support for JRuby 9.3 diff --git a/README.md b/README.md index b6ee98ed..0bfd8550 100644 --- a/README.md +++ b/README.md @@ -14,7 +14,7 @@ For more information on Rack, visit http://rack.github.io/. | JRuby-Rack Version | Status | JRuby Compat | Java Compat | Target Servlet API | Target Java EE | Notes | |--------------------------------------------------------------|------------|--------------|-------------|--------------------|----------------|---------------------------------------------------| | 2.0.x (_planned_) | Dev | 9.4 → 10.0 | Java 17+ | 5.0 | Jakarta EE 9 | | -| 1.3.x (master, _unreleased_) | Dev | 9.4 → 10.0 | Java 11+ | 4.0 | Java EE 8 | | +| 1.3.x (master, _unreleased_) | Dev | 9.4 → 10.0 | Java 8+ | 4.0 | Java EE 8 | | | [1.2.x](https://github.com/jruby/jruby-rack/tree/1.2-stable) | Maintained | 9.3 → 9.4 | Java 8+ | 3.0 | Java EE 6 | Servlet 3.1 → 4.0 tested OK with some containers. | | [1.1.x](https://github.com/jruby/jruby-rack/tree/1.1-stable) | EOL | 1.6 → 9.4 | Java 8+ | 2.5 | Java EE 5 | Servlet 3.0 → 4.0 tested OK with some containers. | diff --git a/gemfiles/rails50.gemfile.lock b/gemfiles/rails50.gemfile.lock index a7ff8931..4c0e0aec 100644 --- a/gemfiles/rails50.gemfile.lock +++ b/gemfiles/rails50.gemfile.lock @@ -138,6 +138,7 @@ GEM websocket-extensions (0.1.5) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/gemfiles/rails52.gemfile.lock b/gemfiles/rails52.gemfile.lock index 3b75f9b6..59e70b49 100644 --- a/gemfiles/rails52.gemfile.lock +++ b/gemfiles/rails52.gemfile.lock @@ -146,6 +146,7 @@ GEM websocket-extensions (0.1.5) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/gemfiles/rails60.gemfile.lock b/gemfiles/rails60.gemfile.lock index 2af33bb4..1070db9a 100644 --- a/gemfiles/rails60.gemfile.lock +++ b/gemfiles/rails60.gemfile.lock @@ -162,6 +162,7 @@ GEM zeitwerk (2.6.18) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/gemfiles/rails61.gemfile.lock b/gemfiles/rails61.gemfile.lock index 193015ec..3d45bdfd 100644 --- a/gemfiles/rails61.gemfile.lock +++ b/gemfiles/rails61.gemfile.lock @@ -165,6 +165,7 @@ GEM zeitwerk (2.6.18) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/gemfiles/rails70.gemfile.lock b/gemfiles/rails70.gemfile.lock index 50a5c4a1..00832067 100644 --- a/gemfiles/rails70.gemfile.lock +++ b/gemfiles/rails70.gemfile.lock @@ -162,6 +162,7 @@ GEM zeitwerk (2.6.18) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/gemfiles/rails71.gemfile.lock b/gemfiles/rails71.gemfile.lock index 76530016..e335a488 100644 --- a/gemfiles/rails71.gemfile.lock +++ b/gemfiles/rails71.gemfile.lock @@ -207,6 +207,7 @@ GEM zeitwerk (2.6.18) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/gemfiles/rails72.gemfile.lock b/gemfiles/rails72.gemfile.lock index 599b5b58..2bfa7d61 100644 --- a/gemfiles/rails72.gemfile.lock +++ b/gemfiles/rails72.gemfile.lock @@ -201,6 +201,7 @@ GEM zeitwerk (2.6.18) PLATFORMS + universal-java-1.8 universal-java-11 universal-java-17 universal-java-21 diff --git a/pom.xml b/pom.xml index fbdbce47..9c557ea0 100644 --- a/pom.xml +++ b/pom.xml @@ -201,8 +201,8 @@ maven-compiler-plugin 3.14.0 - 11 - 11 + 8 + 8 true true diff --git a/src/main/java/org/jruby/rack/DefaultRackConfig.java b/src/main/java/org/jruby/rack/DefaultRackConfig.java index 7705f556..24f3d5b5 100644 --- a/src/main/java/org/jruby/rack/DefaultRackConfig.java +++ b/src/main/java/org/jruby/rack/DefaultRackConfig.java @@ -382,7 +382,7 @@ private Map toStringMap(final String env) { for ( final String entry : entries ) { String[] pair = entry.split("=", 2); if ( pair.length == 1 ) { // no = separator - if ( entry.isBlank() ) continue; + if ( entry.trim().isEmpty() ) continue; if ( lastKey == null ) continue; // missing key map.put( lastKey, lastVal = lastVal + ',' + entry ); } diff --git a/src/main/java/org/jruby/rack/UnmappedRackFilter.java b/src/main/java/org/jruby/rack/UnmappedRackFilter.java index c3617efa..f0f05d3d 100644 --- a/src/main/java/org/jruby/rack/UnmappedRackFilter.java +++ b/src/main/java/org/jruby/rack/UnmappedRackFilter.java @@ -42,18 +42,24 @@ public class UnmappedRackFilter extends AbstractFilter { private boolean responseHandledByDefault = true; - private static final Collection RESPONSE_NOT_HANDLED_STATUSES = Set.of( - 404, - 403, // 403 due to containers not supporting PUT/DELETE correctly (Tomcat 6) - 405, // 405 returned by Jetty 7/8 on PUT/DELETE requests by default - 501 // 501 is returned for non standard http verbs like PATCH - ); + private static final Collection RESPONSE_NOT_HANDLED_STATUSES; + static { + final Set statuses = new HashSet<>(8, 1); + statuses.add(404); + // 403 due containers not supporting PUT/DELETE correctly (Tomcat 6) + statuses.add(403); + // 405 returned by Jetty 7/8 on PUT/DELETE requests by default + statuses.add(405); + // 501 is returned for non standard http verbs like PATCH + statuses.add(501); + RESPONSE_NOT_HANDLED_STATUSES = Collections.unmodifiableSet(statuses); + } private Collection responseNotHandledStatuses = RESPONSE_NOT_HANDLED_STATUSES; private RackContext context; private RackDispatcher dispatcher; - public UnmappedRackFilter() { /** constructor used by container */ } + public UnmappedRackFilter() { /* constructor used by container */ } /** * Dependency-injected constructor for testing @@ -85,7 +91,7 @@ public void init(FilterConfig config) throws ServletException { map(String::trim) .filter(status -> !status.isEmpty()) .map(Integer::parseInt) - .collect(Collectors.toUnmodifiableSet()); + .collect(Collectors.toSet()); } // ResponseCapture.handledByDefault true/false (true by default) value = config.getInitParameter("responseHandledByDefault"); diff --git a/src/main/java/org/jruby/rack/servlet/RequestCapture.java b/src/main/java/org/jruby/rack/servlet/RequestCapture.java index 87da4c92..7090685e 100644 --- a/src/main/java/org/jruby/rack/servlet/RequestCapture.java +++ b/src/main/java/org/jruby/rack/servlet/RequestCapture.java @@ -10,8 +10,8 @@ import java.io.BufferedReader; import java.io.IOException; import java.io.InputStreamReader; +import java.io.UnsupportedEncodingException; import java.net.URLDecoder; -import java.nio.charset.StandardCharsets; import java.util.Enumeration; import java.util.HashMap; import java.util.Iterator; @@ -79,7 +79,7 @@ public Map getParameterMap() { @Override public Enumeration getParameterNames() { if ( requestParametersParsed() ) { - return new Enumeration<>() { + return new Enumeration() { final Iterator keys = requestParams.keySet().iterator(); public boolean hasMoreElements() { return keys.hasNext(); @@ -121,25 +121,27 @@ private boolean parseRequestParams() { final Map params = new HashMap<>(); final String[] pairs = line.split("\\&"); for (String pair : pairs) { - String[] fields = pair.split("=", 2); - String key = URLDecoder.decode(fields[0], StandardCharsets.UTF_8); - String value = null; - if (fields.length == 2) { - value = URLDecoder.decode(fields[1], StandardCharsets.UTF_8); - } - if (value != null) { - String[] newValues; - if (params.containsKey(key)) { - String[] values = params.get(key); - newValues = new String[values.length + 1]; - System.arraycopy(values, 0, newValues, 0, values.length); - newValues[values.length] = value; - } else { - newValues = new String[1]; - newValues[0] = value; + try { + String[] fields = pair.split("=", 2); + String key = URLDecoder.decode(fields[0], "UTF-8"); + String value = null; + if (fields.length == 2) { + value = URLDecoder.decode(fields[1], "UTF-8"); } - params.put(key, newValues); - } + if (value != null) { + String[] newValues; + if (params.containsKey(key)) { + String[] values = params.get(key); + newValues = new String[values.length + 1]; + System.arraycopy(values, 0, newValues, 0, values.length); + newValues[values.length] = value; + } else { + newValues = new String[1]; + newValues[0] = value; + } + params.put(key, newValues); + } + } catch (UnsupportedEncodingException ignore) { /* UTF-8 should be fine */ } } this.requestParams = params;