Module: PrestoHTTP::Config

Includes:
PrestoCore::Utils
Included in:
ClassAPI, Slice
Defined in:
lib/presto/http/config.rb

Overview

Note:

configs here are set by both controller and slice

Note:

methods here used to setup the HTTP API. to have an consistent setup, it should be write-able only at class definition. any later updates should be prohibited. to accomplish this, any updates for mounted controller are silently dropped.

Constant Summary

Constant Summary

Constants included from PrestoCore::Utils

PrestoCore::Utils::PATH_MODIFIERS, PrestoCore::Utils::STATUS__NOT_FOUND, PrestoCore::Utils::STATUS__OK, PrestoCore::Utils::STATUS__PERMANENT_REDIRECT, PrestoCore::Utils::STATUS__REDIRECT, PrestoCore::Utils::STATUS__RESTRICTED, PrestoCore::Utils::STATUS__SERVER_ERROR

Instance Attribute Summary (collapse)

Instance Method Summary (collapse)

Methods included from PrestoCore::Utils

build_path, #extract_controllers, is_controller?, normalize_path, rootify_url

Instance Attribute Details

- (Object) cache_pool(pool = nil)

by default, Presto will use an in memory cache pool. it is well and fast as long as your content fit into available RAM. to keep memory low, consider to use some fast key/value db.

Examples:

use mongodb as cache pool:

db = Mongo::Connection.new.db(:cache)
http.cache_pool ::PrestoCache::MongoDB.new db

Parameters:

  • pool (defaults to: nil)


345
346
347
348
349
350
# File 'lib/presto/http/config.rb', line 345

def cache_pool pool = nil
  @cache_pool = pool if pool && configurable?
  @setup[:cache_pool] ||= @cache_pool ||
      (@controller.ctrl.slice.http.cache_pool if @controller) ||
      ::Presto.setup.http.cache_pool
end

- (String) content_type(*actions, &proc) Also known as: provide

content type to be returned by action(s). default is text/html

Examples:

http.content_type { |action| http.mime_type( ".js" ) }
# all actions will return text/javascript

http.content_type :feed { |a| http.mime_type( ".rss" ) }
# feed will return application/rss+xml

Parameters:

  • actions (Array)
  • proc (Proc)

Returns:

  • (String)


84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/presto/http/config.rb', line 84

def content_type *actions, &proc

  if proc && configurable?
    actions = [:*] if actions.size == 0
    actions.each { |a| @content_type[a] = proc }
  end

  action = actions.first
  @setup['content_type::%s' % action] ||= @content_type[action] ||
      @content_type[:*] ||
      (@controller.ctrl.slice.http.content_type(action) if @controller)
end

- (Object) middleware

each controller may have own middleware.

Examples:

http.use SomeMiddleware, :with, some: :args

Parameters:

  • ware (Class)
  • args (Array)
  • proc (Proc)


360
361
362
# File 'lib/presto/http/config.rb', line 360

def middleware
  @middleware
end

- (Object) path_rules(rules = nil)

Note:

# default rules

- "__"   (2 underscores) => "-" (dash)
- "___"  (3 underscores) => "/" (slash)
- "____" (4 underscores) => "." (period)

allow app to define its own rewriting rules for method names. each method are translated into its path representation.

return [Hash, nil]

Examples:

define custom rules

http.path_rules  "__" => "/",
                 "__dash__" => "-",
                 "__dot__" => "."

def some__dash__action__dot__html
  # will resolve to /some-action.html
end

Parameters:

  • rules (Hash) (defaults to: nil)


135
136
137
138
139
140
# File 'lib/presto/http/config.rb', line 135

def path_rules rules = nil
  @path_rules = rules.freeze if rules && configurable?
  @setup[:path_rules] ||= @path_rules ||
      (@controller.ctrl.slice.http.path_rules if @controller) ||
      ::Presto.setup.http.path_rules
end

- (Object) rewrite_rules (readonly)

Returns the value of attribute rewrite_rules



15
16
17
# File 'lib/presto/http/config.rb', line 15

def rewrite_rules
  @rewrite_rules
end

Instance Method Details

- (Object) after(*actions, &proc)

hooks to be executed before/after given action(s) or before/after any action if no actions given.

Examples:

http.before { puts "will be executed before each action" }
http.before(:index) { puts "will be executed only before :index" }

Parameters:

  • actions (Array)
  • proc (Proc)


46
47
48
49
50
51
52
# File 'lib/presto/http/config.rb', line 46

def after *actions, &proc
  if proc && configurable?
    actions = [:*] if actions.size == 0
    actions.each { |a| @hooks_z[a] = proc } if proc
  end
  @hooks_z
end

- (Object) auth(*actions_and_or_opts, &proc)

making some actions, or all, to require authorization.

Examples:

restricting all actions:

http.auth do |user, pass|
  # some validation logic
end

restricting only #edit action:

http.auth :edit do |u,p|
  # some validation logic
end

restricting only #edit and #delete actions:

http.auth :edit, :delete do |u,p|
  # some validation logic
end

digest auth:

realm = 'AccessRestricted'
http.digest_auth realm: realm  do |user|
  # hash the password somewhere in irb:
  # ::Digest::MD5.hexdigest ['user', realm, 'somePassword'] * ':'
  # the hash used below is obtained from:
  # ::Digest::MD5.hexdigest ['admin', realm, 'pwd'] * ':'
  {
      'admin' => '9d77d54decc22cdcfb670b7b79ee0ef0'
  }[user]
end

plain password

http.digest_auth plain: true do |user|
  # Note! it is strongly discouraged to put here plain passwords.
  # use :plain only if your password are stored encrypted with an private key,
  # which also should NOT be kept in source code.
  {
      'admin' => some_logic_that_decrypt_password_into_plaintext()
  }[user]
end

html auth storing data in sessions

http.html_auth pool: :session do |user|
  {'admin' => 'md5 hash of your password'}[user]
end

html auth storing data in custom pool

http.html_auth pool: ::PrestoCache::MongoDB.new(protected_mongodb_database) do |user|
  {'admin' => 'md5 hash of your password'}[user]
end

Parameters:

  • actions_and_or_opts
  • &proc (Proc)


256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
# File 'lib/presto/http/config.rb', line 256

def auth *actions_and_or_opts, &proc

  if proc && configurable? # prohibit updates after controller mounted

    actions, opts = [], {}
    actions_and_or_opts.each { |arg| arg.is_a?(Hash) ? opts.update(arg) : actions << arg }
    if opted_type = opts[:type]
      AUTHORIZATION_TYPES.include?(opted_type.to_s) ||
          raise('%s is an unknown auth type, please use one of :%s' % [opted_type.inspect, AUTHORIZATION_TYPES.join(', :')])
    end
    opts[:proc] = proc

    actions = [:*] if actions.size == 0
    actions.each { |a| @restrictions[a] = opts.merge(action: a) }
  end

  action = actions_and_or_opts.first
  @setup['%s::%s' % [:auth, action]] ||= @restrictions[action] ||
      @restrictions[:*] ||
      (@controller.ctrl.slice.http.auth(action) if @controller)
end

- (Object) basic_auth(*args, &proc)



278
279
280
# File 'lib/presto/http/config.rb', line 278

def basic_auth *args, &proc
  auth *args, type: :Basic, &proc
end

- (Object) before(*actions, &proc)

hooks to be executed before/after given action(s) or before/after any action if no actions given.

Examples:

http.before { puts "will be executed before each action" }
http.before(:index) { puts "will be executed only before :index" }

Parameters:

  • actions (Array)
  • proc (Proc)


37
38
39
40
41
42
43
# File 'lib/presto/http/config.rb', line 37

def before *actions, &proc
  if proc && configurable?
    actions = [:*] if actions.size == 0
    actions.each { |a| @hooks_a[a] = proc } if proc
  end
  @hooks_a
end

- (Object) cache(*actions, &proc)

Note:

if no actions given, all actions will use same setup.

Note:

block is required, cause it is a bad idea to leave cache out of control.

Note:

http hooks WILL BE EVER executed regardless cache.

setting some actions(or all) to use cache.

given block will be used to decide which requests will use cache and which will not.

  • if block returns any positive value, cache will be returned

  • if block returns :update [Symbol], cache will be updated then returned

otherwise a fresh version of action will be returned.

Examples:

caching all actions:


# callback receiving back the current action and its arguments.
http.cache do |action, *arguments|
  cache = true
  cache = false if http.query_string =~ /no_cache/
  cache = :update if http.query_string =~ /update_cache/
  #and so on
  cache
end

caching #static action:


http.cache :static do |action, *arguments|
  true
end

Parameters:

  • actions (Array)
  • proc (Proc)


323
324
325
326
327
328
329
330
331
332
333
334
# File 'lib/presto/http/config.rb', line 323

def cache *actions, &proc

  if proc && configurable? # prohibit updates after controller mounted
    actions = [:*] if actions.size == 0
    actions.each { |a| @cache[a] = proc }
  end

  action = actions.first
  @setup['%s::%s' % [:cache, action]] ||= @cache[action] ||
      @cache[:*] ||
      (@controller.ctrl.slice.http.cache(action) if @controller)
end

- (Object) digest_auth(*args, &proc)



282
283
284
# File 'lib/presto/http/config.rb', line 282

def digest_auth *args, &proc
  auth *args, type: :Digest, &proc
end

- (Object) encoding(*actions, &proc) Also known as: charset



99
100
101
102
103
104
105
106
107
108
109
110
# File 'lib/presto/http/config.rb', line 99

def encoding *actions, &proc

  if proc && configurable?
    actions = [:*] if actions.size == 0
    actions.each { |a| @encoding[a] = proc }
  end

  action = actions.first
  @setup['encoding::%s' % action] ||= @encoding[action] ||
      @encoding[:*] ||
      (@controller.ctrl.slice.http.encoding(action) if @controller)
end

- (Object) error(code, &proc)

define callbacks to be executed on HTTP errors.

Examples:

handle 404 errors:

class App
  # ...
  http.error 404 do |message|
    view.render_layout(:layout_404) { message }
  end
end

Parameters:

  • code (Integer)
  • proc (Proc)


64
65
66
67
68
69
70
# File 'lib/presto/http/config.rb', line 64

def error code, &proc
  if proc && configurable? # prohibit updates after controller mounted
    @error_procs[code] = proc
  end
  @setup['%s::%s' % [:error_procs, code]] ||= @error_procs[code] ||
      (@controller.ctrl.slice.http.error(code) if @controller)
end

- (Object) html_auth(*args, &proc)



286
287
288
# File 'lib/presto/http/config.rb', line 286

def html_auth *args, &proc
  auth *args, type: :HTML, &proc
end

- (Config) initialize(*args)

A new instance of Config

Returns:

  • (Config)

    a new instance of Config



17
18
19
20
21
22
23
24
25
26
# File 'lib/presto/http/config.rb', line 17

def initialize *args
  @middleware = []
  @rewrite_rules = {}
  @cache = {}
  @restrictions = {}
  @content_type, @encoding = {}, {}
  @error_procs = {}
  @hooks_a, @hooks_z = {}, {}
  @setup = {}
end

- (Object) rewrite(rule, &proc)

Examples:

app = Presto.new
app.mount Cms do

  # redirect to new address
  http.rewrite /(.*)\.php$/ do |title|
    redirect Cms, :index, title
  end

  # permanently redirect to new address, on inner controller
  http.rewrite /^news\/([\w|\d]+)\-(\d+)\.html/ do |title, id|
    permanent_redirect Forum, :posts, :title => title, :id => id
  end

  # execute an arbitrary action on an arbitrary controller without redirect
  http.rewrite /^latest\/(.*)\.html/ do |title|
    pass News, :index, :scope => :latest, :title => title
  end

  # Return arbitrary body, status-code, headers, without redirect:
  # If argument is a hash, it is added to headers.
  # If argument is a Integer, it is treated as Status-Code.
  # Any other arguments are treated as body.
  http.rewrite /^archived\/(.*)\.html/ do |title|
    if page = Model::Page.first(url: title)
      halt page.content, 'Last-Modified' => page.last_modified
    else
      halt 'page not found', 404
    end
  end

end


174
175
176
177
178
# File 'lib/presto/http/config.rb', line 174

def rewrite rule, &proc
  if proc && configurable?
    (@rewrite_rules[@slice && @slice.root] ||= []) << [rule, proc]
  end
end

- (Object) use(ware, *args, &proc)

each controller may have own middleware.

Examples:

http.use SomeMiddleware, :with, some: :args

Parameters:

  • ware (Class)
  • args (Array)
  • proc (Proc)


360
361
362
# File 'lib/presto/http/config.rb', line 360

def use ware, *args, &proc
  @middleware << {ware: ware, args: args, block: proc} if configurable?
end