rocketio 0.0.0.pre.alpha → 0.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (74) hide show
  1. checksums.yaml +4 -4
  2. data/.gitignore +5 -2
  3. data/LICENSE.txt +22 -0
  4. data/README.md +5 -22
  5. data/Rakefile +1 -7
  6. data/lib/rocketio.rb +3 -131
  7. data/lib/rocketio/version.rb +2 -2
  8. data/rocketio.gemspec +17 -21
  9. metadata +11 -146
  10. data/.travis.yml +0 -3
  11. data/bin/console +0 -14
  12. data/bin/setup +0 -7
  13. data/lib/rocketio/application.rb +0 -31
  14. data/lib/rocketio/controller.rb +0 -288
  15. data/lib/rocketio/controller/authentication.rb +0 -141
  16. data/lib/rocketio/controller/authorization.rb +0 -53
  17. data/lib/rocketio/controller/cookies.rb +0 -59
  18. data/lib/rocketio/controller/error_handlers.rb +0 -89
  19. data/lib/rocketio/controller/filters.rb +0 -119
  20. data/lib/rocketio/controller/flash.rb +0 -21
  21. data/lib/rocketio/controller/helpers.rb +0 -438
  22. data/lib/rocketio/controller/middleware.rb +0 -32
  23. data/lib/rocketio/controller/render.rb +0 -148
  24. data/lib/rocketio/controller/render/engine.rb +0 -76
  25. data/lib/rocketio/controller/render/layout.rb +0 -27
  26. data/lib/rocketio/controller/render/layouts.rb +0 -85
  27. data/lib/rocketio/controller/render/templates.rb +0 -83
  28. data/lib/rocketio/controller/request.rb +0 -115
  29. data/lib/rocketio/controller/response.rb +0 -84
  30. data/lib/rocketio/controller/sessions.rb +0 -64
  31. data/lib/rocketio/controller/token_auth.rb +0 -118
  32. data/lib/rocketio/controller/websocket.rb +0 -21
  33. data/lib/rocketio/error_templates/404.html +0 -3
  34. data/lib/rocketio/error_templates/409.html +0 -7
  35. data/lib/rocketio/error_templates/500.html +0 -3
  36. data/lib/rocketio/error_templates/501.html +0 -6
  37. data/lib/rocketio/error_templates/layout.html +0 -1
  38. data/lib/rocketio/exceptions.rb +0 -4
  39. data/lib/rocketio/router.rb +0 -65
  40. data/lib/rocketio/util.rb +0 -122
  41. data/test/aliases_test.rb +0 -54
  42. data/test/authentication_test.rb +0 -307
  43. data/test/authorization_test.rb +0 -91
  44. data/test/cache_control_test.rb +0 -268
  45. data/test/content_type_test.rb +0 -124
  46. data/test/cookies_test.rb +0 -49
  47. data/test/error_handlers_test.rb +0 -125
  48. data/test/etag_test.rb +0 -445
  49. data/test/filters_test.rb +0 -177
  50. data/test/halt_test.rb +0 -73
  51. data/test/helpers_test.rb +0 -171
  52. data/test/middleware_test.rb +0 -57
  53. data/test/redirect_test.rb +0 -135
  54. data/test/render/engine_test.rb +0 -71
  55. data/test/render/get.erb +0 -1
  56. data/test/render/items.erb +0 -1
  57. data/test/render/layout.erb +0 -1
  58. data/test/render/layout_test.rb +0 -104
  59. data/test/render/layouts/master.erb +0 -1
  60. data/test/render/layouts_test.rb +0 -145
  61. data/test/render/master.erb +0 -1
  62. data/test/render/post.erb +0 -1
  63. data/test/render/put.erb +0 -1
  64. data/test/render/render_test.rb +0 -101
  65. data/test/render/setup.rb +0 -14
  66. data/test/render/templates/a/get.erb +0 -1
  67. data/test/render/templates/master.erb +0 -1
  68. data/test/render/templates_test.rb +0 -146
  69. data/test/request_test.rb +0 -105
  70. data/test/response_test.rb +0 -119
  71. data/test/routes_test.rb +0 -70
  72. data/test/sendfile_test.rb +0 -209
  73. data/test/sessions_test.rb +0 -176
  74. data/test/setup.rb +0 -59
data/.travis.yml DELETED
@@ -1,3 +0,0 @@
1
- language: ruby
2
- rvm:
3
- - 2.2.2
data/bin/console DELETED
@@ -1,14 +0,0 @@
1
- #!/usr/bin/env ruby
2
-
3
- require "bundler/setup"
4
- require "rocketio"
5
-
6
- # You can add fixtures and/or initialization code here to make experimenting
7
- # with your gem easier. You can also use a different console, if you like.
8
-
9
- # (If you use this, don't forget to add pry to your Gemfile!)
10
- # require "pry"
11
- # Pry.start
12
-
13
- require "irb"
14
- IRB.start
data/bin/setup DELETED
@@ -1,7 +0,0 @@
1
- #!/bin/bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
-
5
- bundle install
6
-
7
- # Do any other automated setup that you need to do here
@@ -1,31 +0,0 @@
1
- module RocketIO
2
- class Application
3
-
4
- def initialize *args, &block
5
- controllers = args.empty? ? RocketIO.controllers : args.flatten
6
- if block
7
- controllers.each {|c| c.class_exec {define_method(:call!, block)}}
8
- end
9
- @router = Router.new(*controllers)
10
- end
11
-
12
- def call env
13
- catch :__response__ do # catch 404 errors and potential `halt` calls from middleware
14
- controller, path_params = @router.resolve_path(env[PATH_INFO])
15
-
16
- unless controller
17
- controller = RocketIO::Controller.initialize_controller
18
- controller.env = env
19
- controller.error(404)
20
- end
21
-
22
- controller = controller.initialize_controller(REQUEST_METHODS[env[REQUEST_METHOD]], path_params)
23
- chain = controller.middleware.reverse.inject(controller) {|app,ware| ware.call(app)}
24
- if controller.sessions
25
- chain = controller.sessions[0].new(chain, controller.sessions[1])
26
- end
27
- chain.call(env)
28
- end
29
- end
30
- end
31
- end
@@ -1,288 +0,0 @@
1
- module RocketIO
2
- class Controller
3
- extend Forwardable
4
-
5
- def_delegators 'self.class', :url, :dirname, :parameters_policy
6
- def_delegators :request, :session, :request_method
7
- def_delegators RocketIO, :indifferent_params, :indifferent_hash, :mime_type, :engine_const, :engine_class
8
- def_delegators CGI, :escape_html
9
-
10
- # defining get, post etc. methods that will be called
11
- # when a request matches current controller and appropriate request method used.
12
- #
13
- # by default all requests, except HEAD, will return a NotImplementedError.
14
- # override the methods you need to be handled by controller.
15
- #
16
- RocketIO::REQUEST_METHODS.each_value do |verb|
17
- define_method(verb) {|*| error(501)}
18
- end
19
- def head(*); end
20
-
21
- # call requested method.
22
- # also call #before, #around and #after filters.
23
- #
24
- # @param [Hash] env
25
- # @return [Rack::Response]
26
- #
27
- def call env
28
- catch :__response__ do
29
- begin
30
- self.env = env
31
- validate_or_request_authentication_if_needed
32
- validate_or_request_authorization_if_needed
33
- validate_parameters
34
-
35
- call! proc {
36
- invoke_before_filter
37
- invoke_around_filter proc {
38
- response.body = public_send(requested_method, *path_params_array)
39
- }
40
- invoke_after_filter
41
- }
42
- response.body ||= RocketIO::EMPTY_ARRAY
43
- response.body = [] if head? # dropping body on HEAD requests
44
- response.finish
45
- rescue Exception => e
46
- if RocketIO.development?
47
- puts "\e[0;31m%s\e[0m" % e.inspect
48
- e.backtrace.each {|l| puts " \e[0;36m%s\e[0m" % l}
49
- end
50
- error(500, e)
51
- end
52
- end
53
- end
54
-
55
- def call! app
56
- app.call
57
- end
58
-
59
- def env= env
60
- @__env__ = env
61
- end
62
-
63
- def env
64
- @__env__
65
- end
66
-
67
- def validate_parameters
68
- # enforce policy only if a method defined for current request method
69
- # cause stock REST methods accepting any number of arguments
70
- return unless policy = parameters_policy[requested_method]
71
-
72
- if path_params_array.size >= policy[:min]
73
- return if policy[:max] == :* || path_params_array.size <= policy[:max]
74
- end
75
-
76
- error(409)
77
- end
78
-
79
- def path_params
80
- @__path_params__ ||= begin
81
- rangemap = self.class.path_params[requested_method] ||
82
- raise(StandardError, 'No path_params map found for %s method' % requested_method)
83
- indifferent_params(rangemap.each_with_object({}) {|(m,r),o|
84
- o[m] = r.min == r.max ? path_params_array[r.min] : path_params_array[r]
85
- }).freeze
86
- end
87
- end
88
-
89
- def path_params_array
90
- @__path_params_array__
91
- end
92
-
93
- def params
94
- @__params__ ||= indifferent_params(request.params)
95
- end
96
-
97
- def request
98
- @__request__ ||= RocketIO::Request.new(env)
99
- end
100
-
101
- def response
102
- @__response__ ||= RocketIO::Response.new
103
- end
104
-
105
- def requested_method
106
- @__requested_method__ ||= RocketIO::REQUEST_METHODS[request_method]
107
- end
108
- end
109
-
110
- class << Controller
111
-
112
- def inherit setup, opts = {}
113
- opts[:from] || raise(ArgumentError, ':from option is required')
114
- __send__(:"define_#{setup}_methods", opts[:from])
115
- end
116
-
117
- def inherited base
118
- # registering new controller
119
- RocketIO.controllers.push(base)
120
-
121
- # new controller inherits all setups from superclass
122
- base.inherit :before, from: self
123
- base.inherit :around, from: self
124
- base.inherit :after, from: self
125
-
126
- base.inherit :basic_auth, from: self
127
- base.inherit :digest_auth, from: self
128
- base.inherit :token_auth, from: self
129
-
130
- base.inherit :error_handlers, from: self
131
- base.inherit :middleware, from: self
132
- base.inherit :sessions, from: self
133
-
134
- base.inherit :engine, from: self
135
- base.inherit :layout, from: self
136
- base.inherit :layouts, from: self
137
- base.inherit :templates, from: self
138
-
139
- # removing superclass name from new controller name
140
- path = RocketIO.underscore(base.name.to_s.sub(self.name.to_s + '::', '').gsub('::', '/'))
141
-
142
- # new controller uses for URL its underscored name prefixed by superclass URL
143
- base.map RocketIO.rootify_path(url, path)
144
-
145
- # setting dirname for new controller
146
- base.instance_variable_set(:@__dirname__, RocketIO.caller_to_dirname(caller).freeze)
147
- end
148
-
149
- # by default controllers will use underscored name for base URL.
150
- # this method allow to set a custom base URL.
151
- #
152
- # @example Users::Register will listen on /users/register by default
153
- # class Users
154
- # class Register < RocketIO
155
- #
156
- # end
157
- # end
158
- #
159
- # @note
160
- #
161
- # @example make Users::Register to listen on /users/join rather than /users/register
162
- #
163
- # class Users
164
- # class Register < RocketIO
165
- # map :join
166
- #
167
- # end
168
- # end
169
- #
170
- # @note if given URL starts with a slash it will ignore class name and set URL as is
171
- #
172
- # @example make Users::Register to listen on /members/join
173
- #
174
- # class Users < RocketIO
175
- # class Register < self
176
- # map '/members/join'
177
- #
178
- # end
179
- # end
180
- #
181
- # @param path [String || Symbol]
182
- #
183
- def map path
184
- path = path.to_s
185
- @__url__ = if path =~ /\A\//
186
- path
187
- else
188
- if superclass == Object
189
- RocketIO.rootify_path(path)
190
- else
191
- RocketIO.rootify_path(superclass.url, path)
192
- end
193
- end.freeze
194
- end
195
-
196
- # allow controllers to serve multiple URLs
197
- #
198
- # @param path [String || Symbol]
199
- #
200
- def alias_url path
201
- path = path.to_s
202
- path = if path =~ /\A\//
203
- path
204
- else
205
- if superclass == Object
206
- RocketIO.rootify_path(path)
207
- else
208
- RocketIO.rootify_path(superclass.url, path)
209
- end
210
- end.freeze
211
- aliases.push(path)
212
- end
213
-
214
- def aliases
215
- @__aliases__ ||= []
216
- end
217
-
218
- # build a URL from given chunks prefixing them with actual path
219
- #
220
- # @param *args [Array]
221
- # @return [String]
222
- def url *args
223
- return @__url__ if args.empty?
224
- query = if args.last.is_a?(Hash)
225
- RocketIO::QUERY_PREFIX + ::Rack::Utils.build_nested_query(args.pop)
226
- else
227
- RocketIO::EMPTY_STRING
228
- end
229
- ::File.join(@__url__, args.map!(&:to_s)) + query
230
- end
231
-
232
- def method_added meth
233
- parameters = instance_method(meth).parameters
234
- path_params[meth] = RocketIO.path_params(parameters).freeze
235
- if requested_method = RocketIO::REQUEST_METHODS.values.find {|verb| verb == meth}
236
- # REST methods should be called with a predetermined set of parameters.
237
- # setting an appropriate policy for just defined method based on its parameters.
238
- parameters_policy[requested_method] = RocketIO.parameters_policy(parameters).freeze
239
- end
240
- end
241
-
242
- # initializing the controller to process a HTTP request
243
- #
244
- # @param path_params [Array]
245
- # @return a RocketIO::Route instance
246
- def initialize_controller requested_method = nil, path_params_array = nil
247
- controller = allocate
248
- controller.instance_variable_set(:@__requested_method__, requested_method.to_sym) if requested_method
249
- controller.instance_variable_set(:@__path_params_array__, (path_params_array || []).freeze)
250
- controller
251
- end
252
-
253
- def parameters_policy
254
- @__parameters_policy__ ||= {}
255
- end
256
-
257
- def path_params
258
- @__path_params__ ||= {}
259
- end
260
-
261
- def dirname *args
262
- ::File.join(@__dirname__, args.map!(&:to_s))
263
- end
264
-
265
- # making controller to act as a Rack application
266
- def call env
267
- initialize_controller.call(env)
268
- end
269
-
270
- def api
271
- public_instance_methods(false)
272
- end
273
- end
274
- end
275
-
276
- require 'rocketio/controller/authentication'
277
- require 'rocketio/controller/authorization'
278
- require 'rocketio/controller/cookies'
279
- require 'rocketio/controller/error_handlers'
280
- require 'rocketio/controller/filters'
281
- require 'rocketio/controller/flash'
282
- require 'rocketio/controller/helpers'
283
- require 'rocketio/controller/middleware'
284
- require 'rocketio/controller/request'
285
- require 'rocketio/controller/response'
286
- require 'rocketio/controller/sessions'
287
- require 'rocketio/controller/websocket'
288
- require 'rocketio/controller/render'
@@ -1,141 +0,0 @@
1
- module RocketIO
2
- class Controller
3
-
4
- # easily restrict access to controller using basic auth
5
- #
6
- # @example protect all request methods
7
- # basic_auth do |user,pass|
8
- # user == 'admin' && pass == 'super secret password'
9
- # end
10
- #
11
- # @example protect only POST, PUT and DELETE request methods
12
- # basic_auth :post, :put, :delete do |user,pass|
13
- # user == 'admin' && pass == 'super secret password'
14
- # end
15
- #
16
- # @example use different credentials for GET and POST
17
- # basic_auth :get do |user,pass|
18
- # user == 'reader' && pass == 'readPass'
19
- # end
20
- #
21
- # basic_auth :post do |user,pass|
22
- # user == 'poster' && pass == 'writePass'
23
- # end
24
- #
25
- # @note authorization is composable, that's it, if superclass is protecting :get method
26
- # and current controller protects :post method,
27
- # both :get and :post will be protected in current controller
28
- #
29
- # @params *args [Array]
30
- # @param block [Proc]
31
- #
32
- def self.basic_auth *args, &block
33
- opts = args.last.is_a?(Hash) ? args.pop : {}
34
- rqms = args.any? ? args.map!(&:to_sym) : RocketIO::REQUEST_METHODS.values
35
- rqms.each do |rm|
36
- (@__basic_auth__ ||= {})[rm] = {
37
- class: Rack::Auth::Basic,
38
- arguments: [opts[:realm] || RocketIO::DEFAULT_AUTH_REALM].freeze,
39
- block: block,
40
- mock: RocketIO::HTTP_AUTHORIZATION_MOCKS[:basic]
41
- }.freeze
42
- end
43
- define_basic_auth_methods
44
- end
45
-
46
- def self.define_basic_auth_methods source = self
47
- prompts = (source.instance_variable_get(:@__basic_auth__) || {}).each_with_object(allocate.basic_auth.dup) do |(rm,p),o|
48
- method = :"__basic_auth__#{rm}__"
49
- define_method(method, &p[:block])
50
- o[rm] = p.merge(method: method).freeze
51
- end.freeze
52
- return if prompts.empty?
53
- define_method(:basic_auth) {prompts}
54
- end
55
-
56
- def basic_auth; RocketIO::EMPTY_HASH end
57
-
58
- # easily restrict access to controller using digest auth
59
- #
60
- # @example protect all request methods using hashed passwords
61
- # # hash the password somewhere in irb:
62
- # # ::Digest::MD5.hexdigest 'admin:AccessRestricted:somePassword'
63
- # # username ^ realm ^ password ^
64
- #
65
- # #=> 9d77d54decc22cdcfb670b7b79ee0ef0
66
- #
67
- # digest_auth :passwords_hashed => true, :realm => 'AccessRestricted' do |user|
68
- # {'admin' => '9d77d54decc22cdcfb670b7b79ee0ef0'}[user]
69
- # end
70
- #
71
- # @example protect all request methods using plain passwords
72
- # digest_auth do |user|
73
- # {'admin' => 'password'}[user]
74
- # end
75
- #
76
- # @example protect only POST, PUT and DELETE request methods
77
- # digest_auth :post, :put, :delete do |user|
78
- # {'admin' => 'password'}[user]
79
- # end
80
- #
81
- # @example use different credentials for GET and POST
82
- # digest_auth :get do |user|
83
- # {'user' => 'readPass'}[user]
84
- # end
85
- #
86
- # digest_auth :post do |user|
87
- # {'poster' => 'writePass'}[user]
88
- # end
89
- #
90
- # @params *args [Array]
91
- # @param block [Proc]
92
- #
93
- def self.digest_auth *args, &block
94
- opts = args.last.is_a?(Hash) ? args.pop : {}
95
- opts[:realm] ||= RocketIO::DEFAULT_AUTH_REALM
96
- opts[:opaque] ||= opts[:realm]
97
- rqms = args.any? ? args.map!(&:to_sym) : RocketIO::REQUEST_METHODS.values
98
- rqms.each do |rm|
99
- (@__digest_auth__ ||= {})[rm] = {
100
- class: Rack::Auth::Digest::MD5,
101
- arguments: [opts].freeze,
102
- block: block,
103
- mock: RocketIO::HTTP_AUTHORIZATION_MOCKS[:digest]
104
- }.freeze
105
- end
106
- define_digest_auth_methods
107
- end
108
-
109
- def self.define_digest_auth_methods source = self
110
- prompts = (source.instance_variable_get(:@__digest_auth__) || {}).each_with_object(allocate.digest_auth.dup) do |(rm,p),o|
111
- method = :"__digest_auth__#{rm}__"
112
- define_method(method, &p[:block])
113
- o[rm] = p.merge(method: method).freeze
114
- end.freeze
115
- return if prompts.empty?
116
- define_method(:digest_auth) {prompts}
117
- end
118
-
119
- def digest_auth; RocketIO::EMPTY_HASH end
120
-
121
- def user?
122
- env[RocketIO::REMOTE_USER]
123
- end
124
-
125
- # checks whether authentication is required and
126
- # send an authorization request if credentials not present or invalid
127
- def validate_or_request_authentication_if_needed
128
- return unless auth = digest_auth[requested_method] || basic_auth[requested_method]
129
- return unless prompt = auth[:class].new(proc {}, *auth[:arguments]) do |*a|
130
- self.__send__(auth[:method], *a)
131
- end.call(
132
- if RocketIO::HTTP_AUTHORIZATION_KEYS.detect {|key| env.has_key?(key)}
133
- env
134
- else
135
- env.merge(RocketIO::HTTP_AUTHORIZATION_KEYS.first => auth[:mock])
136
- end
137
- )
138
- throw(:__response__, prompt)
139
- end
140
- end
141
- end