roy 0.5.2 → 0.5.3

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- roy (0.5.2)
4
+ roy (0.5.3)
5
5
  rack
6
6
 
7
7
  GEM
data/LICENSE CHANGED
@@ -1,4 +1,4 @@
1
- Copyright (c) 2009-2011 François "madx" Vaux <madx@yapok.org>
1
+ Copyright (c) 2009-2012 François "madx" Vaux <madx@yapok.org>
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person
4
4
  obtaining a copy of this software and associated documentation
@@ -1,4 +1,30 @@
1
1
  module Roy
2
+ # This module allows you to modify the response before it is sent to the
3
+ # client. It does this by overriding the {Roy#call} method.
4
+ #
5
+ # == Configuration:
6
+ # roy.conf.after::
7
+ # A proc object that will be called with the response as argument.
8
+ # Defaults to identity if not set.
9
+ #
10
+ # @example Forcing a custom content-type
11
+ #
12
+ # class SetContentType
13
+ # include Roy
14
+ #
15
+ # roy use: [:after],
16
+ # after: ->(resp) { resp.headers['Content-Type'] = 'text/x-foo' }
17
+ #
18
+ # def get(_)
19
+ # "Hello, world\n"
20
+ # end
21
+ # end
22
+ #
23
+ # @example Demo
24
+ #
25
+ # $ curl -i localhost:9292
26
+ # HTTP/1.1 200 OK
27
+ # Content-Type: text/x-foo
2
28
  module After
3
29
  def call(env)
4
30
  status, header, body = super
@@ -9,17 +9,23 @@ require 'ostruct'
9
9
  require 'roy/version'
10
10
  require 'roy/context'
11
11
 
12
+ # This is the main module that applications should include.
12
13
  module Roy
14
+
15
+ # Default options.
13
16
  Defaults = {allow: [:get], prefix: :'', use: [:halt]}
14
17
 
18
+ # Extend the class with the ClassMethods module.
15
19
  def self.included(base)
16
20
  base.send(:extend, ClassMethods)
17
21
  end
18
22
 
23
+ # Returns the application context or initialize it
19
24
  def roy
20
25
  @roy ||= Context.new(self)
21
26
  end
22
27
 
28
+ # A Rack-compliant #call method.
23
29
  def call(env)
24
30
  roy.prepare!(env)
25
31
 
@@ -41,6 +47,7 @@ module Roy
41
47
  module ClassMethods
42
48
  attr_reader :conf
43
49
 
50
+ # Setup default configuration for the application.
44
51
  def self.extended(base)
45
52
  base.instance_eval do
46
53
  @conf ||= OpenStruct.new
@@ -48,6 +55,7 @@ module Roy
48
55
  end
49
56
  end
50
57
 
58
+ # Set options for the application
51
59
  def roy(options={})
52
60
  options.each do |key,value|
53
61
  case key
@@ -1,20 +1,76 @@
1
1
  module Roy
2
+ # This module provides helpers for using the HTTP basic authentication system.
3
+ #
4
+ # == Configuration:
5
+ # roy.conf.auth [:realm]::
6
+ # The authentication realm to use.
7
+ # roy.conf.auth [:logic]::
8
+ # A proc that checks if an user is authorized. See #authorized? in
9
+ # InstanceMethods.
10
+ #
11
+ # @example Simple auth example
12
+ #
13
+ # class AuthApp
14
+ # include Roy
15
+ # roy use: [:basic_auth],
16
+ # auth: {
17
+ # realm: "My Realm",
18
+ # logic: ->(_, u, p) { %w(admin foobar) == [u, p] }
19
+ # }
20
+ #
21
+ # def get(_)
22
+ # roy.protected!
23
+ # "Protected zone"
24
+ # end
25
+ # end
26
+ #
27
+ # @example Using user data
28
+ #
29
+ # class AuthUserDataApp
30
+ # include Roy
31
+ # roy use: [:basic_auth],
32
+ # auth: {
33
+ # realm: "My Realm",
34
+ # logic: ->(override, u, p) {
35
+ # override || (%w(admin foobar) == [u, p])
36
+ # }
37
+ # }
38
+ #
39
+ # def get(path)
40
+ # roy.protected!(path =~ /private/)
41
+ # "Protected if path contains private"
42
+ # end
43
+ # end
2
44
  module BasicAuth
3
- def protected!(data=nil)
4
- unless authorized?(data)
5
- realm = roy.conf.auth && roy.conf.auth[:realm] || 'Realm'
6
- roy.response['WWW-Authenticate'] = %(Basic realm="#{realm}")
7
- roy.halt 401
8
- end
45
+ def self.setup(roy)
46
+ roy.send(:extend, InstanceMethods)
9
47
  end
10
48
 
11
- def authorized?(data=nil)
12
- auth = Rack::Auth::Basic::Request.new(roy.request.env)
49
+ module InstanceMethods
50
+
51
+ # Protect all subsequent code using HTTP Basic Authentication.
52
+ #
53
+ # @param data user data to pass to #authorized?
54
+ def protected!(data=nil)
55
+ unless authorized?(data)
56
+ realm = conf.auth && conf.auth[:realm] || 'Realm'
57
+ response['WWW-Authenticate'] = %(Basic realm="#{realm}")
58
+ halt 401
59
+ end
60
+ end
13
61
 
14
- auth.provided? && auth.basic? && auth.credentials &&
15
- (roy.conf.auth[:logic] || ->(data, u, p) {
16
- %w(admin password) == [u, p]
17
- }).(data, *auth.credentials)
62
+ # Runs the authentication logic against the user and passord given in the
63
+ # request, using custom additional data.
64
+ #
65
+ # @param data user data to pass to the authentication logic
66
+ def authorized?(data=nil)
67
+ auth = Rack::Auth::Basic::Request.new(request.env)
68
+
69
+ auth.provided? && auth.basic? && auth.credentials &&
70
+ (conf.auth[:logic] || ->(data, u, p) {
71
+ %w(admin password) == [u, p]
72
+ }).(data, *auth.credentials)
73
+ end
18
74
  end
19
75
  end
20
76
  end
@@ -1,4 +1,33 @@
1
1
  module Roy
2
+ # This module allows you to modify the environment before it is handled by the
3
+ # application. It does this by overriding the {Roy#call} method.
4
+ #
5
+ # == Configuration:
6
+ # roy.conf.before::
7
+ # A proc object that will be called with the environment as argument.
8
+ # Defaults to identity if not set.
9
+ #
10
+ # @example Forcing a method
11
+ #
12
+ # class AlwaysGet
13
+ # include Roy
14
+ #
15
+ # roy allow: [:put, :post], use: [:before],
16
+ # before: ->(env) { env['REQUEST_METHOD'] = 'GET' }
17
+ #
18
+ # def get(_)
19
+ # "Hello, world\n"
20
+ # end
21
+ # end
22
+ #
23
+ # @example Demo
24
+ #
25
+ # $ curl -i localhost:9292
26
+ # HTTP/1.1 200 OK
27
+ # $ curl -X POST -i localhost:9292
28
+ # HTTP/1.1 200 OK
29
+ # $ curl -X PUT -i localhost:9292
30
+ # HTTP/1.1 200 OK
2
31
  module Before
3
32
  def call(env)
4
33
  (roy.conf.before || lambda {|x| x }).(env)
@@ -1,7 +1,33 @@
1
1
  module Roy
2
+ # Application context for Roy applications.
3
+ #
4
+ # Everything must be namespaced in this context to avoid any clashes and to
5
+ # make the code cleaner.
2
6
  class Context
3
- attr_reader :app, :conf, :env, :request, :response, :headers, :params
7
+ # Returns the current application
8
+ attr_reader :app
4
9
 
10
+ # Returns the application's configuration
11
+ attr_reader :conf
12
+
13
+ # Returns the environment passed to #call
14
+ attr_reader :env
15
+
16
+ # Returns the current request
17
+ attr_reader :request
18
+
19
+ # Returns the current response
20
+ attr_reader :response
21
+
22
+ # Returns the current response's headers
23
+ attr_reader :headers
24
+
25
+ # Returns the current request's params
26
+ attr_reader :params
27
+
28
+ # Creates a new Context object.
29
+ #
30
+ # @param app the context's application
5
31
  def initialize(app)
6
32
  @app = app
7
33
  @conf = app.class.conf
@@ -11,6 +37,9 @@ module Roy
11
37
  end
12
38
  end
13
39
 
40
+ # Initializes the attributes based on an environment.
41
+ #
42
+ # @param env the environment to use
14
43
  def prepare!(env)
15
44
  @env = env
16
45
  @request = Rack::Request.new(env)
@@ -1,11 +1,38 @@
1
1
  module Roy
2
+ # This module adds a +halt+ method to the application context that allows you
3
+ # to break during a handler and immediately return a status code and a body.
4
+ #
5
+ # Included by default.
6
+ #
7
+ # @example A Not Found application
8
+ #
9
+ # class NotFoundApp
10
+ # include Roy
11
+ #
12
+ # def get(_)
13
+ # halt 404
14
+ # end
15
+ # end
16
+ #
17
+ # @example Test
18
+ #
19
+ # $ curl -i localhost:9292
20
+ # HTTP/1.1 404 Not Found
2
21
  module Halt
3
22
 
4
23
  def self.setup(roy)
5
- class << roy
6
- def halt(code, message=nil)
7
- throw :halt, [code, message || Rack::Utils::HTTP_STATUS_CODES[code]]
8
- end
24
+ roy.send(:extend, InstanceMethods)
25
+ end
26
+
27
+ module InstanceMethods
28
+ # Break from the current +catch(:halt)+ block
29
+ #
30
+ # @param [Integer] code the response status code.
31
+ # @param [String] message the response body.
32
+ # @return [Integer, String] the status and the given message or a default
33
+ # one.
34
+ def halt(code, message=nil)
35
+ throw :halt, [code, message || Rack::Utils::HTTP_STATUS_CODES[code]]
9
36
  end
10
37
  end
11
38
 
@@ -1,24 +1,99 @@
1
1
  require 'tilt'
2
2
 
3
3
  module Roy
4
+ # A simple template rendering mechanism based on Tilt.
5
+ #
6
+ # == Configuration:
7
+ # roy.conf.render::
8
+ # A hash of options to pass to Tilt.
9
+ # roy.conf.views::
10
+ # The directory where views are kept. Defaults to +views/+
11
+ #
12
+ # @example Using <tt>roy.render</tt>
13
+ #
14
+ # class ErbApp
15
+ # include Roy
16
+ #
17
+ # roy use: [:render]
18
+ #
19
+ # def get(path)
20
+ # case path
21
+ # when /\/hello/
22
+ # roy.render :erb, "Hello, <%= roy.params[:p] || \"world\" %>!\n"
23
+ # else
24
+ # roy.render :erb, :index
25
+ # end
26
+ # end
27
+ # end
28
+ #
29
+ # @example Test
30
+ #
31
+ # $ cat views/index.erb
32
+ # Let me <a href="/hello">greet</a> you.
33
+ # $ curl -i localhost:9292
34
+ # Let me <a href="/hello">greet</a> you.
35
+ # $ curl -i localhost:9292/hello?p=blah
36
+ # Hello, blah!
37
+ #
38
+ # @example Haml renderer with partials support
39
+ #
40
+ # module HamlRenderWithPartial
41
+ # def self.setup(roy)
42
+ # roy.send(:extend, InstanceMethods)
43
+ # end
44
+ #
45
+ # module InstanceMethods
46
+ # def render(tpl_or_string, params={})
47
+ # case layout = params.delete(:layout)
48
+ # when false
49
+ # super(:haml, tpl_or_string, params)
50
+ # else
51
+ # super(:haml, :layout, params do
52
+ # super(:haml, tpl_or_string, params)
53
+ # end
54
+ # end
55
+ # end
56
+ # end
57
+ # end
4
58
  module Render
5
59
 
6
60
  def self.setup(roy)
7
- class << roy
8
- def render(engine, view_or_string, params={}, &block)
9
- options = conf.render || {}
10
- template = case view_or_string
11
- when Symbol
12
- file = [view_or_string.to_s, engine].map(&:to_s).join('.')
13
- dir = conf.views || 'views'
14
- Tilt.new(File.join(dir, file), nil, options)
15
- else
16
- Tilt[engine].new(nil, nil, options) { view_or_string.to_s }
17
- end
61
+ roy.send(:extend, InstanceMethods)
62
+ end
63
+
64
+ module InstanceMethods
18
65
 
19
- template.render(app, params, &block)
20
- end
66
+ # Render the given template or string with the selected engine.
67
+ #
68
+ # Views are looked for inside the +roy.conf.views+ directory.
69
+ # Files should have an extension matching the selected engine.
70
+ # If you want to use sub-directories, you have to use the
71
+ # +:"subdir/file.ext"+ syntax.
72
+ #
73
+ # @see https://github.com/rtomayko/tilt/blob/master/README.md
74
+ # @see https://github.com/rtomayko/tilt/blob/master/TEMPLATES.md
75
+ #
76
+ # @param [Symbol] engine the name of the rendering engine. Must be
77
+ # supported by Tilt.
78
+ # @param [Symbol] view_or_string a template file.
79
+ # @param [String] view_or_string a template string.
80
+ # @param [Hash] params locals for Tilt::Template#render.
81
+ # @param [Proc] block a block to execute when using +yield+ in the
82
+ # template.
83
+ def render(engine, view_or_string, params={}, &block)
84
+ options = conf.render || {}
85
+ template = case view_or_string
86
+ when Symbol
87
+ file = [view_or_string.to_s, engine].map(&:to_s).join('.')
88
+ dir = conf.views || 'views'
89
+ Tilt.new(File.join(dir, file), nil, options)
90
+ else
91
+ Tilt[engine].new(nil, nil, options) { view_or_string.to_s }
92
+ end
93
+
94
+ template.render(app, params, &block)
21
95
  end
96
+
22
97
  end
23
98
 
24
99
  end
@@ -1,6 +1,8 @@
1
1
  module Roy
2
- VERSION = [0, 5, 2]
2
+ # Roy version
3
+ VERSION = [0, 5, 3]
3
4
 
5
+ # Return the version as a String.
4
6
  def self.version
5
7
  VERSION.join('.')
6
8
  end
@@ -10,7 +10,7 @@ class BasicAuthTestObject
10
10
  }
11
11
 
12
12
  def get(path)
13
- protected!
13
+ roy.protected!
14
14
  'success'
15
15
  end
16
16
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: roy
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.5.2
4
+ version: 0.5.3
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,11 +9,11 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-01-17 00:00:00.000000000 Z
12
+ date: 2012-02-07 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rack
16
- requirement: &19255820 !ruby/object:Gem::Requirement
16
+ requirement: &13775240 !ruby/object:Gem::Requirement
17
17
  none: false
18
18
  requirements:
19
19
  - - ! '>='
@@ -21,10 +21,10 @@ dependencies:
21
21
  version: '0'
22
22
  type: :runtime
23
23
  prerelease: false
24
- version_requirements: *19255820
24
+ version_requirements: *13775240
25
25
  - !ruby/object:Gem::Dependency
26
26
  name: minitest
27
- requirement: &19255280 !ruby/object:Gem::Requirement
27
+ requirement: &13774520 !ruby/object:Gem::Requirement
28
28
  none: false
29
29
  requirements:
30
30
  - - ! '>='
@@ -32,10 +32,10 @@ dependencies:
32
32
  version: '0'
33
33
  type: :development
34
34
  prerelease: false
35
- version_requirements: *19255280
35
+ version_requirements: *13774520
36
36
  - !ruby/object:Gem::Dependency
37
37
  name: rack-test
38
- requirement: &19254660 !ruby/object:Gem::Requirement
38
+ requirement: &13792140 !ruby/object:Gem::Requirement
39
39
  none: false
40
40
  requirements:
41
41
  - - ! '>='
@@ -43,10 +43,10 @@ dependencies:
43
43
  version: '0'
44
44
  type: :development
45
45
  prerelease: false
46
- version_requirements: *19254660
46
+ version_requirements: *13792140
47
47
  - !ruby/object:Gem::Dependency
48
48
  name: tilt
49
- requirement: &19254220 !ruby/object:Gem::Requirement
49
+ requirement: &13791400 !ruby/object:Gem::Requirement
50
50
  none: false
51
51
  requirements:
52
52
  - - ! '>='
@@ -54,7 +54,7 @@ dependencies:
54
54
  version: '0'
55
55
  type: :development
56
56
  prerelease: false
57
- version_requirements: *19254220
57
+ version_requirements: *13791400
58
58
  description: ! 'roy is a small library which allows every Ruby object to be used
59
59
 
60
60
  as a Rack application.'
@@ -111,7 +111,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
111
111
  version: '0'
112
112
  requirements: []
113
113
  rubyforge_project: roy
114
- rubygems_version: 1.8.5
114
+ rubygems_version: 1.8.15
115
115
  signing_key:
116
116
  specification_version: 3
117
117
  summary: make your objects REST-friendly