class Ocular::Inputs::HTTP::Input
Constants
- DEFAULT_SETTINGS
- URI_INSTANCE
Attributes
routes[R]
Public Class Methods
new(settings_factory)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 574 def initialize(settings_factory) settings = settings_factory.get(:inputs)[:http] @routes = {} @settings = DEFAULT_SETTINGS.merge(settings) @stopsignal = Queue.new() @thread = nil end
Public Instance Methods
add_delete(script_name, path, options, proxy, &block)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 288 def add_delete(script_name, path, options, proxy, &block) name = generate_uri_from_names(script_name, path) route('DELETE', name, options, proxy, &block) end
add_get(script_name, path, options, proxy, &block)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 278 def add_get(script_name, path, options, proxy, &block) name = generate_uri_from_names(script_name, path) route('GET', name, options, proxy, &block) end
add_options(script_name, path, options, proxy, &block)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 293 def add_options(script_name, path, options, proxy, &block) name = generate_uri_from_names(script_name, path) route('OPTIONS', name, options, proxy, &block) end
add_post(script_name, path, options, proxy, &block)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 283 def add_post(script_name, path, options, proxy, &block) name = generate_uri_from_names(script_name, path) route('POST', name, options, proxy, &block) end
body(context, value = nil, &block)
click to toggle source
Set or retrieve the response body. When a block is given, evaluation is deferred until the body is read with each.
# File lib/ocular/inputs/http_input.rb, line 423 def body(context, value = nil, &block) if block_given? def block.each; yield(call) end context.response.body = block elsif value # Rack 2.0 returns a Rack::File::Iterator here instead of # Rack::File as it was in the previous API. unless context.request.head? headers(context).delete 'Content-Length' end context.response.body = value else context.response.body end end
build_signature(pattern, keys, &block)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 298 def build_signature(pattern, keys, &block) return [pattern, keys, block] end
call(env)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 417 def call(env) dup.call!(env) end
call!(env)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 439 def call!(env) context = WebRunContext.new context.request = Request.new(env) context.response = Response.new context.env = env context.params = indifferent_params(context.request.params) context.response['Content-Type'] = nil invoke(context) do |context| dispatch(context) end unless context.response['Content-Type'] context.response['Content-Type'] = "text/html" end context.response.finish end
call_block(context) { |context| ... }
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 505 def call_block(context) yield(context) end
compile(path)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 348 def compile(path) if path.respond_to? :to_str keys = [] # Split the path into pieces in between forward slashes. # A negative number is given as the second argument of path.split # because with this number, the method does not ignore / at the end # and appends an empty string at the end of the return value. # segments = path.split('/', -1).map! do |segment| ignore = [] # Special character handling. # pattern = segment.to_str.gsub(/[^\?\%\\\/\:\*\w]|:(?!\w)/) do |c| ignore << escaped(c).join if c.match(/[\.@]/) patt = encoded(c) patt.gsub(/%[\da-fA-F]{2}/) do |match| match.split(//).map! { |char| char == char.downcase ? char : "[#{char}#{char.downcase}]" }.join end end ignore = ignore.uniq.join # Key handling. # pattern.gsub(/((:\w+)|\*)/) do |match| if match == "*" keys << 'splat' "(.*?)" else keys << $2[1..-1] ignore_pattern = safe_ignore(ignore) ignore_pattern end end end # Special case handling. # if last_segment = segments[-1] and last_segment.match(/\[\^\\\./) parts = last_segment.rpartition(/\[\^\\\./) parts[1] = '[^' segments[-1] = parts.join end [/\A#{segments.join('/')}\z/, keys] elsif path.respond_to?(:keys) && path.respond_to?(:match) [path, path.keys] elsif path.respond_to?(:names) && path.respond_to?(:match) [path, path.names] elsif path.respond_to? :match [path, []] else raise TypeError, path end end
define_check_route()
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 607 def define_check_route pattern, keys = compile("/check") (@routes["GET"] ||= []) << build_signature(pattern, keys) do |context| [200, "OK\n"] end end
dispatch(context)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 459 def dispatch(context) invoke(context) do |context| route!(context) end rescue ::Exception => error invoke(context) do |context| handle_exception!(context, error) end ensure end
encoded(char)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 406 def encoded(char) enc = URI_INSTANCE.escape(char) enc = "(?:#{escaped(char, enc).join('|')})" if enc == char enc = "(?:#{enc}|#{encoded('+')})" if char == " " enc end
escaped(char, enc = URI_INSTANCE.escape(char))
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 413 def escaped(char, enc = URI_INSTANCE.escape(char)) [Regexp.escape(enc), URI_INSTANCE.escape(char, /./)] end
generate_uri_from_names(script_name, path)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 264 def generate_uri_from_names(script_name, path) if path[0] == "/" path = path[1..-1] end if script_name && script_name != "" name = script_name + "/" + path else name = path end return "/" + name end
handle_exception!(context, error)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 485 def handle_exception!(context, error) context.env['error'] = error if error.respond_to? :http_status context.response.status = error.http_status if error.respond_to? :to_s str = error.to_s if !str.end_with?("\n") str += "\n" end context.response.body = str end else context.response.status = 500 puts "Internal Server Error: #{error}" puts error.backtrace end end
headers(context, hash = nil)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 569 def headers(context, hash = nil) context.response.headers.merge! hash if hash context.response.headers end
indifferent_hash()
click to toggle source
Creates a Hash with indifferent access.
# File lib/ocular/inputs/http_input.rb, line 546 def indifferent_hash Hash.new {|hash,key| hash[key.to_s] if Symbol === key } end
indifferent_params(object)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 551 def indifferent_params(object) case object when Hash new_hash = indifferent_hash object.each { |key, value| new_hash[key] = indifferent_params(value) } new_hash when Array object.map { |item| indifferent_params(item) } else object end end
invoke(context) { |context| ... }
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 472 def invoke(context) res = catch(:halt) { yield(context) } if Array === res and Fixnum === res.first res = res.dup status(context, res.shift) body(context, res.pop) headers(context, *res) elsif res.respond_to? :each body(context, res) end nil # avoid double setting the same response tuple twice end
process_route(context, pattern, keys, values = []) { |self, values| ... }
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 525 def process_route(context, pattern, keys, values = []) route = context.request.path_info route = '/' if route.empty? return unless match = pattern.match(route) values += match.captures.map! { |v| URI_INSTANCE.unescape(v) if v } if values.any? original, @params = context.params, context.params.merge('splat' => [], 'captures' => values) keys.zip(values) { |k,v| Array === context.params[k] ? context.params[k] << v : context.params[k] = v if v } end yield(self, values) rescue context.env['error.params'] = context.params raise ensure @params = original if original end
route(verb, path, options, proxy, &block)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 302 def route(verb, path, options, proxy, &block) ::Ocular.logger.debug("Binding #{verb} #{path} to block #{block}") eventbase = Ocular::DSL::EventBase.new(proxy, &block) (proxy.events[verb] ||= {})[path] = eventbase pattern, keys = compile(path) (@routes[verb] ||= []) << build_signature(pattern, keys) do |context| context.event_signature = [verb, path] response = eventbase.exec(context) environment = { :path => path, :options => options, :request => context.request, :params => context.params, :env => context.env, :response => response } context.log_cause("on#{verb}", environment) response end end
route!(context)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 509 def route!(context) if routes = @routes[context.request.request_method] routes.each do |pattern, keys, block| process_route(context, pattern, keys) do |*args| #env['route'] = block.instance_variable_get(:@route_name) #throw :halt, context.exec(&block) throw :halt, call_block(context, &block) end end end puts "Route missing: #{context.request.request_method} #{context.request.path_info}" raise NotFound end
safe_ignore(ignore)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 327 def safe_ignore(ignore) unsafe_ignore = [] ignore = ignore.gsub(/%[\da-fA-F]{2}/) do |hex| unsafe_ignore << hex[1..2] '' end unsafe_patterns = unsafe_ignore.map! do |unsafe| chars = unsafe.split(//).map! do |char| char == char.downcase ? char : char + char.downcase end "|(?:%[^#{chars[0]}].|%[#{chars[0]}][^#{chars[1]}])" end if unsafe_patterns.length > 0 "((?:[^#{ignore}/?#%]#{unsafe_patterns.join()})+)" else "([^#{ignore}/?#]+)" end end
start()
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 584 def start() if @settings[:verbose] @app = Rack::CommonLogger.new(@app, STDOUT) end ::Ocular.logger.debug "Puma HTTP server started with settings #{@settings}" @thread = Thread.new do events_hander = @settings[:silent] ? ::Puma::Events.strings : ::Puma::Events.stdio server = ::Puma::Server.new(self, events_hander) server.add_tcp_listener @settings[:host], @settings[:port] server.min_threads = 0 server.max_threads = 16 server.run @stopsignal.pop server.stop(true) end define_check_route() end
status(context, value = nil)
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 564 def status(context, value = nil) context.response.status = value if value context.response.status end
stop()
click to toggle source
# File lib/ocular/inputs/http_input.rb, line 615 def stop() @stopsignal << "EXIT" @thread.join end