Class: Fishwife::RackServlet

Inherits:
HttpServlet
  • Object
show all
Defined in:
lib/fishwife/rack_servlet.rb

Overview

Wraps a Rack application in a Java servlet.

Relevant documentation:

Constant Summary collapse

ASCII_8BIT =
Encoding.find( "ASCII-8BIT" )
REQ_HIJACK_NOT_SUPPORTED =
lambda do
  raise( NotImplementedError,
         'Only response hijacking is supported, not request hijacking' )
end

Instance Method Summary collapse

Constructor Details

#initialize(app, opts = {}) ⇒ RackServlet

Returns a new instance of RackServlet.



49
50
51
52
53
54
55
56
# File 'lib/fishwife/rack_servlet.rb', line 49

def initialize( app, opts = {} )
  super()
  @log = RJack::SLF4J[ self.class ]
  @app = app
  @request_body_ram = opts[:request_body_ram] ||      256 * 1024
  @request_body_tmpdir = opts[:request_body_tmpdir] || Dir.tmpdir
  @request_body_max = opts[:request_body_max] || 8 * 1024 * 1024
end

Instance Method Details

#service(request, response) ⇒ Object

Takes an incoming request (as a Java Servlet) and dispatches it to the rack application setup via [rackup]. All this really involves is translating the various bits of the Servlet API into the Rack API on the way in, and translating the response back on the way out.



63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
# File 'lib/fishwife/rack_servlet.rb', line 63

def service(request, response)
  # Turn the ServletRequest into a Rack env hash
  env = servlet_to_rack(request)

  # Add our own special bits to the rack environment so that Rack
  # middleware can have access to the Java internals.
  env['rack.java.servlet'] = true
  env['rack.java.servlet.request'] = request
  env['rack.java.servlet.response'] = response

  rack_response = @app.call(env)
  rack_to_servlet(rack_response, request, response)
  nil
rescue RequestBodyTooLarge => e
  @log.warn( "On service: #{e.class.name}: #{e.message}" )
  response.sendError( 413 )
rescue NativeException => n
  @log.warn( "On service (native): #{n.cause.to_string}" )
  raise n.cause
rescue Exception => e
  @log.error( "On service: #{e}" )
  raise e
ensure
  fin = env && env['fishwife.input']
  fin.close if fin
end