diff --git a/src/main/java/org/jruby/rack/servlet/ResponseCapture.java b/src/main/java/org/jruby/rack/servlet/ResponseCapture.java index 11e77070..9c89dd2c 100644 --- a/src/main/java/org/jruby/rack/servlet/ResponseCapture.java +++ b/src/main/java/org/jruby/rack/servlet/ResponseCapture.java @@ -12,8 +12,11 @@ import java.io.PrintWriter; import java.lang.reflect.InvocationTargetException; import java.lang.reflect.Method; +import java.util.Arrays; import java.util.Collection; import java.util.Collections; +import java.util.HashSet; +import java.util.Set; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; @@ -24,6 +27,13 @@ * Response wrapper passed to filter chain. */ public class ResponseCapture extends HttpServletResponseWrapper { + /** + * In case of OPTION calls we check what headers are set by the servlet to decide if a request is + * already handled. Some container implementation of DefaultServlet already set 'Allow' and/or 'Date' fields which + * we need to ignore when working with this approach + */ + private static final Set HEADERS_NOT_CONSIDERED_HANDLED_FOR_OPTIONS_CALL + = new HashSet(Arrays.asList("Allow", "Date")); private static final String STREAM = "stream"; private static final String WRITER = "writer"; @@ -230,9 +240,10 @@ public boolean isHandled(final HttpServletRequest request) { // not to happen but there's all kind of beasts out there return false; } + // if any other headers occur beside 'Allow' and 'Date' we consider this request handled. for ( final String headerName : headerNames ) { - if ( ! "Allow".equals( headerName ) ) { - return handled = true; // not just Allow header - consider handled + if ( !HEADERS_NOT_CONSIDERED_HANDLED_FOR_OPTIONS_CALL.contains(headerName) ) { + return handled = true; } } return false; // OPTIONS with only Allow header set - unhandled diff --git a/src/spec/ruby/rack/servlet/response_capture_spec.rb b/src/spec/ruby/rack/servlet/response_capture_spec.rb index 606dff43..8ef3e385 100644 --- a/src/spec/ruby/rack/servlet/response_capture_spec.rb +++ b/src/spec/ruby/rack/servlet/response_capture_spec.rb @@ -65,6 +65,16 @@ expect( response_capture.isHandled(servlet_request) ).to be false end + it "is not considered handled when only Allow or Date header is added with OPTIONS" do + servlet_request.method = 'OPTIONS' + + # NOTE: Jetty sets both Date and Allow in DefaultServlet#doOptions + response_capture.addHeader "Allow", "GET, POST, OPTIONS" + response_capture.addHeader "Date", Time.now.httpdate + + expect( response_capture.isHandled(servlet_request) ).to be false + end + it "is considered handled when more than Allow header is added with OPTIONS" do pending "need Servlet API 3.0" unless servlet_30? @@ -100,4 +110,4 @@ def servlet_30? Java::JavaClass.for_name('javax.servlet.AsyncContext') rescue nil end -end \ No newline at end of file +end