class Soybean::Engine
Public Class Methods
inherited(subclass)
click to toggle source
# File lib/soybean/engine.rb, line 11 def self.inherited(subclass) Soybean.engines << subclass end
new(app = nil)
click to toggle source
# File lib/soybean/engine.rb, line 116 def initialize(app = nil) @app = app setup!(self.class.service) end
Public Instance Methods
call(env)
click to toggle source
# File lib/soybean/engine.rb, line 135 def call(env) s, h, b = with_logging(env, logger) do handle(env) end return s, h, b rescue => e [200, {'Allow' => 'POST', 'Content-Type' => 'text/xml'}, [e.message, e.backtrace.join("\n")]] end
handle(env)
click to toggle source
# File lib/soybean/engine.rb, line 177 def handle(env) # yeah, all soap calls are over POST if env['REQUEST_METHOD'] != 'POST' return 405, { 'Allow' => 'POST', 'Content-Type' => 'text/plain'}, ["405 - Method Not Allowed"] 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/soybean/engine.rb, line 225 def parse_soapaction(soapaction) if !soapaction.nil? and !soapaction.empty? if /\A"(.+)"\z/ =~ soapaction return $1 end end nil end
setup!(service)
click to toggle source
# File lib/soybean/engine.rb, line 121 def setup!(service) self.class.setup {} service.class::Methods.each do |definitions| opt = definitions.last if opt[:request_style] == :document self.class.router.add_document_operation(service, *definitions) else self.class.router.add_rpc_operation(service, *definitions) end end self.class.mapping_registry = Mappings::EncodedRegistry self.class.literal_mapping_registry = Mappings::LiteralRegistry end
setup_request(conn_data, env)
click to toggle source
# File lib/soybean/engine.rb, line 194 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/soybean/engine.rb, line 204 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
with_logging(env, logger) { || ... }
click to toggle source
# File lib/soybean/engine.rb, line 146 def with_logging(env, logger) request = Rack::Request.new(env) input_params = request.body.read request.body.rewind logger.info "Started %s \"%s\" for %s at %s. caller %s" % [request.request_method, URI(env['REQUEST_URI']).path, request.ip, Time.now.strftime("%Y-%m-%d %H:%M:%S"), request.referer] if logger logger.info " Processing by %s" % [self.class.service.class.name] if logger logger.debug " Request: " if logger logger.debug pretty_xml(input_params, ' ') if logger s, h, b = yield logger.debug " Response:" % [h.inspect] if logger logger.debug " Headers: %s" % [h.inspect] if logger logger.debug " Body: " if logger logger.debug pretty_xml(b.join, ' ') if logger return s, h, b rescue => e logger.error "\tERROR: \n%s" % [e.message] if logger raise e end
Protected Instance Methods
pretty_xml(string, ident=' ')
click to toggle source
# File lib/soybean/engine.rb, line 235 def pretty_xml(string, ident=' ') Nokogiri.XML(string) { |config| config.default_xml.noblanks }.to_xml(ident: 2).each_line.map do |line| "#{ident}#{line}" end.join rescue string end