class Blix::Rest::Controller

base class for controllers. within your block handling a particular route you have access to a number of methods

env : the request environment hash body : the request body as a string body_hash : the request body as a hash constructed from json query_params : a hash of parameters as passed in the url as parameters path_params : a hash of parameters constructed from variable parts of the path params : all the params combined user : the user making this request ( or nil if format : the format the response should be in :json or :html session : the rack session if middleware has been used

to accept requests other thatn json then set :accept=>[:json,:html] as options in the route
  eg  post '/myform' :accept=>[:html]              # this will only accept html requests.

Constants

ESCAPE_HTML

the following is copied from Rack::Utils

ESCAPE_HTML_PATTERN
JS_ESCAPE_MAP

Public Class Methods

__erb_path() click to toggle source

default method .. will be overridden with erb_path method

# File lib/blix/rest/controller.rb, line 431
def __erb_path
  nil
end
all(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 493
def all(*a, &b)
  route 'ALL', *a, &b
end
check_format(accept, format) click to toggle source
# File lib/blix/rest/controller.rb, line 441
def check_format(accept, format)
  return if (format == :json) && accept.nil?  # the majority of cases
  return if (format == :_) && accept.nil?     # assume json by default.

  accept ||= :json
  accept = [accept].flatten
  raise ServiceError, 'invalid format for this request' unless accept.index format
end
delete(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 489
def delete(*a, &b)
  route 'DELETE', *a, &b
end
erb_dir(val) click to toggle source

redefine the __erb_path method for this and derived classes

# File lib/blix/rest/controller.rb, line 436
def erb_dir(val)
  str = "def self.__erb_path;\"#{val}\";end"
  class_eval str
end
erb_root() click to toggle source
# File lib/blix/rest/controller.rb, line 362
def self.erb_root
  @_erb_root ||= begin
    root = File.join(Dir.pwd, 'app', 'views')
    raise('use set_erb_root() to specify the location of your views') unless Dir.exist?(root)

    root
  end
end
erb_templates() click to toggle source

cache templates here

# File lib/blix/rest/controller.rb, line 354
def self.erb_templates
  @_erb ||= {}
end
get(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 469
def get(*a, &b)
  route 'GET', *a, &b
end
head(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 473
def head(*a, &b)
  route 'HEAD', *a, &b
end
new(path_params, _params, req, format, verb, response, server_options) click to toggle source
# File lib/blix/rest/controller.rb, line 332
def initialize(path_params, _params, req, format, verb, response, server_options)
  @_req = req
  @_env = req.env
  @_query_params = StringHash.new(req.GET)
  @_path_params  = StringHash.new(path_params)
  @_format = format
  @_verb = verb
  @_response = response
  @_server_options = server_options
end
no_template_cache() click to toggle source

do not cache templates in development mode

# File lib/blix/rest/controller.rb, line 344
def self.no_template_cache
  @_no_template_cache = (Blix::Rest.environment != 'production') if @_no_template_cache.nil?
  @_no_template_cache
end
no_template_cache=(val) click to toggle source
# File lib/blix/rest/controller.rb, line 349
def self.no_template_cache=(val)
  @_no_template_cache = val
end
options(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 497
def options(*a, &b)
  route 'OPTIONS', *a, &b
end
patch(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 485
def patch(*a, &b)
  route 'PATCH', *a, &b
end
post(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 477
def post(*a, &b)
  route 'POST', *a, &b
end
put(*a, &b) click to toggle source
# File lib/blix/rest/controller.rb, line 481
def put(*a, &b)
  route 'PUT', *a, &b
end
render(text, context, opts = {}) click to toggle source

render a string within a layout.

# File lib/blix/rest/controller.rb, line 374
def render(text, context, opts = {})
  layout_name = opts[:layout]
  path        = opts[:path] || __erb_path || Controller.erb_root

  layout = layout_name && if no_template_cache
                            ERB.new(File.read(File.join(path, layout_name + '.html.erb')),nil,'-')
                          else
                            erb_templates[layout_name] ||= ERB.new(File.read(File.join(path, layout_name + '.html.erb')),nil,'-')
  end

  begin
    if layout
      layout.result(context._get_binding { |*_args| text })
    else
      text
    end
  rescue Exception
    puts $!
    puts $@
    '*** TEMPLATE ERROR ***'
  end
end
render_erb(name, context, opts = {}) click to toggle source
# File lib/blix/rest/controller.rb, line 397
def render_erb(name, context, opts = {})
  name        = name.to_s
  layout_name = opts[:layout] && opts[:layout].to_s
  locals      = opts[:locals]
  path        = opts[:erb_dir] || __erb_path || Controller.erb_root

  layout = layout_name && if no_template_cache
                            ERB.new(File.read(File.join(path, layout_name + '.html.erb')),nil,'-')
                          else
                            erb_templates[layout_name] ||= ERB.new(File.read(File.join(path, layout_name + '.html.erb')),nil,'-')
  end

  erb = if no_template_cache
          ERB.new(File.read(File.join(path, name + '.html.erb')),nil,'-')
        else
          erb_templates[name] ||= ERB.new(File.read(File.join(path, name + '.html.erb')),nil,'-')
  end

  begin
    bind = context._get_binding
    locals&.each { |k, v| bind.local_variable_set(k, v) } # works from ruby 2.1
    if layout
      layout.result(context._get_binding { |*_args| erb.result(bind) })
    else
      erb.result(bind)
    end
  rescue Exception
    puts $!
    puts $@
    '*** TEMPLATE ERROR ***'
  end
end
route(verb, path, opts = {}, &blk) click to toggle source
# File lib/blix/rest/controller.rb, line 450
def route(verb, path, opts = {}, &blk)
  proc = lambda do |_path_params, _params, _req, _format, _response, server_options|
    unless opts[:force] && (opts[:accept] == :*)
      check_format(opts[:accept], _format)
    end
    app = new(_path_params, _params, _req, _format, verb, _response, server_options)
    begin
      app.before(opts)
      response = app.instance_eval( &blk )
    rescue
      raise
    ensure
      app.after(opts, response)
    end
  end

  RequestMapper.add_path(verb.to_s.upcase, path, opts, &proc)
end
set_erb_root(dir) click to toggle source
# File lib/blix/rest/controller.rb, line 358
def self.set_erb_root(dir)
  @_erb_root = dir
end

Public Instance Methods

_get_binding() click to toggle source
# File lib/blix/rest/controller.rb, line 172
def _get_binding
  binding
end
_opt(opts,key) click to toggle source
# File lib/blix/rest/controller.rb, line 305
def  _opt(opts,key)
  if opts.key?(key.to_sym)
    opts[key.to_sym]
  else
    opts[key.to_s]
  end
end
_opt?(opts,key) click to toggle source
# File lib/blix/rest/controller.rb, line 301
def _opt?(opts,key)
  opts.key?(key.to_sym) || opts.key?(key.to_s)
end
add_headers(headers) click to toggle source
# File lib/blix/rest/controller.rb, line 197
def add_headers(headers)
  @_response.headers.merge!(headers)
end
after(_opts, response) click to toggle source

a hook used to insert processing for after the method call. return a hash containing the response.

# File lib/blix/rest/controller.rb, line 326
def after(_opts, response)
  response
end
auth_error(*params) click to toggle source
# File lib/blix/rest/controller.rb, line 234
def auth_error(*params)
  if params[0].kind_of?(String)
      message = params[0]
      opts = params[1] || {}
  else
      message = nil
      opts = params[-1] || {}
  end
  raise AuthorizationError.new(message,opts[:realm], opts[:type])
end
before(opts) click to toggle source

a hook used to insert processing for before the method call

# File lib/blix/rest/controller.rb, line 322
def before(opts); end
body() click to toggle source
# File lib/blix/rest/controller.rb, line 58
def body
  @_body ||= env['rack.input'].read
  #      env['rack.input'].rewindreq.POST #env["body"]
end
body_hash() click to toggle source
# File lib/blix/rest/controller.rb, line 71
def body_hash
  @_body_hash ||= if body.empty?
                    {}
                  else
                    # should we check the content type here?
                    begin
                      StringHash.new(MultiJson.load(body))
                    rescue StandardError
                      raise ServiceError, "error in data json format/#{body}/"
                    end
  end
end
env() click to toggle source
# File lib/blix/rest/controller.rb, line 29
def env
  @_env
end
escape_javascript(javascript) click to toggle source

escape javascript

# File lib/blix/rest/controller.rb, line 221
def escape_javascript(javascript)
  if javascript
    javascript.gsub(%r{(\|</|\r\n|\342\200\250|\342\200\251|[\n\r"'])}u) { |match| JS_ESCAPE_MAP[match] }
  else
    ''
  end
end
form_hash() click to toggle source
# File lib/blix/rest/controller.rb, line 67
def form_hash
  StringHash.new(req.POST)
end
format() click to toggle source
# File lib/blix/rest/controller.rb, line 88
def format
  @_format
end
full_path(path) click to toggle source

add on the root path

# File lib/blix/rest/controller.rb, line 140
def full_path(path)
  RequestMapper.full_path(path)
end
full_url(_path) click to toggle source

the full url of this path.

# File lib/blix/rest/controller.rb, line 145
def full_url(_path)
  raise 'not yet implemented'
end
get_basic_auth(realm=nil) click to toggle source

extract the user and login from the basic authentication

# File lib/blix/rest/controller.rb, line 177
def get_basic_auth(realm=nil)
  data = env['HTTP_AUTHORIZATION']
  raise AuthorizationError.new('authentication missing',realm) unless data

  type = data[0, 5]
  rest = data[6..-1]

  raise  AuthorizationError.new('wrong authentication method',realm) unless type == 'Basic'
  raise  AuthorizationError.new('username:password missing',realm)   unless rest

  auth_parts = Base64.decode64(rest).split(':')
  login = auth_parts[0]
  password = auth_parts[1]
  [login, password]
end
get_data(field) click to toggle source
# File lib/blix/rest/controller.rb, line 84
def get_data(field)
  body_hash['data'] && body_hash['data'][field]
end
get_session_id(session_name, opts = {}) click to toggle source

manage session handling ————————————————– setup the session and retrieve the session_id this id can be used to retrieve and data associated with the session_id in eg: a database or a memory hash

# File lib/blix/rest/controller.rb, line 290
def get_session_id(session_name, opts = {})
  session_id = get_cookie(session_name)
  session_id || refresh_session_id(session_name, opts)
end
h(string) click to toggle source

Escape ampersands, brackets and quotes to their HTML/XML entities.

# File lib/blix/rest/controller.rb, line 216
def h(string)
  string.to_s.gsub(ESCAPE_HTML_PATTERN) { |c| ESCAPE_HTML[c] }
end
logger() click to toggle source
# File lib/blix/rest/controller.rb, line 38
def logger
  Blix::Rest.logger
end
method() click to toggle source
# File lib/blix/rest/controller.rb, line 131
def method
  env['REQUEST_METHOD'].downcase
end
mode_development?() click to toggle source
# File lib/blix/rest/controller.rb, line 50
def mode_development?
  rack_env == 'development'
end
mode_production?() click to toggle source
# File lib/blix/rest/controller.rb, line 54
def mode_production?
  rack_env == 'production'
end
mode_test?() click to toggle source
# File lib/blix/rest/controller.rb, line 46
def mode_test?
  rack_env == 'test'
end
params() click to toggle source
# File lib/blix/rest/controller.rb, line 100
def params
  @_params ||= StringHash.new(@_query_params,@_path_params)
end
path() click to toggle source
# File lib/blix/rest/controller.rb, line 63
def path
  req.path
end
path_for(path) click to toggle source
# File lib/blix/rest/controller.rb, line 115
def path_for(path)
  File.join(RequestMapper.path_root, path)
end
path_params() click to toggle source
# File lib/blix/rest/controller.rb, line 96
def path_params
  @_path_params
end
post_params() click to toggle source
# File lib/blix/rest/controller.rb, line 104
def post_params
  @_post_params ||= begin
    type = req.media_type
    if type && Rack::Request::FORM_DATA_MEDIA_TYPES.include?(type)
      form_hash
    else
      body_hash
    end
  end
end
query_params() click to toggle source
# File lib/blix/rest/controller.rb, line 92
def query_params
  @_query_params
end
rack_env() click to toggle source
# File lib/blix/rest/controller.rb, line 42
def rack_env
  ENV['RACK_ENV']
end
rawjson(str) click to toggle source
# File lib/blix/rest/controller.rb, line 168
def rawjson(str)
  RawJsonString.new(str)
end
redirect(path, status = 302) click to toggle source
# File lib/blix/rest/controller.rb, line 149
def redirect(path, status = 302)
  raise ServiceError.new(nil, status, 'Location' => path)
end
Also aliased as: redirect_to
redirect_to(path, status = 302)
Alias for: redirect
refresh_session_id(session_name, opts = {}) click to toggle source

generate an new session_id for the current session

# File lib/blix/rest/controller.rb, line 296
def refresh_session_id(session_name, opts = {})
  session_id = SecureRandom.hex(32)
  store_session_id(session_name, session_id, opts)
end
render(text, opts = {}) click to toggle source
# File lib/blix/rest/controller.rb, line 164
def render(text, opts = {})
  self.class.render_erb(text, self, opts)
end
render_erb(template_name, opts = {}) click to toggle source

render an erb template with the variables in the controller

# File lib/blix/rest/controller.rb, line 160
def render_erb(template_name, opts = {})
  self.class.render_erb(template_name, self, opts)
end
req() click to toggle source
# File lib/blix/rest/controller.rb, line 123
def req
  @_req
end
request_ip() click to toggle source
# File lib/blix/rest/controller.rb, line 155
def request_ip
  req.ip
end
send_error(message, status = nil, headers = nil) click to toggle source

send a (default) error

# File lib/blix/rest/controller.rb, line 230
def send_error(message, status = nil, headers = nil)
  raise ServiceError.new(message, status, headers)
end
server_options() click to toggle source

options that were passed to the server at create time.

# File lib/blix/rest/controller.rb, line 34
def server_options
  @_server_options
end
session() click to toggle source
# File lib/blix/rest/controller.rb, line 135
def session
  req.session
end
set_status(value) click to toggle source
# File lib/blix/rest/controller.rb, line 193
def set_status(value)
  @_response.status = value
end
store_session_id(session_name, session_id, opts = {}) click to toggle source

set the cookie header that stores the session_id on the browser.

# File lib/blix/rest/controller.rb, line 314
def store_session_id(session_name, session_id, opts = {})
  store_cookie(session_name, session_id, opts)
end
url_for(path) click to toggle source
# File lib/blix/rest/controller.rb, line 119
def url_for(path)
  req.base_url + path_for(path)
end
verb() click to toggle source
# File lib/blix/rest/controller.rb, line 127
def verb
  @_verb
end