ultra-lite-hub 0.0.1

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 (162) hide show
  1. checksums.yaml +7 -0
  2. data/roda-3.105.0/MIT-LICENSE +21 -0
  3. data/roda-3.105.0/lib/roda/cache.rb +42 -0
  4. data/roda-3.105.0/lib/roda/plugins/Integer_matcher_max.rb +55 -0
  5. data/roda-3.105.0/lib/roda/plugins/_after_hook.rb +11 -0
  6. data/roda-3.105.0/lib/roda/plugins/_base64.rb +34 -0
  7. data/roda-3.105.0/lib/roda/plugins/_before_hook.rb +41 -0
  8. data/roda-3.105.0/lib/roda/plugins/_optimized_matching.rb +227 -0
  9. data/roda-3.105.0/lib/roda/plugins/_symbol_class_matchers.rb +108 -0
  10. data/roda-3.105.0/lib/roda/plugins/_symbol_regexp_matchers.rb +24 -0
  11. data/roda-3.105.0/lib/roda/plugins/additional_render_engines.rb +61 -0
  12. data/roda-3.105.0/lib/roda/plugins/additional_view_directories.rb +66 -0
  13. data/roda-3.105.0/lib/roda/plugins/all_verbs.rb +50 -0
  14. data/roda-3.105.0/lib/roda/plugins/assets.rb +902 -0
  15. data/roda-3.105.0/lib/roda/plugins/assets_preloading.rb +89 -0
  16. data/roda-3.105.0/lib/roda/plugins/assume_ssl.rb +28 -0
  17. data/roda-3.105.0/lib/roda/plugins/autoload_hash_branches.rb +79 -0
  18. data/roda-3.105.0/lib/roda/plugins/autoload_named_routes.rb +65 -0
  19. data/roda-3.105.0/lib/roda/plugins/backtracking_array.rb +88 -0
  20. data/roda-3.105.0/lib/roda/plugins/bearer_token.rb +28 -0
  21. data/roda-3.105.0/lib/roda/plugins/branch_locals.rb +74 -0
  22. data/roda-3.105.0/lib/roda/plugins/break.rb +43 -0
  23. data/roda-3.105.0/lib/roda/plugins/caching.rb +206 -0
  24. data/roda-3.105.0/lib/roda/plugins/capture_erb.rb +94 -0
  25. data/roda-3.105.0/lib/roda/plugins/chunked.rb +331 -0
  26. data/roda-3.105.0/lib/roda/plugins/class_level_routing.rb +111 -0
  27. data/roda-3.105.0/lib/roda/plugins/class_matchers.rb +155 -0
  28. data/roda-3.105.0/lib/roda/plugins/common_logger.rb +80 -0
  29. data/roda-3.105.0/lib/roda/plugins/conditional_sessions.rb +67 -0
  30. data/roda-3.105.0/lib/roda/plugins/content_for.rb +103 -0
  31. data/roda-3.105.0/lib/roda/plugins/content_security_policy.rb +329 -0
  32. data/roda-3.105.0/lib/roda/plugins/cookie_flags.rb +157 -0
  33. data/roda-3.105.0/lib/roda/plugins/cookies.rb +51 -0
  34. data/roda-3.105.0/lib/roda/plugins/csrf.rb +81 -0
  35. data/roda-3.105.0/lib/roda/plugins/custom_block_results.rb +85 -0
  36. data/roda-3.105.0/lib/roda/plugins/custom_matchers.rb +89 -0
  37. data/roda-3.105.0/lib/roda/plugins/default_headers.rb +64 -0
  38. data/roda-3.105.0/lib/roda/plugins/default_status.rb +35 -0
  39. data/roda-3.105.0/lib/roda/plugins/delay_build.rb +18 -0
  40. data/roda-3.105.0/lib/roda/plugins/delegate.rb +77 -0
  41. data/roda-3.105.0/lib/roda/plugins/delete_empty_headers.rb +36 -0
  42. data/roda-3.105.0/lib/roda/plugins/direct_call.rb +38 -0
  43. data/roda-3.105.0/lib/roda/plugins/disallow_file_uploads.rb +38 -0
  44. data/roda-3.105.0/lib/roda/plugins/drop_body.rb +43 -0
  45. data/roda-3.105.0/lib/roda/plugins/each_part.rb +87 -0
  46. data/roda-3.105.0/lib/roda/plugins/early_hints.rb +25 -0
  47. data/roda-3.105.0/lib/roda/plugins/empty_root.rb +49 -0
  48. data/roda-3.105.0/lib/roda/plugins/environments.rb +79 -0
  49. data/roda-3.105.0/lib/roda/plugins/erb_h.rb +43 -0
  50. data/roda-3.105.0/lib/roda/plugins/error_email.rb +152 -0
  51. data/roda-3.105.0/lib/roda/plugins/error_handler.rb +133 -0
  52. data/roda-3.105.0/lib/roda/plugins/error_mail.rb +149 -0
  53. data/roda-3.105.0/lib/roda/plugins/exception_page.rb +445 -0
  54. data/roda-3.105.0/lib/roda/plugins/filter_common_logger.rb +46 -0
  55. data/roda-3.105.0/lib/roda/plugins/flash.rb +117 -0
  56. data/roda-3.105.0/lib/roda/plugins/h.rb +59 -0
  57. data/roda-3.105.0/lib/roda/plugins/halt.rb +108 -0
  58. data/roda-3.105.0/lib/roda/plugins/hash_branch_view_subdir.rb +76 -0
  59. data/roda-3.105.0/lib/roda/plugins/hash_branches.rb +145 -0
  60. data/roda-3.105.0/lib/roda/plugins/hash_matcher.rb +39 -0
  61. data/roda-3.105.0/lib/roda/plugins/hash_paths.rb +128 -0
  62. data/roda-3.105.0/lib/roda/plugins/hash_public.rb +125 -0
  63. data/roda-3.105.0/lib/roda/plugins/hash_public_cache.rb +91 -0
  64. data/roda-3.105.0/lib/roda/plugins/hash_routes.rb +304 -0
  65. data/roda-3.105.0/lib/roda/plugins/head.rb +99 -0
  66. data/roda-3.105.0/lib/roda/plugins/header_matchers.rb +88 -0
  67. data/roda-3.105.0/lib/roda/plugins/heartbeat.rb +41 -0
  68. data/roda-3.105.0/lib/roda/plugins/hmac_paths.rb +413 -0
  69. data/roda-3.105.0/lib/roda/plugins/hooks.rb +92 -0
  70. data/roda-3.105.0/lib/roda/plugins/host_authorization.rb +155 -0
  71. data/roda-3.105.0/lib/roda/plugins/host_routing.rb +190 -0
  72. data/roda-3.105.0/lib/roda/plugins/hsts.rb +35 -0
  73. data/roda-3.105.0/lib/roda/plugins/indifferent_params.rb +124 -0
  74. data/roda-3.105.0/lib/roda/plugins/inject_erb.rb +33 -0
  75. data/roda-3.105.0/lib/roda/plugins/invalid_request_body.rb +107 -0
  76. data/roda-3.105.0/lib/roda/plugins/ip_from_header.rb +34 -0
  77. data/roda-3.105.0/lib/roda/plugins/json.rb +119 -0
  78. data/roda-3.105.0/lib/roda/plugins/json_parser.rb +107 -0
  79. data/roda-3.105.0/lib/roda/plugins/link_to.rb +83 -0
  80. data/roda-3.105.0/lib/roda/plugins/mail_processor.rb +629 -0
  81. data/roda-3.105.0/lib/roda/plugins/mailer.rb +283 -0
  82. data/roda-3.105.0/lib/roda/plugins/map_matcher.rb +48 -0
  83. data/roda-3.105.0/lib/roda/plugins/match_affix.rb +64 -0
  84. data/roda-3.105.0/lib/roda/plugins/match_hook.rb +34 -0
  85. data/roda-3.105.0/lib/roda/plugins/match_hook_args.rb +93 -0
  86. data/roda-3.105.0/lib/roda/plugins/middleware.rb +225 -0
  87. data/roda-3.105.0/lib/roda/plugins/middleware_stack.rb +101 -0
  88. data/roda-3.105.0/lib/roda/plugins/module_include.rb +96 -0
  89. data/roda-3.105.0/lib/roda/plugins/multi_public.rb +95 -0
  90. data/roda-3.105.0/lib/roda/plugins/multi_route.rb +156 -0
  91. data/roda-3.105.0/lib/roda/plugins/multi_run.rb +144 -0
  92. data/roda-3.105.0/lib/roda/plugins/multi_view.rb +83 -0
  93. data/roda-3.105.0/lib/roda/plugins/multibyte_string_matcher.rb +57 -0
  94. data/roda-3.105.0/lib/roda/plugins/named_routes.rb +167 -0
  95. data/roda-3.105.0/lib/roda/plugins/named_templates.rb +102 -0
  96. data/roda-3.105.0/lib/roda/plugins/not_allowed.rb +149 -0
  97. data/roda-3.105.0/lib/roda/plugins/not_found.rb +55 -0
  98. data/roda-3.105.0/lib/roda/plugins/optimized_segment_matchers.rb +53 -0
  99. data/roda-3.105.0/lib/roda/plugins/optimized_string_matchers.rb +50 -0
  100. data/roda-3.105.0/lib/roda/plugins/padrino_render.rb +42 -0
  101. data/roda-3.105.0/lib/roda/plugins/param_matchers.rb +83 -0
  102. data/roda-3.105.0/lib/roda/plugins/params_capturing.rb +116 -0
  103. data/roda-3.105.0/lib/roda/plugins/part.rb +76 -0
  104. data/roda-3.105.0/lib/roda/plugins/partials.rb +74 -0
  105. data/roda-3.105.0/lib/roda/plugins/pass.rb +47 -0
  106. data/roda-3.105.0/lib/roda/plugins/path.rb +255 -0
  107. data/roda-3.105.0/lib/roda/plugins/path_matchers.rb +54 -0
  108. data/roda-3.105.0/lib/roda/plugins/path_rewriter.rb +111 -0
  109. data/roda-3.105.0/lib/roda/plugins/permissions_policy.rb +336 -0
  110. data/roda-3.105.0/lib/roda/plugins/placeholder_string_matchers.rb +48 -0
  111. data/roda-3.105.0/lib/roda/plugins/plain_hash_response_headers.rb +32 -0
  112. data/roda-3.105.0/lib/roda/plugins/precompile_templates.rb +156 -0
  113. data/roda-3.105.0/lib/roda/plugins/public.rb +182 -0
  114. data/roda-3.105.0/lib/roda/plugins/r.rb +35 -0
  115. data/roda-3.105.0/lib/roda/plugins/recheck_precompiled_assets.rb +107 -0
  116. data/roda-3.105.0/lib/roda/plugins/redirect_http_to_https.rb +99 -0
  117. data/roda-3.105.0/lib/roda/plugins/redirect_path.rb +59 -0
  118. data/roda-3.105.0/lib/roda/plugins/relative_path.rb +74 -0
  119. data/roda-3.105.0/lib/roda/plugins/render.rb +998 -0
  120. data/roda-3.105.0/lib/roda/plugins/render_coverage.rb +105 -0
  121. data/roda-3.105.0/lib/roda/plugins/render_each.rb +224 -0
  122. data/roda-3.105.0/lib/roda/plugins/render_locals.rb +102 -0
  123. data/roda-3.105.0/lib/roda/plugins/request_aref.rb +77 -0
  124. data/roda-3.105.0/lib/roda/plugins/request_headers.rb +81 -0
  125. data/roda-3.105.0/lib/roda/plugins/response_attachment.rb +94 -0
  126. data/roda-3.105.0/lib/roda/plugins/response_content_type.rb +79 -0
  127. data/roda-3.105.0/lib/roda/plugins/response_request.rb +29 -0
  128. data/roda-3.105.0/lib/roda/plugins/route_block_args.rb +50 -0
  129. data/roda-3.105.0/lib/roda/plugins/route_csrf.rb +388 -0
  130. data/roda-3.105.0/lib/roda/plugins/run_append_slash.rb +51 -0
  131. data/roda-3.105.0/lib/roda/plugins/run_handler.rb +51 -0
  132. data/roda-3.105.0/lib/roda/plugins/run_require_slash.rb +46 -0
  133. data/roda-3.105.0/lib/roda/plugins/sec_fetch_site_csrf.rb +131 -0
  134. data/roda-3.105.0/lib/roda/plugins/send_file.rb +127 -0
  135. data/roda-3.105.0/lib/roda/plugins/sessions.rb +537 -0
  136. data/roda-3.105.0/lib/roda/plugins/shared_vars.rb +86 -0
  137. data/roda-3.105.0/lib/roda/plugins/sinatra_helpers.rb +443 -0
  138. data/roda-3.105.0/lib/roda/plugins/slash_path_empty.rb +26 -0
  139. data/roda-3.105.0/lib/roda/plugins/static.rb +42 -0
  140. data/roda-3.105.0/lib/roda/plugins/static_routing.rb +89 -0
  141. data/roda-3.105.0/lib/roda/plugins/status_303.rb +34 -0
  142. data/roda-3.105.0/lib/roda/plugins/status_handler.rb +86 -0
  143. data/roda-3.105.0/lib/roda/plugins/streaming.rb +170 -0
  144. data/roda-3.105.0/lib/roda/plugins/strip_path_prefix.rb +33 -0
  145. data/roda-3.105.0/lib/roda/plugins/symbol_matchers.rb +188 -0
  146. data/roda-3.105.0/lib/roda/plugins/symbol_status.rb +32 -0
  147. data/roda-3.105.0/lib/roda/plugins/symbol_views.rb +37 -0
  148. data/roda-3.105.0/lib/roda/plugins/timestamp_public.rb +78 -0
  149. data/roda-3.105.0/lib/roda/plugins/type_routing.rb +215 -0
  150. data/roda-3.105.0/lib/roda/plugins/typecast_params.rb +1183 -0
  151. data/roda-3.105.0/lib/roda/plugins/typecast_params_sized_integers.rb +108 -0
  152. data/roda-3.105.0/lib/roda/plugins/unescape_path.rb +41 -0
  153. data/roda-3.105.0/lib/roda/plugins/view_options.rb +201 -0
  154. data/roda-3.105.0/lib/roda/plugins/view_subdir_leading_slash.rb +49 -0
  155. data/roda-3.105.0/lib/roda/plugins.rb +68 -0
  156. data/roda-3.105.0/lib/roda/request.rb +722 -0
  157. data/roda-3.105.0/lib/roda/response.rb +221 -0
  158. data/roda-3.105.0/lib/roda/session_middleware.rb +183 -0
  159. data/roda-3.105.0/lib/roda/version.rb +18 -0
  160. data/roda-3.105.0/lib/roda.rb +586 -0
  161. data/ultra-lite-hub.gemspec +12 -0
  162. metadata +201 -0
@@ -0,0 +1,221 @@
1
+ # frozen-string-literal: true
2
+
3
+ begin
4
+ require 'rack/headers'
5
+ rescue LoadError
6
+ end
7
+
8
+ class Roda
9
+ # Contains constants for response headers. This approach is used so that all
10
+ # headers used internally by Roda can be lower case on Rack 3, so that it is
11
+ # possible to use a plain hash of response headers instead of using Rack::Headers.
12
+ module RodaResponseHeaders
13
+ downcase = defined?(Rack::Headers) && Rack::Headers.is_a?(Class)
14
+
15
+ %w'Allow Cache-Control Content-Disposition Content-Encoding Content-Length
16
+ Content-Security-Policy Content-Security-Policy-Report-Only Content-Type
17
+ ETag Expires Last-Modified Link Location Set-Cookie Transfer-Encoding Vary
18
+ Permissions-Policy Permissions-Policy-Report-Only Strict-Transport-Security'.
19
+ each do |value|
20
+ value = value.downcase if downcase
21
+ const_set(value.tr('-', '_').upcase!.to_sym, value.freeze)
22
+ end
23
+ end
24
+
25
+ # Base class used for Roda responses. The instance methods for this
26
+ # class are added by Roda::RodaPlugins::Base::ResponseMethods, the class
27
+ # methods are added by Roda::RodaPlugins::Base::ResponseClassMethods.
28
+ class RodaResponse
29
+ @roda_class = ::Roda
30
+ end
31
+
32
+ module RodaPlugins
33
+ module Base
34
+ # Class methods for RodaResponse
35
+ module ResponseClassMethods
36
+ # Reference to the Roda class related to this response class.
37
+ attr_accessor :roda_class
38
+
39
+ # Since RodaResponse is anonymously subclassed when Roda is subclassed,
40
+ # and then assigned to a constant of the Roda subclass, make inspect
41
+ # reflect the likely name for the class.
42
+ def inspect
43
+ "#{roda_class.inspect}::RodaResponse"
44
+ end
45
+ end
46
+
47
+ # Instance methods for RodaResponse
48
+ module ResponseMethods
49
+ # The body for the current response.
50
+ attr_reader :body
51
+
52
+ # The hash of response headers for the current response.
53
+ attr_reader :headers
54
+
55
+ # The status code to use for the response. If none is given, will use 200
56
+ # code for non-empty responses and a 404 code for empty responses.
57
+ attr_accessor :status
58
+
59
+ # Set the default headers when creating a response.
60
+ def initialize
61
+ @headers = _initialize_headers
62
+ @body = []
63
+ @length = 0
64
+ end
65
+
66
+ # Return the response header with the given key. Example:
67
+ #
68
+ # response['Content-Type'] # => 'text/html'
69
+ def [](key)
70
+ @headers[key]
71
+ end
72
+
73
+ # Set the response header with the given key to the given value.
74
+ #
75
+ # response['Content-Type'] = 'application/json'
76
+ def []=(key, value)
77
+ @headers[key] = value
78
+ end
79
+
80
+ # The default headers to use for responses.
81
+ def default_headers
82
+ DEFAULT_HEADERS
83
+ end
84
+
85
+ # Whether the response body has been written to yet. Note
86
+ # that writing an empty string to the response body marks
87
+ # the response as not empty. Example:
88
+ #
89
+ # response.empty? # => true
90
+ # response.write('a')
91
+ # response.empty? # => false
92
+ def empty?
93
+ @body.empty?
94
+ end
95
+
96
+ # Return the rack response array of status, headers, and body
97
+ # for the current response. If the status has not been set,
98
+ # uses the return value of default_status if the body has
99
+ # been written to, otherwise uses a 404 status.
100
+ # Adds the Content-Length header to the size of the response body.
101
+ #
102
+ # Example:
103
+ #
104
+ # response.finish
105
+ # # => [200,
106
+ # # {'Content-Type'=>'text/html', 'Content-Length'=>'0'},
107
+ # # []]
108
+ def finish
109
+ b = @body
110
+ set_default_headers
111
+ h = @headers
112
+
113
+ if b.empty?
114
+ s = @status || 404
115
+ if (s == 304 || s == 204 || (s >= 100 && s <= 199))
116
+ h.delete(RodaResponseHeaders::CONTENT_TYPE)
117
+ elsif s == 205
118
+ empty_205_headers(h)
119
+ else
120
+ h[RodaResponseHeaders::CONTENT_LENGTH] ||= '0'
121
+ end
122
+ else
123
+ s = @status || default_status
124
+ h[RodaResponseHeaders::CONTENT_LENGTH] ||= @length.to_s
125
+ end
126
+
127
+ [s, h, b]
128
+ end
129
+
130
+ # Return the rack response array using a given body. Assumes a
131
+ # 200 response status unless status has been explicitly set,
132
+ # and doesn't add the Content-Length header or use the existing
133
+ # body.
134
+ def finish_with_body(body)
135
+ set_default_headers
136
+ [@status || default_status, @headers, body]
137
+ end
138
+
139
+ # Return the default response status to be used when the body
140
+ # has been written to. This is split out to make overriding
141
+ # easier in plugins.
142
+ def default_status
143
+ 200
144
+ end
145
+
146
+ # Show response class, status code, response headers, and response body
147
+ def inspect
148
+ "#<#{self.class.inspect} #{@status.inspect} #{@headers.inspect} #{@body.inspect}>"
149
+ end
150
+
151
+ # Set the Location header to the given path, and the status
152
+ # to the given status. Example:
153
+ #
154
+ # response.redirect('foo', 301)
155
+ # response.redirect('bar')
156
+ def redirect(path, status = 302)
157
+ @headers[RodaResponseHeaders::LOCATION] = path
158
+ @status = status
159
+ nil
160
+ end
161
+
162
+ # Return the Roda class related to this response.
163
+ def roda_class
164
+ self.class.roda_class
165
+ end
166
+
167
+ # Write to the response body. Returns nil.
168
+ #
169
+ # response.write('foo')
170
+ def write(str)
171
+ s = str.to_s
172
+ @length += s.bytesize
173
+ @body << s
174
+ nil
175
+ end
176
+
177
+ private
178
+
179
+ if defined?(Rack::Headers) && Rack::Headers.is_a?(Class)
180
+ DEFAULT_HEADERS = Rack::Headers[{RodaResponseHeaders::CONTENT_TYPE => "text/html".freeze}].freeze
181
+
182
+ # Use Rack::Headers for headers by default on Rack 3
183
+ def _initialize_headers
184
+ Rack::Headers.new
185
+ end
186
+ else
187
+ DEFAULT_HEADERS = {RodaResponseHeaders::CONTENT_TYPE => "text/html".freeze}.freeze
188
+
189
+ # Use plain hash for headers by default on Rack 1-2
190
+ def _initialize_headers
191
+ {}
192
+ end
193
+ end
194
+
195
+ if Rack.release < '2.0.2'
196
+ # Don't use a content length for empty 205 responses on
197
+ # rack 1, as it violates Rack::Lint in that version.
198
+ def empty_205_headers(headers)
199
+ headers.delete(RodaResponseHeaders::CONTENT_TYPE)
200
+ headers.delete(RodaResponseHeaders::CONTENT_LENGTH)
201
+ end
202
+ else
203
+ # Set the content length for empty 205 responses to 0
204
+ def empty_205_headers(headers)
205
+ headers.delete(RodaResponseHeaders::CONTENT_TYPE)
206
+ headers[RodaResponseHeaders::CONTENT_LENGTH] = '0'
207
+ end
208
+ end
209
+
210
+ # For each default header, if a header has not already been set for the
211
+ # response, set the header in the response.
212
+ def set_default_headers
213
+ h = @headers
214
+ default_headers.each do |k,v|
215
+ h[k] ||= v
216
+ end
217
+ end
218
+ end
219
+ end
220
+ end
221
+ end
@@ -0,0 +1,183 @@
1
+ # frozen-string-literal: true
2
+
3
+ require_relative '../roda'
4
+ require_relative 'plugins/sessions'
5
+
6
+ # Session middleware that can be used in any Rack application
7
+ # that uses Roda's sessions plugin for encrypted and signed cookies.
8
+ # See Roda::RodaPlugins::Sessions for details on options.
9
+ class RodaSessionMiddleware
10
+ # Class to hold session data. This is designed to mimic the API
11
+ # of Rack::Session::Abstract::SessionHash, but is simpler and faster.
12
+ # Undocumented methods operate the same as hash methods, but load the
13
+ # session from the cookie if it hasn't been loaded yet, and convert
14
+ # keys to strings.
15
+ #
16
+ # One difference between SessionHash and Rack::Session::Abstract::SessionHash
17
+ # is that SessionHash does not attempt to setup a session id, since
18
+ # one is not needed for cookie-based sessions, only for sessions
19
+ # that are loaded out of a database. If you need to have a session id
20
+ # for other reasons, manually create a session id using a randomly generated
21
+ # string.
22
+ class SessionHash
23
+ # The Roda::RodaRequest subclass instance related to the session.
24
+ attr_reader :req
25
+
26
+ # The underlying data hash, or nil if the session has not yet been
27
+ # loaded.
28
+ attr_reader :data
29
+
30
+ def initialize(req)
31
+ @req = req
32
+ end
33
+
34
+ # The Roda sessions plugin options used by the middleware for this
35
+ # session hash.
36
+ def options
37
+ @req.roda_class.opts[:sessions]
38
+ end
39
+
40
+ def each(&block)
41
+ load!
42
+ @data.each(&block)
43
+ end
44
+
45
+ def [](key)
46
+ load!
47
+ @data[key.to_s]
48
+ end
49
+
50
+ def fetch(key, default = (no_default = true), &block)
51
+ load!
52
+ if no_default
53
+ @data.fetch(key.to_s, &block)
54
+ else
55
+ @data.fetch(key.to_s, default, &block)
56
+ end
57
+ end
58
+
59
+ def has_key?(key)
60
+ load!
61
+ @data.has_key?(key.to_s)
62
+ end
63
+ alias :key? :has_key?
64
+ alias :include? :has_key?
65
+
66
+ def []=(key, value)
67
+ load!
68
+ @data[key.to_s] = value
69
+ end
70
+ alias :store :[]=
71
+
72
+ # Clear the session, also removing a couple of roda session
73
+ # keys from the environment so that the related cookie will
74
+ # either be set or cleared in the rack response.
75
+ def clear
76
+ load!
77
+ env = @req.env
78
+ env.delete('roda.session.created_at')
79
+ env.delete('roda.session.updated_at')
80
+ @data.clear
81
+ end
82
+ alias :destroy :clear
83
+
84
+ def to_hash
85
+ load!
86
+ @data.dup
87
+ end
88
+
89
+ def update(hash)
90
+ load!
91
+ hash.each do |key, value|
92
+ @data[key.to_s] = value
93
+ end
94
+ @data
95
+ end
96
+ alias :merge! :update
97
+
98
+ def replace(hash)
99
+ load!
100
+ @data.clear
101
+ update(hash)
102
+ end
103
+
104
+ def delete(key)
105
+ load!
106
+ @data.delete(key.to_s)
107
+ end
108
+
109
+ # If the session hasn't been loaded, display that.
110
+ def inspect
111
+ if loaded?
112
+ @data.inspect
113
+ else
114
+ "#<#{self.class}:0x#{self.object_id.to_s(16)} not yet loaded>"
115
+ end
116
+ end
117
+
118
+ # Return whether the session cookie already exists.
119
+ # If this is false, then the session was set to an empty hash.
120
+ def exists?
121
+ load!
122
+ req.env.has_key?('roda.session.serialized')
123
+ end
124
+
125
+ # Whether the session has already been loaded from the cookie yet.
126
+ def loaded?
127
+ !!defined?(@data)
128
+ end
129
+
130
+ def empty?
131
+ load!
132
+ @data.empty?
133
+ end
134
+
135
+ def keys
136
+ load!
137
+ @data.keys
138
+ end
139
+
140
+ def values
141
+ load!
142
+ @data.values
143
+ end
144
+
145
+ private
146
+
147
+ # Load the session from the cookie.
148
+ def load!
149
+ @data ||= @req.send(:_load_session)
150
+ end
151
+ end
152
+
153
+ module RequestMethods
154
+ # Work around for if type_routing plugin is loaded into Roda class itself.
155
+ def _remaining_path(_)
156
+ end
157
+ end
158
+
159
+ # Setup the middleware, passing +opts+ as the Roda sessions plugin options.
160
+ def initialize(app, opts)
161
+ mid = Class.new(Roda)
162
+ Roda::RodaPlugins.set_temp_name(mid){"RodaSessionMiddleware::_RodaSubclass"}
163
+ mid.plugin :sessions, opts
164
+ @req_class = mid::RodaRequest
165
+ @req_class.send(:include, RequestMethods)
166
+ @app = app
167
+ end
168
+
169
+ # Initialize the session hash in the environment before calling the next
170
+ # application, and if the session has been loaded after the result has been
171
+ # returned, then persist the session in the cookie.
172
+ def call(env)
173
+ session = env['rack.session'] = SessionHash.new(@req_class.new(nil, env))
174
+
175
+ res = @app.call(env)
176
+
177
+ if session.loaded?
178
+ session.req.persist_session(res[1], session.data)
179
+ end
180
+
181
+ res
182
+ end
183
+ end
@@ -0,0 +1,18 @@
1
+ class Roda
2
+ # The major version of Roda, updated only for major changes that are
3
+ # likely to require modification to Roda apps.
4
+ RodaMajorVersion = 3
5
+
6
+ # The minor version of Roda, updated for new feature releases of Roda.
7
+ RodaMinorVersion = 105
8
+
9
+ # The patch version of Roda, updated only for bug fixes from the last
10
+ # feature release.
11
+ RodaPatchVersion = 0
12
+
13
+ # The full version of Roda as a string.
14
+ RodaVersion = "#{RodaMajorVersion}.#{RodaMinorVersion}.#{RodaPatchVersion}".freeze
15
+
16
+ # The full version of Roda as a number (3.7.0 => 30070)
17
+ RodaVersionNumber = RodaMajorVersion*10000 + RodaMinorVersion*10 + RodaPatchVersion
18
+ end