gloo 3.1.1 → 3.3.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (52) hide show
  1. checksums.yaml +4 -4
  2. data/gloo.gemspec +1 -0
  3. data/lib/VERSION +1 -1
  4. data/lib/VERSION_NOTES +13 -0
  5. data/lib/gloo/app/log.rb +46 -6
  6. data/lib/gloo/app/platform.rb +7 -1
  7. data/lib/gloo/app/running_app.rb +42 -1
  8. data/lib/gloo/convert/falseclass_to_integer.rb +20 -0
  9. data/lib/gloo/convert/nilclass_to_date.rb +21 -0
  10. data/lib/gloo/convert/nilclass_to_datetime.rb +21 -0
  11. data/lib/gloo/convert/nilclass_to_integer.rb +21 -0
  12. data/lib/gloo/convert/nilclass_to_string.rb +21 -0
  13. data/lib/gloo/convert/nilclass_to_time.rb +21 -0
  14. data/lib/gloo/convert/trueclass_to_integer.rb +20 -0
  15. data/lib/gloo/core/error.rb +7 -0
  16. data/lib/gloo/core/it.rb +7 -0
  17. data/lib/gloo/core/obj.rb +41 -1
  18. data/lib/gloo/core/parser.rb +6 -3
  19. data/lib/gloo/exec/exec_env.rb +4 -0
  20. data/lib/gloo/exec/script.rb +9 -1
  21. data/lib/gloo/objs/basic/container.rb +18 -2
  22. data/lib/gloo/objs/basic/integer.rb +1 -0
  23. data/lib/gloo/objs/cli/menu.rb +9 -3
  24. data/lib/gloo/objs/{basic → ctrl}/function.rb +12 -0
  25. data/lib/gloo/objs/data/markdown.rb +60 -2
  26. data/lib/gloo/objs/data/mysql.rb +35 -7
  27. data/lib/gloo/objs/data/pg.rb +8 -0
  28. data/lib/gloo/objs/data/query.rb +66 -11
  29. data/lib/gloo/objs/data/query_result.rb +22 -1
  30. data/lib/gloo/objs/data/sqlite.rb +17 -2
  31. data/lib/gloo/objs/data/table.rb +143 -4
  32. data/lib/gloo/objs/web/json.rb +2 -0
  33. data/lib/gloo/objs/web_svr/element.rb +13 -5
  34. data/lib/gloo/objs/web_svr/page.rb +44 -2
  35. data/lib/gloo/objs/web_svr/partial.rb +7 -2
  36. data/lib/gloo/objs/web_svr/svr.rb +71 -4
  37. data/lib/gloo/verbs/break.rb +44 -0
  38. data/lib/gloo/verbs/create.rb +6 -0
  39. data/lib/gloo/verbs/invoke.rb +80 -0
  40. data/lib/gloo/verbs/log.rb +26 -5
  41. data/lib/gloo/verbs/redirect.rb +54 -6
  42. data/lib/gloo/web_svr/asset.rb +51 -23
  43. data/lib/gloo/web_svr/handler.rb +4 -2
  44. data/lib/gloo/web_svr/request.rb +35 -2
  45. data/lib/gloo/web_svr/routing/resource_router.rb +47 -0
  46. data/lib/gloo/web_svr/routing/router.rb +218 -0
  47. data/lib/gloo/web_svr/routing/show_routes.rb +98 -0
  48. data/lib/gloo/web_svr/server.rb +10 -2
  49. data/lib/gloo/web_svr/table_renderer.rb +147 -0
  50. data/lib/gloo/web_svr/web_method.rb +54 -0
  51. metadata +31 -4
  52. data/lib/gloo/web_svr/router.rb +0 -179
@@ -16,6 +16,10 @@ module Gloo
16
16
  HOST = 'host'.freeze
17
17
  PORT = 'port'.freeze
18
18
 
19
+ # SSL Configuration
20
+ SSL_CERT = 'ssl_cert'.freeze
21
+ SSL_KEY = 'ssl_key'.freeze
22
+
19
23
  # Events
20
24
  ON_START = 'on_start'.freeze
21
25
  ON_STOP = 'on_stop'.freeze
@@ -32,7 +36,7 @@ module Gloo
32
36
 
33
37
 
34
38
  # Messages
35
- SERVER_NOT_RUNNING = 'The web server is not running and cannot be stopped'.freeze
39
+ SERVER_NOT_RUNNING = 'The web server is not running!'.freeze
36
40
 
37
41
  #
38
42
  # Should the current request be redirected?
@@ -115,6 +119,56 @@ module Gloo
115
119
  return o
116
120
  end
117
121
 
122
+
123
+ # ---------------------------------------------------------------------
124
+ # SSL
125
+ # ---------------------------------------------------------------------
126
+
127
+ #
128
+ # Is SSL configured for this server?
129
+ # True if the Cert and Key are both present.
130
+ #
131
+ def use_ssl?
132
+ return ssl_cert && ssl_key
133
+ end
134
+
135
+ #
136
+ # Get the SSL certificate from the child object.
137
+ # Returns nil if there is none.
138
+ #
139
+ def ssl_cert
140
+ cert = find_child SSL_CERT
141
+ return nil unless cert
142
+
143
+ cert = Gloo::Objs::Alias.resolve_alias( @engine, cert )
144
+ return cert
145
+ end
146
+
147
+ #
148
+ # Get the SSL key from the child object.
149
+ # Returns nil if there is none.
150
+ #
151
+ def ssl_key
152
+ key = find_child SSL_KEY
153
+ return nil unless key
154
+
155
+ key = Gloo::Objs::Alias.resolve_alias( @engine, key )
156
+ return key
157
+ end
158
+
159
+ #
160
+ # Get the SSL configuration for the server.
161
+ #
162
+ def ssl_config
163
+ return nil unless use_ssl?
164
+
165
+ return {
166
+ :private_key_file => ssl_key.value,
167
+ :cert_chain_file => ssl_cert.value,
168
+ :verify_peer => false,
169
+ }
170
+ end
171
+
118
172
  # ---------------------------------------------------------------------
119
173
  # Children
120
174
  # ---------------------------------------------------------------------
@@ -156,7 +210,7 @@ module Gloo
156
210
  # Get a list of message names that this object receives.
157
211
  #
158
212
  def self.messages
159
- return super + [ 'start', 'stop' ]
213
+ return super + [ 'start', 'stop', 'routes' ]
160
214
  end
161
215
 
162
216
  #
@@ -183,6 +237,18 @@ module Gloo
183
237
  end
184
238
  end
185
239
 
240
+ #
241
+ # Helper message to show all routes in the running server.
242
+ #
243
+ def msg_routes
244
+ if @router
245
+ @router.show_routes
246
+ else
247
+ @engine.log.error SERVER_NOT_RUNNING
248
+ end
249
+ end
250
+
251
+
186
252
  # ---------------------------------------------------------------------
187
253
  # Start and Stop Events
188
254
  # Might come from messages or from other application events.
@@ -197,10 +263,10 @@ module Gloo
197
263
  @engine.log.info "Web Server URL: #{config.base_url}"
198
264
 
199
265
  handler = Gloo::WebSvr::Handler.new( @engine, self )
200
- @web_server = Gloo::WebSvr::Server.new( @engine, handler, config )
266
+ @web_server = Gloo::WebSvr::Server.new( @engine, handler, config, ssl_config )
201
267
  @web_server.start
202
268
 
203
- @router = Gloo::WebSvr::Router.new( @engine, self )
269
+ @router = Gloo::WebSvr::Routing::Router.new( @engine, self )
204
270
  @router.add_page_routes
205
271
 
206
272
  @asset = Gloo::WebSvr::Asset.new( @engine, self )
@@ -219,6 +285,7 @@ module Gloo
219
285
  @engine.log.info "Stopping web server…"
220
286
  @web_server.stop
221
287
  @web_server = nil
288
+ @router = nil
222
289
 
223
290
  run_on_stop
224
291
  @engine.log.info "Web server stopped…"
@@ -0,0 +1,44 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Break out of the script without error.
5
+ #
6
+
7
+ module Gloo
8
+ module Verbs
9
+ class Break < Gloo::Core::Verb
10
+
11
+ KEYWORD = 'break'.freeze
12
+ KEYWORD_SHORT = 'stop'.freeze
13
+
14
+ #
15
+ # Run the verb.
16
+ # Stop the execution of the current script.
17
+ #
18
+ def run
19
+ @engine.exec_env.running_script.break_out
20
+ end
21
+
22
+ #
23
+ # Get the Verb's keyword.
24
+ #
25
+ def self.keyword
26
+ return KEYWORD
27
+ end
28
+
29
+ #
30
+ # Get the Verb's keyword shortcut.
31
+ #
32
+ def self.keyword_shortcut
33
+ return KEYWORD_SHORT
34
+ end
35
+
36
+ # ---------------------------------------------------------------------
37
+ # Private functions
38
+ # ---------------------------------------------------------------------
39
+
40
+ private
41
+
42
+ end
43
+ end
44
+ end
@@ -57,6 +57,12 @@ module Gloo
57
57
  if Gloo::Expr::LString.string?( value )
58
58
  value = Gloo::Expr::LString.strip_quotes( value )
59
59
  end
60
+
61
+ # Check to see if this is an alias
62
+ pn = Gloo::Core::Pn.new( @engine, name )
63
+ obj = pn.resolve if pn
64
+ name = obj.value if obj&.is_alias?
65
+
60
66
  obj = @engine.factory.create( { name: name, type: type, value: value } )
61
67
 
62
68
  obj.add_default_children if obj&.add_children_on_create?
@@ -0,0 +1,80 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # Invoke a function from a script.
5
+ #
6
+
7
+ module Gloo
8
+ module Verbs
9
+ class Invoke < Gloo::Core::Verb
10
+
11
+ KEYWORD = 'invoke'.freeze
12
+ KEYWORD_SHORT = '~>'.freeze
13
+
14
+ #
15
+ # Run the verb.
16
+ #
17
+ def run
18
+ if @tokens.token_count > 1
19
+ ob = @tokens.first
20
+
21
+ # Get the function object
22
+ pn = Gloo::Core::Pn.new( @engine, @tokens.second )
23
+ func = pn.resolve
24
+
25
+ # Is the object a function?
26
+ if func&.is_function?
27
+ params = get_params_arr
28
+
29
+ @engine.log.debug "invoking function: #{func.pn}"
30
+ result = func.invoke( params )
31
+ @engine.log.debug "function returned: #{result}"
32
+ @engine.heap.it.set_to result
33
+ return result
34
+ end
35
+ end
36
+ end
37
+
38
+ #
39
+ # Get the Verb's keyword.
40
+ #
41
+ def self.keyword
42
+ return KEYWORD
43
+ end
44
+
45
+ #
46
+ # Get the Verb's keyword shortcut.
47
+ #
48
+ def self.keyword_shortcut
49
+ return KEYWORD_SHORT
50
+ end
51
+
52
+ # ---------------------------------------------------------------------
53
+ # Private functions
54
+ # ---------------------------------------------------------------------
55
+
56
+ private
57
+
58
+ #
59
+ # Get params array.
60
+ #
61
+ def get_params_arr
62
+ @engine.log.debug "token params: #{@tokens.params}"
63
+ params = @tokens.params[1..-1]
64
+
65
+ @engine.log.info "params: #{params}"
66
+ evaluated_params = []
67
+
68
+ params.each do |p|
69
+ expr = Gloo::Expr::Expression.new( @engine, [ p ] )
70
+ evaluated_params << expr.evaluate
71
+ end
72
+
73
+ @engine.log.debug "evaluated_params: #{evaluated_params}"
74
+
75
+ return evaluated_params
76
+ end
77
+
78
+ end
79
+ end
80
+ end
@@ -16,11 +16,11 @@ module Gloo
16
16
  #
17
17
  def run
18
18
  if @tokens.token_count > 1
19
- expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
20
- result = expr.evaluate
21
- level = log_level_specified( result )
22
- @engine.log.write result, level
23
- @engine.heap.it.set_to result
19
+ if is_clear_cmd?
20
+ @engine.log.clear
21
+ else
22
+ write_to_log
23
+ end
24
24
  else
25
25
  @engine.log.debug ''
26
26
  end
@@ -46,6 +46,27 @@ module Gloo
46
46
 
47
47
  private
48
48
 
49
+ #
50
+ # Write to the specified logger.
51
+ #
52
+ def write_to_log
53
+ expr = Gloo::Expr::Expression.new( @engine, @tokens.params )
54
+ result = expr.evaluate
55
+ level = log_level_specified( result )
56
+ @engine.log.write result, level
57
+ @engine.heap.it.set_to result
58
+ end
59
+
60
+ #
61
+ # Is this a clear logs command?
62
+ #
63
+ def is_clear_cmd?
64
+ return true if ( ( @tokens.token_count == 2 ) &&
65
+ ( @tokens.params.first == 'clear' ) )
66
+
67
+ return false
68
+ end
69
+
49
70
  #
50
71
  # Get the formatted string.
51
72
  #
@@ -12,7 +12,11 @@ module Gloo
12
12
  KEYWORD = 'redirect'.freeze
13
13
  KEYWORD_SHORT = 'go'.freeze
14
14
 
15
+ RUN_MESSAGE = 'run'.freeze
16
+
15
17
  MISSING_EXPR_ERR = 'Missing Expression!'.freeze
18
+ APP_NOT_RUNING_ERR = 'The application is not running!'.freeze
19
+ BAD_TARGET_ERR = 'Bad redirect target!'.freeze
16
20
 
17
21
  #
18
22
  # Run the verb.
@@ -23,12 +27,8 @@ module Gloo
23
27
  return
24
28
  end
25
29
 
26
- # Send the redirect page to the running app.
27
- if @engine.app_running?
28
- obj_name = @tokens.second
29
- pn = Gloo::Core::Pn.new( @engine, obj_name )
30
- @engine.running_app.obj.redirect = pn.resolve
31
- end
30
+ determine_target
31
+ redirect_to_target
32
32
  end
33
33
 
34
34
  #
@@ -51,6 +51,54 @@ module Gloo
51
51
 
52
52
  private
53
53
 
54
+ #
55
+ # Send the control to the redirect target.
56
+ # This could be a page or a script.
57
+ #
58
+ def redirect_to_target
59
+ if @target_obj.class == Gloo::Objs::Page
60
+ redirect_to_page
61
+ elsif @target_obj.can_receive_message?( RUN_MESSAGE )
62
+ redirect_to_script
63
+ else
64
+ @engine.err BAD_TARGET_ERR
65
+ end
66
+ end
67
+
68
+ #
69
+ # Find the target of the redirect.
70
+ #
71
+ def determine_target
72
+ obj_name = @tokens.second
73
+ pn = Gloo::Core::Pn.new( @engine, obj_name )
74
+
75
+ @target_obj = pn.resolve
76
+
77
+ @engine.log.info "obj type: #{@target_obj.class}"
78
+ end
79
+
80
+ #
81
+ # Redirect to a page.
82
+ # This requires a running web server.
83
+ #
84
+ def redirect_to_page
85
+ if @engine.app_running?
86
+ @engine.running_app.obj.redirect = @target_obj
87
+ else
88
+ @engine.err APP_NOT_RUNING_ERR
89
+ end
90
+ end
91
+
92
+ #
93
+ # Redirect to another script.
94
+ # This stops execution of the current script.
95
+ #
96
+ def redirect_to_script
97
+ @engine.exec_env.running_script.break_out
98
+
99
+ Gloo::Exec::Dispatch.message( @engine, RUN_MESSAGE, @target_obj )
100
+ end
101
+
54
102
  end
55
103
  end
56
104
  end
@@ -8,9 +8,10 @@ module Gloo
8
8
  module WebSvr
9
9
  class Asset
10
10
 
11
- ASSETS_FOLDER = 'assets'.freeze
12
- IMAGES_FOLDER = 'images'.freeze
13
- STYLESHEETS_FOLDER = 'stylesheets'.freeze
11
+ ASSET_FOLDER = 'asset'.freeze
12
+ IMAGE_FOLDER = 'image'.freeze
13
+ STYLESHEET_FOLDER = 'stylesheet'.freeze
14
+ JAVASCRIPT_FOLDER = 'javascript'.freeze
14
15
 
15
16
  CSS_TYPE = 'text/css'.freeze
16
17
  JS_TYPE = 'text/javascript'.freeze
@@ -41,22 +42,29 @@ module Gloo
41
42
  #
42
43
  # Get the asset folder in the project.
43
44
  #
44
- def assets_folder
45
- return File.join( @engine.settings.project_path, ASSETS_FOLDER )
45
+ def asset_folder
46
+ return File.join( @engine.settings.project_path, ASSET_FOLDER )
46
47
  end
47
48
 
48
49
  #
49
50
  # Get the images folder in the project.
50
51
  #
51
- def images_folder
52
- return File.join( assets_folder, IMAGES_FOLDER )
52
+ def image_folder
53
+ return File.join( asset_folder, IMAGE_FOLDER )
53
54
  end
54
55
 
55
56
  #
56
57
  # Get the stylesheets folder in the project.
57
58
  #
58
- def stylesheets_folder
59
- return File.join( assets_folder, STYLESHEETS_FOLDER )
59
+ def stylesheet_folder
60
+ return File.join( asset_folder, STYLESHEET_FOLDER )
61
+ end
62
+
63
+ #
64
+ # Get the stylesheets folder in the project.
65
+ #
66
+ def javascript_folder
67
+ return File.join( asset_folder, JAVASCRIPT_FOLDER )
60
68
  end
61
69
 
62
70
  #
@@ -69,7 +77,7 @@ module Gloo
69
77
  return pn if File.exist? pn
70
78
 
71
79
  # Look in the web server's asset folder.
72
- pn = File.join( assets_folder, pn )
80
+ pn = File.join( asset_folder, pn )
73
81
 
74
82
  return pn
75
83
  end
@@ -117,7 +125,7 @@ module Gloo
117
125
  # Add all asssets to the web server pages (routes).
118
126
  #
119
127
  def add_asset_routes
120
- return unless File.exist? assets_folder
128
+ return unless File.exist? asset_folder
121
129
 
122
130
  @log.debug 'Adding asset routes to web server…'
123
131
  @factory = @engine.factory
@@ -125,6 +133,7 @@ module Gloo
125
133
  add_containers
126
134
  add_images
127
135
  add_stylesheets
136
+ add_javascript
128
137
  end
129
138
 
130
139
  #
@@ -133,14 +142,17 @@ module Gloo
133
142
  def add_containers
134
143
  pages = @web_svr_obj.pages_container
135
144
 
136
- @assets = pages.find_child( ASSETS_FOLDER ) ||
137
- @factory.create_can( ASSETS_FOLDER, pages )
145
+ @assets = pages.find_child( ASSET_FOLDER ) ||
146
+ @factory.create_can( ASSET_FOLDER, pages )
147
+
148
+ @images = @assets.find_child( IMAGE_FOLDER ) ||
149
+ @factory.create_can( IMAGE_FOLDER, @assets )
138
150
 
139
- @images = @assets.find_child( IMAGES_FOLDER ) ||
140
- @factory.create_can( IMAGES_FOLDER, @assets )
151
+ @stylesheets = @assets.find_child( STYLESHEET_FOLDER ) ||
152
+ @factory.create_can( STYLESHEET_FOLDER, @assets )
141
153
 
142
- @stylesheets = @assets.find_child( STYLESHEETS_FOLDER ) ||
143
- @factory.create_can( STYLESHEETS_FOLDER, @assets )
154
+ @javascript = @assets.find_child( JAVASCRIPT_FOLDER ) ||
155
+ @factory.create_can( JAVASCRIPT_FOLDER, @assets )
144
156
  end
145
157
 
146
158
  #
@@ -149,12 +161,12 @@ module Gloo
149
161
  def add_images
150
162
  @log.debug 'Adding image asset routes to web server…'
151
163
 
152
- return unless File.exist? images_folder
164
+ return unless File.exist? image_folder
153
165
 
154
166
  # for each file in the images folder
155
167
  # create a file object and add it to the images container
156
- Dir.each_child( images_folder ) do |name|
157
- pn = File.join( IMAGES_FOLDER, name )
168
+ Dir.each_child( image_folder ) do |name|
169
+ pn = File.join( IMAGE_FOLDER, name )
158
170
  add_file_obj( @images, name, pn )
159
171
  end
160
172
  end
@@ -165,16 +177,32 @@ module Gloo
165
177
  def add_stylesheets
166
178
  @log.debug 'Adding stylesheet asset routes to web server…'
167
179
 
168
- return unless File.exist? stylesheets_folder
180
+ return unless File.exist? stylesheet_folder
169
181
 
170
182
  # for each file in the stylesheets folder
171
183
  # create a file object and add it to the stylesheets container
172
- Dir.each_child( stylesheets_folder ) do |name|
173
- pn = File.join( STYLESHEETS_FOLDER, name )
184
+ Dir.each_child( stylesheet_folder ) do |name|
185
+ pn = File.join( STYLESHEET_FOLDER, name )
174
186
  add_file_obj( @stylesheets, name, pn )
175
187
  end
176
188
  end
177
189
 
190
+ #
191
+ # Add the Javascript files to the web server pages.
192
+ #
193
+ def add_javascript
194
+ @log.debug 'Adding javascript asset routes to web server…'
195
+
196
+ return unless File.exist? javascript_folder
197
+
198
+ # for each file in the javascript folder
199
+ # create a file object and add it to the javascript container
200
+ Dir.each_child( javascript_folder ) do |name|
201
+ pn = File.join( JAVASCRIPT_FOLDER, name )
202
+ add_file_obj( @javascript, name, pn )
203
+ end
204
+ end
205
+
178
206
  #
179
207
  # Add a file object (page route) to the given container.
180
208
  #
@@ -36,7 +36,9 @@ module Gloo
36
36
  def handle request
37
37
  @request = request
38
38
 
39
- page = @server_obj.router.page_for_route @request.path
39
+ page, id = @server_obj.router.page_for_route( @request.path, @request.method )
40
+ @engine.log.debug "Found Page: #{page&.name}" if page
41
+ request.id = id
40
42
  if page
41
43
  if page.is_a? Gloo::Objs::FileHandle
42
44
  return handle_file page
@@ -53,7 +55,7 @@ module Gloo
53
55
  # Render the page, with possible redirect.
54
56
  #
55
57
  def handle_page page
56
- result = page.render
58
+ result = page.render @request
57
59
  if redirect_set?
58
60
  page = @engine.running_app.obj.redirect
59
61
  @log.debug "Redirecting to: #{page.pn}"
@@ -19,7 +19,8 @@ module Gloo
19
19
  HTTP_HOST = 'HTTP_HOST'.freeze
20
20
  QUERY_STRING = 'QUERY_STRING'.freeze
21
21
 
22
- attr_reader :method, :host, :path, :query
22
+ attr_reader :method, :host, :path, :query, :body
23
+ attr_accessor :id
23
24
 
24
25
 
25
26
  # ---------------------------------------------------------------------
@@ -66,6 +67,10 @@ module Gloo
66
67
  @path = @env[ REQUEST_PATH ]
67
68
  @host = @env[ HTTP_HOST ]
68
69
  @query = @env[ QUERY_STRING ]
70
+
71
+ @body = @env[ 'rack.input' ].read
72
+ @body = Rack::Utils.parse_query @body
73
+ check_body_method
69
74
  end
70
75
 
71
76
 
@@ -78,6 +83,7 @@ module Gloo
78
83
  #
79
84
  def start_timer
80
85
  @start = Time.now
86
+ @engine.running_app.reset_db_time
81
87
  end
82
88
 
83
89
  #
@@ -86,7 +92,8 @@ module Gloo
86
92
  def finish_timer
87
93
  @finish = Time.now
88
94
  @elapsed = ( ( @finish - @start ) * 1000.0 ).round(2)
89
- @log.info "Web request complete. Elapsed time: #{@elapsed} ms"
95
+ db = @engine.running_app.db_time
96
+ @log.info "*** Web request complete. DB: #{db} ms. Elapsed time: #{@elapsed} ms"
90
97
  end
91
98
 
92
99
 
@@ -94,12 +101,38 @@ module Gloo
94
101
  # Helper functions
95
102
  # ---------------------------------------------------------------------
96
103
 
104
+ #
105
+ # Check the body to see if there is a PATCH or a PUT in
106
+ # the method override.
107
+ #
108
+ def check_body_method
109
+ if @body[ '_method' ]
110
+ @method = @body[ '_method' ].upcase
111
+ end
112
+ end
113
+
114
+ #
115
+ # Get the hash of query parameters.
116
+ #
117
+ def query_params
118
+ return {} unless @query
119
+ return Rack::Utils.parse_query( @query )
120
+ end
121
+
122
+ #
123
+ # Get the hash of body parameters.
124
+ #
125
+ def body_params
126
+ return @body ? @body : {}
127
+ end
128
+
97
129
  #
98
130
  # Write the request information to the log.
99
131
  #
100
132
  def log
101
133
  @log.info "#{@method} #{@host}#{@path}"
102
134
  @log.info "Parameters: #{@query}"
135
+ @log.info "Body: #{@body}" unless @body.empty?
103
136
  end
104
137
 
105
138
  end
@@ -0,0 +1,47 @@
1
+ # Author:: Eric Crane (mailto:eric.crane@mac.com)
2
+ # Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
3
+ #
4
+ # A helper class for Resource routing.
5
+ #
6
+
7
+ module Gloo
8
+ module WebSvr
9
+ module Routing
10
+ class ResourceRouter
11
+
12
+ INDEX = 'index'.freeze
13
+ SHOW = 'show'.freeze
14
+ DELETE = 'delete'.freeze
15
+ UPDATE = 'update'.freeze
16
+
17
+ POST_ROUTE = 'create'.freeze
18
+
19
+
20
+ #
21
+ # Is the given route segment an implicit create resource?
22
+ # It is explicit if it is 'create'
23
+ # and implicit if it is a POST to the resource.
24
+ #
25
+ def self.is_implicit_create?( method, route_segment )
26
+ return false unless Gloo::WebSvr::WebMethod.is_post?( method )
27
+
28
+ return ! route_segment.eql?( POST_ROUTE )
29
+ end
30
+
31
+ #
32
+ # Add the segment based on the method.
33
+ #
34
+ def self.segment_for_method( method )
35
+ if Gloo::WebSvr::WebMethod.is_delete?( method )
36
+ return DELETE
37
+ elsif Gloo::WebSvr::WebMethod.is_patch?( method )
38
+ return UPDATE
39
+ else
40
+ return SHOW
41
+ end
42
+ end
43
+
44
+ end
45
+ end
46
+ end
47
+ end