module Soap4r::Middleware

Constants

VERSION

Public Class Methods

included(klass) click to toggle source
# File lib/soap4r-middleware.rb, line 7
def self.included(klass)
  klass.send(:extend, ::Soap4r::Middleware::ClassMethods)
end
new(app = nil) click to toggle source
# File lib/soap4r-middleware.rb, line 11
def initialize(app = nil)
  @app = app
end

Public Instance Methods

call(env) click to toggle source
# File lib/soap4r-middleware.rb, line 15
def call(env)
  if env['PATH_INFO'].match(self.class.endpoint)
    handle(env)
  else
    # we can act as both a middleware and an app
    @app ?
      @app.call(env) :
      [ 404, { "Content-Type" => "text/html" }, ["Not Found"] ]
  end
end
handle(env) click to toggle source
# File lib/soap4r-middleware.rb, line 26
def handle(env)
  # yeah, all soap calls are over POST
  if env['REQUEST_METHOD'] != 'POST'
    return 405, { 'Content-Length' => '0',
      'Allow' => 'POST',
      'Content-Type' => 'text/plain' }, []
  end

  conn_data = ::SOAP::StreamHandler::ConnectionData.new
  setup_request(conn_data, env)
  conn_data = self.class.router.route(conn_data)
  status, headers, body = setup_response(conn_data, env)
  [ status, headers, body ]
rescue
  raise # TODO -- do we 500 right here, or let the exception bubble up?
end
parse_soapaction(soapaction) click to toggle source
# File lib/soap4r-middleware.rb, line 74
def parse_soapaction(soapaction)
  if !soapaction.nil? and !soapaction.empty?
    if /\A"(.+)"\z/ =~ soapaction
      return $1
    end
  end
  nil
end
setup_request(conn_data, env) click to toggle source
# File lib/soap4r-middleware.rb, line 43
def setup_request(conn_data, env)
  # TODO: we're reading the whole input here, which kind of stinks if rack is
  # reading from the client on demand. We can't just pass in the rack input
  # object, since REXML needs an IO that responds to :eof? -- we'd need a
  # wrapper IO-like object.
  conn_data.receive_string = env['rack.input'].read
  conn_data.receive_contenttype = env['CONTENT_TYPE']
  conn_data.soapaction = parse_soapaction(env['HTTP_SOAPAction'])
end
setup_response(conn_data, env) click to toggle source
# File lib/soap4r-middleware.rb, line 53
def setup_response(conn_data, env)
  status = 200
  headers = {}
  body = []
  headers['content-type'] = conn_data.send_contenttype
  # TODO: cookies?
  if conn_data.is_nocontent
    status = 202 # ACCEPTED
  elsif conn_data.is_fault
    # rather than sending the 500 here, let's bubble up the exception so the
    # parent application can do with it what it will. The only downside is
    # soap4r has already converted the exception into a soap response body at
    # this point, which isn't what we want at all.
    # maybe someday i'll re-parse the response or something. but not today.
    raise conn_data.send_string
  else
    body << conn_data.send_string
  end
  return status, headers, body
end