class Webservice::Metal
Attributes
env[R]
params[R]
request[R]
response[R]
Public Class Methods
call( env )
click to toggle source
# File lib/webservice/metal.rb, line 139 def call( env ) ## note self.call(env) lets you use => run Base instead of run Base.new ## puts "calling #{self.name}.call" prototype.call( env ) end
delete( pattern, &block)
click to toggle source
# File lib/webservice/metal.rb, line 165 def delete( pattern, &block) route( DELETE, pattern, &block ); end
development?()
click to toggle source
# File lib/webservice/metal.rb, line 186 def development?() environment == :development; end
environment()
click to toggle source
# File lib/webservice/metal.rb, line 180 def environment ## include APP_ENV why? why not? ## todo -- cache value? why why not? (see/follow sinatara set machinery ??) (ENV['APP_ENV'] || ENV['RACK_ENV'] || :development).to_sym end
get( pattern, &block )
click to toggle source
Note: for now defining a `GET` handler also automatically defines a `HEAD` handler (follows sinatra convention)
# File lib/webservice/metal.rb, line 157 def get( pattern, &block ) route( GET, pattern, &block ) route( HEAD, pattern, &block ) end
head( pattern, &block)
click to toggle source
# File lib/webservice/metal.rb, line 166 def head( pattern, &block) route( HEAD, pattern, &block ); end
options( pattern, &block)
click to toggle source
# File lib/webservice/metal.rb, line 167 def options( pattern, &block) route( OPTIONS, pattern, &block ); end
patch( pattern, &block)
click to toggle source
# File lib/webservice/metal.rb, line 163 def patch( pattern, &block) route( PATCH, pattern, &block ); end
post( pattern, &block)
click to toggle source
# File lib/webservice/metal.rb, line 162 def post( pattern, &block) route( POST, pattern, &block ); end
production?()
click to toggle source
# File lib/webservice/metal.rb, line 187 def production?() environment == :production; end
prototype()
click to toggle source
# File lib/webservice/metal.rb, line 144 def prototype ## puts "calling #{self.name}.prototype" @prototype ||= self.new ## pp @prototype ## @prototype end
put( pattern, &block)
click to toggle source
# File lib/webservice/metal.rb, line 164 def put( pattern, &block) route( PUT, pattern, &block ); end
route( method, pattern, &block )
click to toggle source
# File lib/webservice/metal.rb, line 169 def route( method, pattern, &block ) puts "[debug] Webservice::Metal.#{method.downcase} - add route #{method} '#{pattern}' to #<#{self.name}:#{self.object_id}> : #{self.class.name}" ## note: for now use (default to) the sintatra-style patterns (with mustermann) routes[method] << [Mustermann::Sinatra.new(pattern), block] end
routes()
click to toggle source
# File lib/webservice/metal.rb, line 176 def routes @routes ||= Hash.new { |hash, key| hash[key]=[] } end
run!()
click to toggle source
convenience method
# File lib/webservice/metal.rb, line 191 def run! puts "[debug] Webservice::Metal.run! - self = #<#{self.name}:#{self.object_id}> : #{self.class.name}" # note: assumes self is class app = self ## note: use self; will be derived class (e.g. App and not Base) port = 4567 Rack::Handler::WEBrick.run( app, Port:port ) do |server| ## todo: add traps here - why, why not?? end end
test?()
click to toggle source
# File lib/webservice/metal.rb, line 188 def test?() environment == :test; end
Public Instance Methods
call( env )
click to toggle source
# File lib/webservice/metal.rb, line 208 def call( env ) dup.call!( env ) end
call!( env )
click to toggle source
# File lib/webservice/metal.rb, line 212 def call!( env ) env['PATH_INFO'] = '/' if env['PATH_INFO'].empty? @request = Rack::Request.new( env ) @response = Rack::Response.new @params = request.params @env = env catch(:halt) do ## call before if defined in derived (sub)classes before if respond_to? :before route! end @response.finish end
halt( *args )
click to toggle source
# File lib/webservice/metal.rb, line 231 def halt( *args ) response.status = args.detect{ |arg| arg.is_a?(Fixnum) } || 200 response.header.merge!( args.detect{ |arg| arg.is_a?(Hash) } || {} ) response.body = [args.detect{ |arg| arg.is_a?(String) } || ''] throw :halt, response ## todo/check response arg used - what for?? end
Private Instance Methods
route!( base=self.class )
click to toggle source
# File lib/webservice/metal.rb, line 259 def route!( base=self.class ) puts " [#{base.name}] try matching route >#{request.request_method} #{request.path_info}<..." routes = base.routes[ request.request_method ] routes.each do |pattern, block| ## puts "trying matching route >#{request.path_info}<..." url_params = pattern.params( request.path_info ) if url_params ## note: params returns nil if no match ## puts " BINGO! url_params: #{url_params.inspect}" if !url_params.empty? ## url_params hash NOT empty (e.g. {}) merge with req params ## todo/fix: check merge order - params overwrites url_params - why? why not?? ## todo/fix: check params - params works with string keys only - check for indiffent keys - why? why not? ## check rack params - works with indifferent keys by default?? @params = url_params.merge( @params ) end route_eval( &block ) ## todo/check: keep return - why? why not? - note: route_eval will always throw :halt ## handler.handle_response( instance_eval( &block )) ## return end end ## check recursive - all super(parent)classes too (e.g. App > Base > Metal etc.) ## note: superclass is the parent class (returns nil if no more parent class) if base.superclass.respond_to? :routes route!( base.superclass ) return end # no match found for route/request halt 404 end
route_eval( &block )
click to toggle source
run a route block and throw :halt
# File lib/webservice/metal.rb, line 242 def route_eval( &block ) obj = instance_eval( &block ) ## return result - for now assumes a single object if respond_to? :handle_response handle_response( obj ) ## prepare response else ## default response; string expected ## if string pass it along ## if NOT string for debugging / dump to string with inspect response.status = 200 response.body = [obj.is_a?(String) ? obj.to_s : obj.inspect] end throw :halt end