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
@@ -1,115 +0,0 @@
1
- # Copyright (c) 2007, 2008, 2009 Blake Mizerany
2
- # Copyright (c) 2010, 2011, 2012, 2013, 2014 Konstantin Haase
3
- # Copyright (c) 2015 Slee Woo
4
- #
5
- # Permission is hereby granted, free of charge, to any person
6
- # obtaining a copy of this software and associated documentation
7
- # files (the "Software"), to deal in the Software without
8
- # restriction, including without limitation the rights to use,
9
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the
11
- # Software is furnished to do so, subject to the following
12
- # conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be
15
- # included in all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
- # OTHER DEALINGS IN THE SOFTWARE.
25
-
26
- module RocketIO
27
- class Request < Rack::Request
28
-
29
- HEADER_PARAM = /\s*[\w.]+=(?:[\w.]+|"(?:[^"\\]|\\.)*")?\s*/
30
- HEADER_VALUE_WITH_PARAMS = /(?:(?:\w+|\*)\/(?:\w+(?:\.|\-|\+)?|\*)*)\s*(?:;#{HEADER_PARAM})*/
31
-
32
- # Returns an array of acceptable media types for the response
33
- def accept
34
- @__accept__ ||= begin
35
- if env.include?(HTTP_ACCEPT) and !(accept = env[HTTP_ACCEPT].to_s).empty?
36
- accept.scan(HEADER_VALUE_WITH_PARAMS).map! {|e| AcceptEntry.new(e)}.sort
37
- else
38
- [AcceptEntry.new('*/*')]
39
- end
40
- end
41
- end
42
-
43
- def accept?(type)
44
- preferred_type(type).to_s.include?(type)
45
- end
46
-
47
- def preferred_type(*types)
48
- accepts = accept # just evaluate once
49
- return accepts.first if types.empty?
50
- types.flatten!
51
- return types.first if accepts.empty?
52
- accepts.detect do |pattern|
53
- type = types.detect { |t| File.fnmatch(pattern, t) }
54
- return type if type
55
- end
56
- end
57
-
58
- alias secure? ssl?
59
-
60
- def forwarded?
61
- env.include?(HTTP_X_FORWARDED_HOST)
62
- end
63
-
64
- def safe?
65
- get? or head? or options? or trace?
66
- end
67
-
68
- def idempotent?
69
- safe? or put? or delete? or link? or unlink?
70
- end
71
-
72
- class AcceptEntry
73
- attr_accessor :params
74
- attr_reader :entry
75
-
76
- def initialize(entry)
77
- params = entry.scan(HEADER_PARAM).map! do |s|
78
- key, value = s.strip.split('=', 2)
79
- value = value[1..-2].gsub(/\\(.)/, '\1') if value.start_with?('"')
80
- [key, value]
81
- end
82
-
83
- @entry = entry
84
- @type = entry[/[^;]+/].delete(' ')
85
- @params = Hash[params]
86
- @q = @params.delete('q') { 1.0 }.to_f
87
- end
88
-
89
- def <=>(other)
90
- other.priority <=> self.priority
91
- end
92
-
93
- def priority
94
- # We sort in descending order; better matches should be higher.
95
- [ @q, -@type.count('*'), @params.size ]
96
- end
97
-
98
- def to_str
99
- @type
100
- end
101
-
102
- def to_s(full = false)
103
- full ? entry : to_str
104
- end
105
-
106
- def respond_to?(*args)
107
- super or to_str.respond_to?(*args)
108
- end
109
-
110
- def method_missing(*args, &block)
111
- to_str.send(*args, &block)
112
- end
113
- end
114
- end
115
- end
@@ -1,84 +0,0 @@
1
- # Copyright (c) 2007, 2008, 2009 Blake Mizerany
2
- # Copyright (c) 2010, 2011, 2012, 2013, 2014 Konstantin Haase
3
- # Copyright (c) 2015 Slee Woo
4
- #
5
- # Permission is hereby granted, free of charge, to any person
6
- # obtaining a copy of this software and associated documentation
7
- # files (the "Software"), to deal in the Software without
8
- # restriction, including without limitation the rights to use,
9
- # copy, modify, merge, publish, distribute, sublicense, and/or sell
10
- # copies of the Software, and to permit persons to whom the
11
- # Software is furnished to do so, subject to the following
12
- # conditions:
13
- #
14
- # The above copyright notice and this permission notice shall be
15
- # included in all copies or substantial portions of the Software.
16
- #
17
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
18
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
19
- # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
20
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
21
- # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
22
- # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
23
- # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
24
- # OTHER DEALINGS IN THE SOFTWARE.
25
-
26
- module RocketIO
27
- class Response < Rack::Response
28
-
29
- def body= value
30
- @body = case value
31
- when Rack::Response
32
- value.body
33
- when Proc
34
- def value.each; yield(call) end
35
- value
36
- when String
37
- [value]
38
- else
39
- value
40
- end
41
- end
42
-
43
- def empty_body?
44
- @body == EMPTY_ARRAY || @body.nil?
45
- end
46
-
47
- def each
48
- block_given? ? super : enum_for(:each)
49
- end
50
-
51
- def finish
52
- headers[CONTENT_TYPE] ||= DEFAULT_CONTENT_TYPE
53
-
54
- if drop_content_info?
55
- headers.delete(CONTENT_LENGTH)
56
- headers.delete(CONTENT_TYPE)
57
- end
58
-
59
- if drop_body?
60
- close
61
- self.body = EMPTY_ARRAY
62
- end
63
-
64
- [status.to_i, headers, self.body]
65
- end
66
-
67
- def precondition_failed?
68
- status.to_i == 412
69
- end
70
-
71
- def not_modified?
72
- status.to_i == 304
73
- end
74
-
75
- private
76
- def drop_content_info?
77
- status.to_i / 100 == 1 || drop_body?
78
- end
79
-
80
- def drop_body?
81
- DROP_BODY_RESPONSES[status.to_i]
82
- end
83
- end
84
- end
@@ -1,64 +0,0 @@
1
- module RocketIO
2
- class Controller
3
-
4
- # setup sessions.
5
- # there are 2 setups out of the box:
6
- # - cookies
7
- # - memcache
8
- # you can also use your own setup
9
- #
10
- # @note to disable sessions for some controller set sessions to nil or false
11
- #
12
- # @example keep sessions in cookies
13
- # sessions :cookies
14
- #
15
- # @example keep sessions in cookies using custom options
16
- # sessions :cookies, secret: 'someSecret', domain: 'some.domain'
17
- #
18
- # @example keep sessions in memcache
19
- # sessions :memcache
20
- #
21
- # @example use a custom setup, i.e. github.com/migrs/rack-session-mongo
22
- # $ gem install rack-session-mongo
23
- #
24
- # require 'rack/session/mongo'
25
- #
26
- # class Pages < RocketIO::Controller
27
- # sessions Rack::Session::Mongo
28
- # end
29
- #
30
- # @example disable sessions for current controller
31
- # sessions nil # or false
32
- #
33
- # @param pool [Symbol, Class]
34
- # @param opts [Hash]
35
- #
36
- def self.sessions pool = (noargs = true; nil), opts = {}
37
- @__sessions__ = if pool.nil? || pool == false
38
- nil
39
- else
40
- if pool == :cookies && opts[:secret].nil?
41
- opts[:secret] = ::Digest::MD5.hexdigest([Time.now.to_f, rand]*'')
42
- end
43
- pool = case pool
44
- when :cookies
45
- ::Rack::Session::Cookie
46
- when :memcache
47
- ::Rack::Session::Memcache
48
- else
49
- pool
50
- end
51
- [pool, opts]
52
- end
53
- define_sessions_methods
54
- end
55
-
56
- def self.define_sessions_methods source = self
57
- return unless source.instance_variables.include?(:@__sessions__)
58
- sessions = source.instance_variable_get(:@__sessions__)
59
- define_method(:sessions) {sessions}
60
- end
61
-
62
- def sessions; end
63
- end
64
- end
@@ -1,118 +0,0 @@
1
- # Copyright (c) 2004-2015 David Heinemeier Hansson
2
- # Copyright (c) 2015 Slee Woo
3
- #
4
- # Permission is hereby granted, free of charge, to any person obtaining
5
- # a copy of this software and associated documentation files (the
6
- # "Software"), to deal in the Software without restriction, including
7
- # without limitation the rights to use, copy, modify, merge, publish,
8
- # distribute, sublicense, and/or sell copies of the Software, and to
9
- # permit persons to whom the Software is furnished to do so, subject to
10
- # the following conditions:
11
- #
12
- # The above copyright notice and this permission notice shall be
13
- # included in all copies or substantial portions of the Software.
14
- #
15
- # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
- # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
- # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
- # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
- # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
- # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
- # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
-
23
- module RocketIO
24
- module TokenAuth
25
- extend self
26
-
27
- TOKEN_KEY = 'token='.freeze
28
- TOKEN_REGEX = /^Token /
29
- AUTHN_PAIR_DELIMITERS = /(?:,|;|\t+)/
30
-
31
- HTTP_AUTHORIZATION = 'HTTP_AUTHORIZATION'.freeze
32
- X_HTTP_AUTHORIZATION_I = 'X-HTTP_AUTHORIZATION'.freeze
33
- X_HTTP_AUTHORIZATION_II = 'X_HTTP_AUTHORIZATION'.freeze
34
- REDIRECT_X_HTTP_AUTHORIZATION = 'REDIRECT_X_HTTP_AUTHORIZATION'.freeze
35
-
36
- WWW_AUTHENTICATE = 'WWW-Authenticate'.freeze
37
- TOKEN_REALM_FORMAT = 'Token realm="%s"'.freeze
38
- ACCESS_DENIED = "HTTP Token: Access denied.\n".freeze
39
-
40
- # If token Authorization header is present, call the login
41
- # procedure with the present token and options.
42
- #
43
- # @return the return value of given block if a token is found
44
- # @return nil if no token is found
45
- def authenticate env
46
- token, options = token_and_options(env)
47
- return if token.nil? || token.empty?
48
- yield(token, options)
49
- end
50
-
51
- # Parses the token and options out of the token authorization header. If
52
- # the header looks like this:
53
- # Authorization: Token token="abc", nonce="def"
54
- # Then the returned token is "abc", and the options is {nonce: "def"}
55
- #
56
- # @return [Array] if a token is present
57
- # @return nil if no token is found
58
- def token_and_options env
59
- return unless authorization_request = authorization?(env)
60
- return unless authorization_request[TOKEN_REGEX]
61
- params = token_params_from(authorization_request)
62
- [params.shift[1], RocketIO.indifferent_params(Hash[params])]
63
- end
64
-
65
- # Returns the authorization header regardless of whether it was specified directly or through one of the
66
- # proxy alternatives.
67
- def authorization? env
68
- env[HTTP_AUTHORIZATION] ||
69
- env[X_HTTP_AUTHORIZATION_I] ||
70
- env[X_HTTP_AUTHORIZATION_II] ||
71
- env[REDIRECT_X_HTTP_AUTHORIZATION]
72
- end
73
-
74
- def token_params_from auth
75
- rewrite_param_values(params_array_from(raw_params(auth)))
76
- end
77
-
78
- # Takes raw_params and turns it into an array of parameters
79
- #
80
- # @param raw_params [Array]
81
- # @return [Array]
82
- def params_array_from raw_params
83
- raw_params.map { |param| param.split %r/=(.+)?/ }
84
- end
85
-
86
- # This removes the `"` characters wrapping the value.
87
- #
88
- # @param array_params [Array]
89
- def rewrite_param_values array_params
90
- array_params.each { |param| (param[1] || "").gsub! %r/^"|"$/, '' }
91
- end
92
-
93
- # This method takes an authorization body and splits up the key-value
94
- # pairs by the standardized `:`, `;`, or `\t`
95
- #
96
- # @param auth [String]
97
- # @return [Array]
98
- def raw_params auth
99
- _raw_params = auth.sub(TOKEN_REGEX, '').split(/\s*#{AUTHN_PAIR_DELIMITERS}\s*/)
100
- unless _raw_params.first =~ %r{\A#{TOKEN_KEY}}
101
- _raw_params[0] = [TOKEN_KEY, _raw_params.first]*''
102
- end
103
- _raw_params
104
- end
105
-
106
- # Sets a WWW-Authenticate to let the client know a token is desired.
107
- #
108
- # @param realm [String]
109
- # @return [Array]
110
- def authentication_request realm
111
- [
112
- 401,
113
- {WWW_AUTHENTICATE => TOKEN_REALM_FORMAT % realm.tr('"', '')},
114
- [ACCESS_DENIED]
115
- ]
116
- end
117
- end
118
- end
@@ -1,21 +0,0 @@
1
- module RocketIO
2
- class Controller
3
-
4
- def websocket?
5
- @__is_websocket__ ||= websocket_connection? && websocket_upgrade? ? 1 : 0
6
- @__is_websocket__ == 1
7
- end
8
-
9
- def websocket_connection?
10
- env[RocketIO::HTTP_CONNECTION].to_s.downcase.split(/ *, */).include?(RocketIO::UPGRADE)
11
- end
12
-
13
- def websocket_upgrade?
14
- env[RocketIO::HTTP_UPGRADE].to_s.downcase == RocketIO::WEBSOCKET
15
- end
16
-
17
- def websocket_response
18
- [-1, {}, []]
19
- end
20
- end
21
- end
@@ -1,3 +0,0 @@
1
- <h1>404: Not Found</h1>
2
- <hr>
3
- <h2>"{{env.PATH_INFO}}" page is not here :(</h2>
@@ -1,7 +0,0 @@
1
- <h1>Wrong number of arguments received</h1>
2
- <h2>
3
- Controller: {{controller}}<br>
4
- Resolved Path: {{resolved_path}}<br>
5
- Expected Parameters: {{expected_parameters}}<br>
6
- Received Parameters: {{received_parameters}}<br>
7
- </h2>
@@ -1,3 +0,0 @@
1
- <h1>500: Fatal Error</h1>
2
- <hr>
3
- <h4>{{error.message}}</h4>
@@ -1,6 +0,0 @@
1
- <h1>501: Not Implemented</h1>
2
- <hr>
3
- <h2>
4
- "{{env.PATH_INFO}}" page found
5
- but it is not supposed to work through "{{env.REQUEST_METHOD}}" request method
6
- </h2>
@@ -1 +0,0 @@
1
- {{{ yield }}}
@@ -1,4 +0,0 @@
1
- module RocketIO
2
- class TemplateError < RuntimeError; end
3
- class LayoutError < RuntimeError; end
4
- end
@@ -1,65 +0,0 @@
1
- module RocketIO
2
- class Router
3
- ROOT_PATH_PIECES = [''.freeze].freeze
4
- attr_reader :controllers, :routes
5
-
6
- def initialize *controllers
7
- @controllers = controllers.flatten.compact.uniq
8
- @routes = build_routes
9
- freeze!
10
- end
11
-
12
- def resolve_path path
13
- controllers = @routes
14
- pieces = path_pieces(path)
15
- depth = -1
16
- controller = nil
17
- offset = 0
18
- while controllers = controllers[pieces[depth += 1]]
19
- next unless controllers[0]
20
- controller = controllers[0]
21
- offset = depth + 1
22
- end
23
- [controller, pieces[offset .. -1]]
24
- end
25
-
26
- private
27
- # split given path into an array
28
- #
29
- # @example /a/b/c
30
- # ["", a", "b", "c"]
31
- #
32
- # @param path [String]
33
- # @return [Array]
34
- #
35
- def path_pieces path
36
- return ROOT_PATH_PIECES if path == SLASH # that's root path, /
37
- path.to_s.split(/\/+/)
38
- end
39
-
40
- # building a routing tree
41
- #
42
- # @return [Hash]
43
- #
44
- def build_routes
45
- map = {}
46
- @controllers.each do |controller|
47
- [controller.url, *controller.aliases].each do |url|
48
- depth = 0
49
- pieces = path_pieces(url)
50
- pieces.inject(map) do |map,chunk|
51
- map[chunk] ||= {}
52
- map[chunk][0] = controller if pieces.size == (depth += 1)
53
- map[chunk]
54
- end
55
- end
56
- end
57
- map
58
- end
59
-
60
- # freezing the application cause modifying it at runtime may blow the universe
61
- def freeze!
62
- self.freeze
63
- end
64
- end
65
- end