Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

Preliminary include capability #32

Merged
merged 7 commits into from

2 participants

@baq
Collaborator

Hi Nick,

I wanted to float this pull request by you to get your feedback. I've done the initial work to add the include capability. Here's some items of note:

  • I had to use a buffer to capture the include's response. The order in which things are written to the stream wouldn't allow for the jsp include to work without a buffer (the Rack app's response is buffered until the call is complete). So my workaround was to capture the response into a string, much like 'yield' in an erb (which I'm wondering if instead of calling it request.include, I should call it request.yield). This has the drawback of not being able to stream, so if you have some good suggestions on that front, I'd love to hear them.
  • Hardly any unit tests yet, but there's an example worked up in the examples/sinatra app.
  • Still need to add the capability to the Rails sample. I was thinking I'd keep the API you created for Rails (the straight up 'forward_to') but just change the underlying implementation to not require the proc.

Let me know what you think!

Thanks,
Baq

@nicksieger
Owner

Hey Baq, sorry I haven't had a chance to get to this yet. Your code looks great. We can add the Rails APIs soon, it shouldn't be too hard.

Would you mind if I added the project copyright header to the new files? If you prefer to keep your name in the copyright, I understand. I'll look into some sort of contributor agreement if that's amenable to you.

@baq
Collaborator

Nick,

No worries about the delay. And no, I don't need to have my name in the copyright or sign any contributor agreement, so I don't mind at all if you put the project copyright header into the new files. I blame Eclipse for all insertions of my name. :)

Do you mind if I add a few things to this patch before you pull? I'd like to

  • change "request.include" to "request.yield" if you have no objections
  • add some more unit tests
  • change the underlying Rails implementation to use the new forward mechanism and test it

It'll probably take me a week or so to get this in.

Let me know if that works for you,
Baq

Baq Haidri added some commits
Baq Haidri Merge remote branch 'upstream/master' 0d833f3
Baq Haidri Pull Request #32 for JSP Forward/Include support
* Updated forward support in Sinatra/Rails3 to avoid writing to response after it's committed
* Added include support to Rails3
* Changed "request.include" to "request.render" to be more in line with Rails
8f6307c
@baq
Collaborator

Hey Nick,

Do you mind reviewing this pull request when you get the chance? Let me know if you there are any changes that should be made before pulling it in.

Thanks.
Baq

@nicksieger
Owner

Baq, your stuff looks great. Can you go ahead and merge it to master yourself? I added you as a committer.

@nicksieger
Owner

Also, beware that @nicobrevin has a pull request pending (#53) as well that might conflict with yours. Last write loses! :)

@baq baq merged commit 96a3002 into jruby:master
@baq
Collaborator
baq commented

Awesome! I just beat @nicobrevin to the punch and merged my changes in. Sorry Nico and good luck with your merge! Nick, let me know if any problems crop up with the merge.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Apr 19, 2011
  1. @baq
Commits on Apr 21, 2011
  1. @baq
  2. @baq
Commits on Apr 24, 2011
  1. @baq
  2. @baq

    Platform-specific line separator

    baq authored
Commits on Jul 28, 2011
  1. Merge remote branch 'upstream/master'

    Baq Haidri authored
Commits on Aug 17, 2011
  1. Pull Request #32 for JSP Forward/Include support

    Baq Haidri authored
    * Updated forward support in Sinatra/Rails3 to avoid writing to response after it's committed
    * Added include support to Rails3
    * Changed "request.include" to "request.render" to be more in line with Rails
This page is out of date. Refresh to see the latest.
Showing with 373 additions and 32 deletions.
  1. +2 −1  examples/rails3/app/controllers/jsp_controller.rb
  2. +6 −0 examples/rails3/app/controllers/jsp_forward_controller.rb
  3. +5 −0 examples/rails3/app/controllers/jsp_include_controller.rb
  4. +3 −0  examples/rails3/app/views/jsp_include/index.html.erb
  5. +1 −0  examples/rails3/public/jsp/include.jsp
  6. +8 −0 examples/sinatra/lib/env.rb
  7. +1 −0  examples/sinatra/public/jsp/include.jsp
  8. +13 −0 examples/sinatra/public/jsp/index.jsp
  9. +1 −1  examples/sinatra/public/style.css
  10. +13 −0 examples/sinatra/views/jsp_include.erb
  11. +1 −1  src/main/java/org/jruby/rack/RackFilter.java
  12. +1 −1  src/main/java/org/jruby/rack/RackServlet.java
  13. +2 −1  src/main/java/org/jruby/rack/RackTag.java
  14. +14 −1 src/main/java/org/jruby/rack/servlet/ServletRackEnvironment.java
  15. +254 −0 src/main/java/org/jruby/rack/servlet/ServletRackIncludedResponse.java
  16. +1 −1  src/main/java/org/jruby/rack/servlet/ServletRackResponseEnvironment.java
  17. +1 −0  src/main/ruby/jruby/rack.rb
  18. +26 −0 src/main/ruby/jruby/rack/rack_ext.rb
  19. +2 −12 src/main/ruby/jruby/rack/rails/extensions.rb
  20. +1 −3 src/main/ruby/jruby/rack/response.rb
  21. +3 −2 src/main/ruby/rack/handler/servlet.rb
  22. +1 −3 src/spec/ruby/jruby/rack/rails_spec.rb
  23. +6 −4 src/spec/ruby/jruby/rack/response_spec.rb
  24. +7 −1 src/spec/ruby/rack/handler/servlet_spec.rb
View
3  examples/rails3/app/controllers/jsp_controller.rb
@@ -1,6 +1,7 @@
class JspController < ApplicationController
def index
- servlet_request['message'] = 'Hello from Rails!'
+ servlet_request['message'] = "This is being rendered by a JSP!"
forward_to '/jsp/index.jsp'
+ render :nothing => true
end
end
View
6 examples/rails3/app/controllers/jsp_forward_controller.rb
@@ -0,0 +1,6 @@
+class JspForwardController < ApplicationController
+ def index
+ request.forward_to '/jsp/index.jsp', {:message => "This is being rendered by a JSP!"}
+ render :nothing => true
+ end
+end
View
5 examples/rails3/app/controllers/jsp_include_controller.rb
@@ -0,0 +1,5 @@
+class JspIncludeController < ApplicationController
+ def index
+ @today = Time.now.strftime("%m/%d/%Y")
+ end
+end
View
3  examples/rails3/app/views/jsp_include/index.html.erb
@@ -0,0 +1,3 @@
+<div>This line of text came from a Rails ERB, today's date is <%= @today %></div>
+<br/>
+<div>And this is content from a JSP: <br\> <b><%= request.render "/jsp/include.jsp", {"message" => "I'm a message that came from Rails!"} %> </b></div>
View
1  examples/rails3/public/jsp/include.jsp
@@ -0,0 +1 @@
+Yoohoo look at me! I am an included JSP. The servlet request attribute is [<%= request.getAttribute("message") %>]
View
8 examples/sinatra/lib/env.rb
@@ -41,3 +41,11 @@
store
output.string
end
+
+get '/jsp_forward' do
+ request.forward_to "/jsp/index.jsp", {"message" => "Hello from JSP"}
+end
+
+get '/jsp_include' do
+ erb :jsp_include
+end
View
1  examples/sinatra/public/jsp/include.jsp
@@ -0,0 +1 @@
+<div class="inside_jsp">Yoohoo look at me! I am an included JSP. The servlet request attribute is [<%= request.getAttribute("message") %>]</div>
View
13 examples/sinatra/public/jsp/index.jsp
@@ -0,0 +1,13 @@
+<html>
+ <head><title>Sinatra forwards to JSP</title></head>
+ <link rel="stylesheet" href="http://yui.yahooapis.com/2.8.0r4/build/reset/reset-min.css" type="text/css" media="screen, projection">
+ <link rel="stylesheet" href="style.css" type="text/css" media="screen, projection">
+ <link rel="shortcut icon" href="favicon.ico">
+ <body>
+ <div id="content">
+ <div class="inside_jsp">
+ This page has been generated from a JSP. The servlet request attribute is <%= request.getAttribute("message") %>
+ </div>
+ </div>
+ </body>
+</html>
View
2  examples/sinatra/public/style.css
@@ -6,4 +6,4 @@ p {margin: 20px 0px;}
ul, ol {margin:0 1.5em 1.5em 1.5em;}
ul {list-style-type:disc;}
ol {list-style-type:decimal;}
-
+.inside_jsp {border: dotted 1px; margin-left: 20px;}
View
13 examples/sinatra/views/jsp_include.erb
@@ -0,0 +1,13 @@
+<html>
+ <head><title>Sinatra includes JSP</title></head>
+ <link rel="stylesheet" href="http://yui.yahooapis.com/2.8.0r4/build/reset/reset-min.css" type="text/css" media="screen, projection">
+ <link rel="stylesheet" href="style.css" type="text/css" media="screen, projection">
+ <link rel="shortcut icon" href="favicon.ico">
+ <body>
+ <div id="content">
+ <div>This line of text came from ERB.</div>
+ <br/>
+ <div>And this is content from a JSP: <br\> <%= request.render "/jsp/include.jsp", {"message" => "I'm a message that came from Sinatra!"} %></div>
+ </div>
+ </body>
+</html>
View
2  src/main/java/org/jruby/rack/RackFilter.java
@@ -46,7 +46,7 @@ public void init(FilterConfig config) throws ServletException {
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain)
throws IOException, ServletException {
- RackEnvironment env = new ServletRackEnvironment((HttpServletRequest) request, context);
+ RackEnvironment env = new ServletRackEnvironment((HttpServletRequest) request, (HttpServletResponse) response, context);
RackResponseEnvironment responseEnv = new ServletRackResponseEnvironment((HttpServletResponse) response);
HttpServletRequest httpRequest = maybeAppendHtmlToPath(request, env);
HttpServletResponse httpResponse = (HttpServletResponse) response;
View
2  src/main/java/org/jruby/rack/RackServlet.java
@@ -47,7 +47,7 @@ public void init(ServletConfig config) {
@Override
public void service(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
- dispatcher.process(new ServletRackEnvironment(request, rackContext), new ServletRackResponseEnvironment(response));
+ dispatcher.process(new ServletRackEnvironment(request, response, rackContext), new ServletRackResponseEnvironment(response));
}
@Override
View
3  src/main/java/org/jruby/rack/RackTag.java
@@ -11,6 +11,7 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
import javax.servlet.jsp.JspException;
import javax.servlet.jsp.tagext.TagSupport;
@@ -43,7 +44,7 @@ public int doEndTag() throws JspException {
@Override public String getQueryString() { return params; }
@Override public String getServletPath() { return ""; }
};
- RackResponse result = app.call(new ServletRackEnvironment(request, context));
+ RackResponse result = app.call(new ServletRackEnvironment(request, (HttpServletResponse) pageContext.getResponse(), context));
pageContext.getOut().write(result.getBody());
} finally {
factory.finishedWithApplication(app);
View
15 src/main/java/org/jruby/rack/servlet/ServletRackEnvironment.java
@@ -12,6 +12,8 @@
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
+import javax.servlet.http.HttpServletResponse;
+
import java.io.IOException;
import java.io.InputStream;
@@ -22,14 +24,17 @@
@SuppressWarnings("deprecation")
public class ServletRackEnvironment extends HttpServletRequestWrapper
implements HttpServletRequest, RackEnvironment {
+
private String scriptName;
private String requestURI;
private String requestURIWithoutQuery;
private String pathInfo;
private RackContext rackContext;
+ private HttpServletResponse servletResponse;
- public ServletRackEnvironment(HttpServletRequest request, RackContext rackContext) {
+ public ServletRackEnvironment(HttpServletRequest request, HttpServletResponse response, RackContext rackContext) {
super(request);
+ this.servletResponse = response;
this.rackContext = rackContext;
}
@@ -40,6 +45,14 @@ public RackContext getContext() {
public InputStream getInput() throws IOException {
return getInputStream();
}
+
+ /**
+ * The underlying HttpServletResponse
+ * @return
+ */
+ public HttpServletResponse getResponse() {
+ return servletResponse;
+ }
/**
* Define the script name as the context path + the servlet path.
View
254 src/main/java/org/jruby/rack/servlet/ServletRackIncludedResponse.java
@@ -0,0 +1,254 @@
+package org.jruby.rack.servlet;
+
+import java.io.ByteArrayOutputStream;
+import java.io.DataOutputStream;
+import java.io.IOException;
+import java.io.OutputStreamWriter;
+import java.io.PrintWriter;
+import java.io.UnsupportedEncodingException;
+
+import javax.servlet.ServletOutputStream;
+import javax.servlet.ServletResponse;
+import javax.servlet.http.HttpServletResponse;
+import javax.servlet.http.HttpServletResponseWrapper;
+
+/**
+ * Response wrapper used to buffer the output of a server-side include.
+ */
+public class ServletRackIncludedResponse extends HttpServletResponseWrapper {
+
+ private final static int BUFFER_SIZE = 16 * 1024; // 16K buffer size
+
+ private int bufferSize;
+ private ServletResponse wrappedResponse;
+ private PrintWriter writer;
+ private ServletOutputStream outputStream;
+ private ByteArrayOutputStream byteOutputStream;
+
+ public ServletRackIncludedResponse(HttpServletResponse response) {
+ super(response);
+ bufferSize = BUFFER_SIZE;
+ wrappedResponse = response;
+ }
+
+ /**
+ * Returns the output of the include as a string, encoded by the
+ * character encoding available in {@link ServletReponse.getCharacterEncoding()}}
+ * @return
+ */
+ public String getOutput() {
+ String charSet = super.getResponse().getCharacterEncoding();
+ try {
+ flushBuffer();
+ return byteOutputStream.toString(charSet);
+ } catch (Exception e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ @Override
+ public ServletResponse getResponse() {
+ return wrappedResponse;
+ }
+
+ @Override
+ public void setResponse(ServletResponse response) {
+ wrappedResponse = response;
+ }
+
+ @Override
+ public void flushBuffer() throws IOException {
+ if (writer != null) {
+ writer.flush();
+ } else if (outputStream != null) {
+ outputStream.flush();
+ }
+ }
+
+ /**
+ * All content written to this response is buffered,
+ * but this method will return either the initial buffer size
+ * or the one specified using {@link #setBufferSize(int)}.
+ */
+ @Override
+ public int getBufferSize() {
+ return bufferSize;
+ }
+
+ @Override
+ public ServletOutputStream getOutputStream() throws IOException {
+ if (writer != null) {
+ throw new IllegalStateException("Cannot return output stream after a writer has been returned");
+ }
+ if (outputStream == null) {
+ initializeOutputStream();
+ }
+ return outputStream;
+ }
+
+ @Override
+ public PrintWriter getWriter() throws IOException {
+ if (outputStream != null) {
+ throw new IllegalStateException("Cannot return writer after an output stream has been returned");
+ }
+ if (writer == null) {
+ initializeWriter();
+ }
+ return writer;
+ }
+
+ @Override
+ public void reset() {
+ throw new UnsupportedOperationException("Cannot reset a response from inside a server-side include");
+ }
+
+ @Override
+ public void resetBuffer() {
+ if (getResponse().isCommitted()) {
+ throw new IllegalArgumentException("Illegal call to resetBuffer() after response has been committed");
+ }
+ if (writer != null) {
+ initializeWriter();
+ } else if (outputStream != null) {
+ initializeOutputStream();
+ }
+ }
+
+ /**
+ * Calls to this method are ignored if the stream has already been written to,
+ * unless {@link #resetBuffer()} is called.
+ */
+ @Override
+ public void setBufferSize(int size) {
+ bufferSize = size;
+ }
+
+ private void initializeWriter() {
+ String charSet = super.getResponse().getCharacterEncoding();
+ byteOutputStream = new ByteArrayOutputStream(bufferSize);
+ try {
+ writer = new PrintWriter(new OutputStreamWriter(byteOutputStream, charSet));
+ } catch (UnsupportedEncodingException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+ private void initializeOutputStream() {
+ String charSet = super.getResponse().getCharacterEncoding();
+ byteOutputStream = new ByteArrayOutputStream(bufferSize);
+ outputStream = new ByteArrayServletOutputStream(byteOutputStream, charSet);
+ }
+
+ /**
+ * Crunchy ServletOutputStream coating hiding a chewy ByteArrayOutputStream center.
+ * @author bhaidri
+ */
+ private final static class ByteArrayServletOutputStream extends ServletOutputStream {
+
+ private final static String LINE_SEPARATOR = System.getProperty("line.separator");
+ private final DataOutputStream dataOutputStream;
+ private final String charSet;
+
+ public ByteArrayServletOutputStream(ByteArrayOutputStream byteOutputStream, String charSet) {
+ super();
+ this.dataOutputStream = new DataOutputStream(byteOutputStream);
+ this.charSet = charSet;
+ }
+
+ @Override
+ public void print(boolean b) throws IOException {
+ dataOutputStream.writeBoolean(b);
+ }
+
+ @Override
+ public void print(char c) throws IOException {
+ dataOutputStream.writeChar(c);
+ }
+
+ @Override
+ public void print(double d) throws IOException {
+ dataOutputStream.writeDouble(d);
+ }
+
+ @Override
+ public void print(float f) throws IOException {
+ dataOutputStream.writeFloat(f);
+ }
+
+ @Override
+ public void print(int i) throws IOException {
+ dataOutputStream.write(i);
+ }
+
+ @Override
+ public void print(long l) throws IOException {
+ dataOutputStream.writeLong(l);
+ }
+
+ @Override
+ public void print(String s) throws IOException {
+ dataOutputStream.write(s.getBytes(charSet));
+ }
+
+ @Override
+ public void println() throws IOException {
+ dataOutputStream.write(LINE_SEPARATOR.getBytes(charSet));
+ }
+
+ @Override
+ public void println(boolean b) throws IOException {
+ print(b);
+ println();
+ }
+
+ @Override
+ public void println(char c) throws IOException {
+ print(c);
+ println();
+ }
+
+ @Override
+ public void println(double d) throws IOException {
+ print(d);
+ println();
+ }
+
+ @Override
+ public void println(float f) throws IOException {
+ print(f);
+ println();
+ }
+
+ @Override
+ public void println(int i) throws IOException {
+ print(i);
+ println();
+ }
+
+ @Override
+ public void println(long l) throws IOException {
+ print(l);
+ println();
+ }
+
+ @Override
+ public void println(String s) throws IOException {
+ print(s);
+ }
+
+ @Override
+ public void write(byte[] b, int off, int len) throws IOException {
+ dataOutputStream.write(b, off, len);
+ }
+
+ @Override
+ public void write(byte[] b) throws IOException {
+ dataOutputStream.write(b);
+ }
+
+ @Override
+ public void write(int i) throws IOException {
+ dataOutputStream.write(i);
+ }
+ }
+}
View
2  src/main/java/org/jruby/rack/servlet/ServletRackResponseEnvironment.java
@@ -25,7 +25,7 @@
public ServletRackResponseEnvironment(HttpServletResponse response) {
super(response);
}
-
+
public void defaultRespond(RackResponse response) throws IOException {
setStatus(response.getStatus());
for (Iterator it = response.getHeaders().entrySet().iterator(); it.hasNext();) {
View
1  src/main/ruby/jruby/rack.rb
@@ -35,3 +35,4 @@ def self.booter
require 'jruby/rack/servlet_ext'
require 'jruby/rack/core_ext'
require 'jruby/rack/bundler_ext'
+require 'jruby/rack/rack_ext'
View
26 src/main/ruby/jruby/rack/rack_ext.rb
@@ -0,0 +1,26 @@
+# Servlet API friendly extensions to Rack
+# Allows for forwarding the request to another servlet/JSP
+# as well as server-side include of content generated by a servlet/JSP
+java_import org.jruby.rack.servlet.ServletRackIncludedResponse
+
+module Rack
+ class Request
+ def forward_to(path, params={})
+ servlet_request = env['java.servlet_request']
+ params.each { |k,v| servlet_request[k.to_s] = v}
+ servlet_response = env['java.servlet_response']
+ servlet_request.getRequestDispatcher(path).forward(servlet_request, servlet_response)
+ end
+
+ # Returns the output of the server-side include as a string, honoring the character
+ # encoding set on the response.
+ def render(path, params={})
+ servlet_request = env['java.servlet_request']
+ params.each { |k,v| servlet_request[k.to_s] = v}
+ servlet_response = ServletRackIncludedResponse.new(env['java.servlet_response'])
+ servlet_request.getRequestDispatcher(path).include(servlet_request, servlet_response)
+ servlet_response.getOutput
+ end
+ end
+end
+
View
14 src/main/ruby/jruby/rack/rails/extensions.rb
@@ -29,19 +29,9 @@ class Base
def servlet_request
request.env['java.servlet_request']
end
-
- def render_with_servlet_response(&block)
- if block
- @performed_render = true
- response.headers['Forward'] = block
- end
- end
-
+
def forward_to(url)
- req = servlet_request
- render_with_servlet_response do |resp|
- req.getRequestDispatcher(url).forward(req, resp)
- end
+ request.forward_to(url)
end
end
View
4 src/main/ruby/jruby/rack/response.rb
@@ -42,9 +42,7 @@ def getBody
end
def respond(response)
- if (fwd = @headers["Forward"]) && fwd.respond_to?(:call)
- fwd.call(response)
- else
+ unless response.committed?
write_status(response)
write_headers(response)
write_body(response)
View
5 src/main/ruby/rack/handler/servlet.rb
@@ -30,8 +30,8 @@ def create_lazy_env(servlet_env)
class Env
BUILTINS = %w(rack.version rack.multithread rack.multiprocess rack.run_once
- rack.input rack.errors rack.url_scheme java.servlet_request java.servlet_context
- jruby.rack.version jruby.rack.jruby.version jruby.rack.rack.release)
+ rack.input rack.errors rack.url_scheme java.servlet_request java.servlet_response
+ java.servlet_context jruby.rack.version jruby.rack.jruby.version jruby.rack.rack.release)
REQUEST = %w(CONTENT_TYPE CONTENT_LENGTH REQUEST_METHOD SCRIPT_NAME REQUEST_URI
PATH_INFO QUERY_STRING SERVER_NAME SERVER_SOFTWARE REMOTE_HOST REMOTE_ADDR REMOTE_USER SERVER_PORT)
@@ -120,6 +120,7 @@ def load_builtin(env, key)
scheme = env[key] = @servlet_env.getScheme
env['HTTPS'] = 'on' if scheme == 'https'
when 'java.servlet_request' then env[key] = @servlet_env.getRequest rescue @servlet_env
+ when 'java.servlet_response' then env[key] = @servlet_env.getResponse rescue @servlet_env
when 'java.servlet_context' then env[key] = $servlet_context
when 'jruby.rack.version' then env[key] = JRuby::Rack::VERSION
when 'jruby.rack.jruby.version' then env[key] = JRUBY_VERSION
View
4 src/spec/ruby/jruby/rack/rails_spec.rb
@@ -227,10 +227,8 @@ class << logger; attr_accessor :log; end
it "should add a #forward_to method for forwarding to another servlet" do
@servlet_response = mock "servlet response"
dispatcher = mock "dispatcher"
- @servlet_request.should_receive(:getRequestDispatcher).with("/forward.jsp").and_return dispatcher
- dispatcher.should_receive(:forward).with(@servlet_request, @servlet_response)
+ @controller.request.should_receive(:forward_to).with("/forward.jsp")
@controller.forward_to "/forward.jsp"
- @controller.response.headers['Forward'].call(@servlet_response)
end
end
View
10 src/spec/ruby/jruby/rack/response_spec.rb
@@ -100,17 +100,19 @@ class << s; undef_method :each; end if s.respond_to?(:each)
end
it "should write the status first, followed by the headers, and the body last" do
+ @servlet_response.should_receive(:committed?).and_return false
@response.should_receive(:write_status).ordered
@response.should_receive(:write_headers).ordered
@response.should_receive(:write_body).ordered
@response.respond(@servlet_response)
end
- it "should forward the request if the special 'Forward' header is present" do
- response = nil
- @headers.should_receive(:[]).with("Forward").and_return(proc {|resp| response = resp})
+ it "should not write the status, the headers, or the body if the request was forwarded" do
+ @servlet_response.should_receive(:committed?).and_return true
+ @response.should_not_receive(:write_status)
+ @response.should_not_receive(:write_headers)
+ @response.should_not_receive(:write_body)
@response.respond(@servlet_response)
- response.should == @servlet_response
end
it "#getBody should call close on the body if the body responds to close" do
View
8 src/spec/ruby/rack/handler/servlet_spec.rb
@@ -14,7 +14,8 @@
before :each do
@servlet = Rack::Handler::Servlet.new(nil)
@servlet_env = mock "servlet request"
- @env = org.jruby.rack.servlet.ServletRackEnvironment.new @servlet_env, @rack_context
+ @servlet_response = mock "servlet response"
+ @env = org.jruby.rack.servlet.ServletRackEnvironment.new @servlet_env, @servlet_response, @rack_context
@servlet_env.stub!(:getAttributeNames).and_return enumeration([])
end
@@ -311,6 +312,11 @@ def enumeration(arr)
env["HTTP_IF_MODIFIED_SINCE"].should == "today"
env["HTTP_X_SOME_REALLY_LONG_HEADER"].should == "yeap"
end
+
+ it "should return the servlet response when queried with java.servlet_response" do
+ env = @servlet.create_lazy_env @env
+ env['java.servlet_response'].should == @servlet_response
+ end
end
describe Rack::Handler::Servlet, "call" do
Something went wrong with that request. Please try again.