gloo 4.7.0 → 5.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.
- checksums.yaml +4 -4
- data/LICENSE.txt +1 -1
- data/gloo.gemspec +22 -11
- data/lib/VERSION +1 -1
- data/lib/VERSION_NOTES +11 -0
- data/lib/gloo/app/engine.rb +3 -2
- data/lib/gloo/app/running_app.rb +13 -0
- data/lib/gloo/core/dictionary.rb +13 -2
- data/lib/gloo/objs/ctrl/each.rb +2 -2
- data/lib/gloo/{ext → plugin}/base.rb +1 -1
- data/lib/gloo/{ext → plugin}/callback.rb +2 -3
- data/lib/gloo/{ext/manager.rb → plugin/ext_manager.rb} +2 -2
- data/lib/gloo/plugin/lib_manager.rb +97 -0
- data/lib/gloo/verbs/exists.rb +74 -0
- data/lib/gloo/verbs/help.rb +28 -0
- data/lib/gloo/verbs/load.rb +8 -2
- data/lib/gloo/verbs/redirect.rb +2 -1
- metadata +38 -164
- data/lib/gloo/objs/cli/colorize.rb +0 -73
- data/lib/gloo/objs/cli/confirm.rb +0 -96
- data/lib/gloo/objs/cli/menu.rb +0 -370
- data/lib/gloo/objs/cli/menu_item.rb +0 -95
- data/lib/gloo/objs/cli/prompt.rb +0 -110
- data/lib/gloo/objs/cli/select.rb +0 -127
- data/lib/gloo/objs/ctrl/each_repo.rb +0 -84
- data/lib/gloo/objs/data/markdown.rb +0 -133
- data/lib/gloo/objs/data/markdown_ext.rb +0 -260
- data/lib/gloo/objs/data/mysql.rb +0 -254
- data/lib/gloo/objs/data/query.rb +0 -269
- data/lib/gloo/objs/data/query_result.rb +0 -158
- data/lib/gloo/objs/data/sqlite.rb +0 -174
- data/lib/gloo/objs/data/table.rb +0 -267
- data/lib/gloo/objs/dev/git.rb +0 -140
- data/lib/gloo/objs/dev/stats.rb +0 -123
- data/lib/gloo/objs/system/ssh_exec.rb +0 -126
- data/lib/gloo/objs/web_svr/element.rb +0 -254
- data/lib/gloo/objs/web_svr/field.rb +0 -429
- data/lib/gloo/objs/web_svr/form.rb +0 -271
- data/lib/gloo/objs/web_svr/page.rb +0 -562
- data/lib/gloo/objs/web_svr/partial.rb +0 -210
- data/lib/gloo/objs/web_svr/svr.rb +0 -713
- data/lib/gloo/utils/stats.rb +0 -206
- data/lib/gloo/web_svr/asset.rb +0 -407
- data/lib/gloo/web_svr/asset_info.rb +0 -116
- data/lib/gloo/web_svr/config.rb +0 -56
- data/lib/gloo/web_svr/embedded_renderer.rb +0 -154
- data/lib/gloo/web_svr/handler.rb +0 -154
- data/lib/gloo/web_svr/request.rb +0 -143
- data/lib/gloo/web_svr/request_params.rb +0 -181
- data/lib/gloo/web_svr/response.rb +0 -177
- data/lib/gloo/web_svr/response_code.rb +0 -69
- data/lib/gloo/web_svr/routing/resource_router.rb +0 -47
- data/lib/gloo/web_svr/routing/router.rb +0 -232
- data/lib/gloo/web_svr/routing/show_routes.rb +0 -94
- data/lib/gloo/web_svr/server.rb +0 -105
- data/lib/gloo/web_svr/session.rb +0 -215
- data/lib/gloo/web_svr/table_renderer.rb +0 -151
- data/lib/gloo/web_svr/web_method.rb +0 -54
- /data/lib/gloo/objs/{security → str_utils}/cipher.rb +0 -0
- /data/lib/gloo/objs/{security → str_utils}/csrf_token.rb +0 -0
- /data/lib/gloo/objs/{security → str_utils}/password.rb +0 -0
- /data/lib/gloo/objs/{ror → system}/erb.rb +0 -0
- /data/lib/gloo/objs/{ror → system}/eval.rb +0 -0
|
@@ -1,181 +0,0 @@
|
|
|
1
|
-
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
-
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
|
3
|
-
#
|
|
4
|
-
# A Parameters associated with a request.
|
|
5
|
-
#
|
|
6
|
-
# Kinds of Params
|
|
7
|
-
# Id - The entity id
|
|
8
|
-
# Key - URL parameter key
|
|
9
|
-
# URL Params - Parameters in the URL
|
|
10
|
-
# Body Params - Data from the body of the request
|
|
11
|
-
#
|
|
12
|
-
|
|
13
|
-
module Gloo
|
|
14
|
-
module WebSvr
|
|
15
|
-
class RequestParams
|
|
16
|
-
|
|
17
|
-
attr_accessor :id, :route_params
|
|
18
|
-
attr_reader :query_params, :body_params, :body_binary
|
|
19
|
-
|
|
20
|
-
# ---------------------------------------------------------------------
|
|
21
|
-
# Initialization
|
|
22
|
-
# ---------------------------------------------------------------------
|
|
23
|
-
|
|
24
|
-
#
|
|
25
|
-
# Set up the web server.
|
|
26
|
-
#
|
|
27
|
-
def initialize( log )
|
|
28
|
-
@log = log
|
|
29
|
-
end
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
# ---------------------------------------------------------------------
|
|
33
|
-
# Value Detection
|
|
34
|
-
# ---------------------------------------------------------------------
|
|
35
|
-
|
|
36
|
-
#
|
|
37
|
-
# Detect the parameters from query string.
|
|
38
|
-
#
|
|
39
|
-
def init_query_params query_string
|
|
40
|
-
if query_string
|
|
41
|
-
@query_params = Rack::Utils.parse_query( query_string )
|
|
42
|
-
else
|
|
43
|
-
@query_params = {}
|
|
44
|
-
end
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
#
|
|
48
|
-
# Detect the parameters from the body of the request.
|
|
49
|
-
#
|
|
50
|
-
def init_body_params body
|
|
51
|
-
if body && body.length > 0
|
|
52
|
-
# if body is binary, then it is not a query string
|
|
53
|
-
begin
|
|
54
|
-
@body_params = Rack::Utils.parse_query body
|
|
55
|
-
rescue => exception
|
|
56
|
-
init_multipart body
|
|
57
|
-
end
|
|
58
|
-
else
|
|
59
|
-
@body_params = {}
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
#
|
|
64
|
-
# Set the body to a binary file.
|
|
65
|
-
#
|
|
66
|
-
# TODO: find a lib or method to handle this.
|
|
67
|
-
# This is very rough and will need to be fixed.
|
|
68
|
-
#
|
|
69
|
-
def init_multipart body
|
|
70
|
-
# puts "*********** first lines: *********** "
|
|
71
|
-
# body.lines[0..3].each { |line| puts line }
|
|
72
|
-
# puts "*********** last lines: *********** "
|
|
73
|
-
# body.lines.last(5).each { |line| puts line }
|
|
74
|
-
# puts "************************************"
|
|
75
|
-
|
|
76
|
-
# boundary = body.lines.first
|
|
77
|
-
# puts "boundary: #{boundary}"
|
|
78
|
-
|
|
79
|
-
header = body.lines[1..3].join
|
|
80
|
-
# puts "header: #{header}"
|
|
81
|
-
|
|
82
|
-
footer = body.lines.last(5).join
|
|
83
|
-
# puts "footer: #{footer}"
|
|
84
|
-
|
|
85
|
-
binary_data = body.lines[4..-6].join
|
|
86
|
-
# puts "binary_data length: #{binary_data.length}"
|
|
87
|
-
# puts "binary first line: #{binary_data.lines.first}"
|
|
88
|
-
# puts "binary last line: #{binary_data.lines.last}"
|
|
89
|
-
|
|
90
|
-
i = header.lines.first.index( 'filename=' )
|
|
91
|
-
filename = header.lines.first[ i+10..-4 ]
|
|
92
|
-
content_type = header.lines.second[14..-3]
|
|
93
|
-
# puts "filename: #{filename}"
|
|
94
|
-
# puts "content_type: #{content_type}"
|
|
95
|
-
|
|
96
|
-
@body_binary = body
|
|
97
|
-
@body_params = {}
|
|
98
|
-
@body_params[ 'content_type' ] = content_type
|
|
99
|
-
@body_params[ 'file_name' ] = filename
|
|
100
|
-
@body_params[ 'file_size' ] = binary_data.length
|
|
101
|
-
@body_params[ 'file_data' ] = binary_data
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
# ---------------------------------------------------------------------
|
|
106
|
-
# Authenticity Token checking
|
|
107
|
-
# ---------------------------------------------------------------------
|
|
108
|
-
|
|
109
|
-
#
|
|
110
|
-
# Check the authenticity token if it is present.
|
|
111
|
-
# Returns true if it is present and valid, and
|
|
112
|
-
# also if it is not present.
|
|
113
|
-
# Returns false if it is present but not valid.
|
|
114
|
-
#
|
|
115
|
-
def check_authenticity_token engine
|
|
116
|
-
auth_token = @query_params[ Gloo::Objs::CsrfToken::AUTHENTICITY_TOKEN ]
|
|
117
|
-
if auth_token
|
|
118
|
-
session_id = engine.running_app.obj&.session&.get_session_id
|
|
119
|
-
return false unless session_id
|
|
120
|
-
|
|
121
|
-
return Gloo::Objs::CsrfToken.valid_csrf_token?( session_id, auth_token )
|
|
122
|
-
end
|
|
123
|
-
|
|
124
|
-
return true
|
|
125
|
-
end
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
# ---------------------------------------------------------------------
|
|
129
|
-
# Helper functions
|
|
130
|
-
# ---------------------------------------------------------------------
|
|
131
|
-
|
|
132
|
-
#
|
|
133
|
-
# Check the body to see if there is a PATCH or a PUT in
|
|
134
|
-
# the method override.
|
|
135
|
-
#
|
|
136
|
-
def get_body_method_override orig_method
|
|
137
|
-
if @body_params[ '_method' ]
|
|
138
|
-
return @body_params[ '_method' ].upcase
|
|
139
|
-
end
|
|
140
|
-
return orig_method
|
|
141
|
-
end
|
|
142
|
-
|
|
143
|
-
#
|
|
144
|
-
# Write the querey and body params to the log.
|
|
145
|
-
#
|
|
146
|
-
def log_params
|
|
147
|
-
return unless @log
|
|
148
|
-
|
|
149
|
-
if @query_params && ! @query_params.empty?
|
|
150
|
-
@log.info "--- Query Parameters: #{@query_params}"
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
if @body_params && ! @body_params.empty?
|
|
154
|
-
if @body_params[ 'file_data' ]
|
|
155
|
-
# exclude the file data from the params shown
|
|
156
|
-
params = @body_params.dup
|
|
157
|
-
params.delete( 'file_data' )
|
|
158
|
-
params[ 'file_data' ] = '...'
|
|
159
|
-
@log.info "--- Body Parameters: #{params}"
|
|
160
|
-
else
|
|
161
|
-
@log.info "--- Body Parameters: #{@body_params}"
|
|
162
|
-
end
|
|
163
|
-
end
|
|
164
|
-
end
|
|
165
|
-
|
|
166
|
-
#
|
|
167
|
-
# Write the id and route params to the log.
|
|
168
|
-
#
|
|
169
|
-
def log_id_keys
|
|
170
|
-
return unless @log
|
|
171
|
-
|
|
172
|
-
@log.info "--- ID Parameter: #{@id}" if @id
|
|
173
|
-
|
|
174
|
-
if @route_params && ! @route_params.empty?
|
|
175
|
-
@log.info "--- Route Parameters: #{@route_params}"
|
|
176
|
-
end
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
end
|
|
180
|
-
end
|
|
181
|
-
end
|
|
@@ -1,177 +0,0 @@
|
|
|
1
|
-
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
-
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
|
3
|
-
#
|
|
4
|
-
# The Response for a web Request.
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
module Gloo
|
|
8
|
-
module WebSvr
|
|
9
|
-
class Response
|
|
10
|
-
|
|
11
|
-
#
|
|
12
|
-
# SEE: https://stackoverflow.com/questions/23714383/what-are-all-the-possible-values-for-http-content-type-header#48704300
|
|
13
|
-
# for a list of content types.
|
|
14
|
-
#
|
|
15
|
-
CONTENT_TYPE = 'Content-Type'.freeze
|
|
16
|
-
TEXT_TYPE = 'text/plain'.freeze
|
|
17
|
-
JSON_TYPE = 'application/json'.freeze
|
|
18
|
-
HTML_TYPE = 'text/html'.freeze
|
|
19
|
-
|
|
20
|
-
attr_reader :code, :type, :data
|
|
21
|
-
attr_accessor :location
|
|
22
|
-
attr_accessor :file_name
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
# ---------------------------------------------------------------------
|
|
26
|
-
# Initialization
|
|
27
|
-
# ---------------------------------------------------------------------
|
|
28
|
-
|
|
29
|
-
#
|
|
30
|
-
# Set up the web server.
|
|
31
|
-
#
|
|
32
|
-
def initialize( engine = nil,
|
|
33
|
-
code = Gloo::WebSvr::ResponseCode::SUCCESS,
|
|
34
|
-
type = HTML_TYPE,
|
|
35
|
-
data = nil,
|
|
36
|
-
assetCache = false,
|
|
37
|
-
file_name = nil,
|
|
38
|
-
download = false )
|
|
39
|
-
|
|
40
|
-
@engine = engine
|
|
41
|
-
@log = @engine.log if @engine
|
|
42
|
-
|
|
43
|
-
@code = code
|
|
44
|
-
@type = type
|
|
45
|
-
@data = data
|
|
46
|
-
@assetCache = assetCache
|
|
47
|
-
@location = nil
|
|
48
|
-
@file_name = file_name
|
|
49
|
-
@download = download
|
|
50
|
-
end
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
# ---------------------------------------------------------------------
|
|
54
|
-
# Static Helper Functions
|
|
55
|
-
# ---------------------------------------------------------------------
|
|
56
|
-
|
|
57
|
-
#
|
|
58
|
-
# Helper to create a successful JSON response with the given data.
|
|
59
|
-
#
|
|
60
|
-
def self.json_response( engine, data,
|
|
61
|
-
code = Gloo::WebSvr::ResponseCode::SUCCESS )
|
|
62
|
-
|
|
63
|
-
return Gloo::WebSvr::Response.new( engine, code, JSON_TYPE, data )
|
|
64
|
-
end
|
|
65
|
-
|
|
66
|
-
#
|
|
67
|
-
# Helper to create a successful text response with the given data.
|
|
68
|
-
#
|
|
69
|
-
def self.text_response( engine, data,
|
|
70
|
-
code = Gloo::WebSvr::ResponseCode::SUCCESS )
|
|
71
|
-
|
|
72
|
-
return Gloo::WebSvr::Response.new( engine, code, TEXT_TYPE, data )
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
#
|
|
76
|
-
# Helper to create a successful web response with the given data.
|
|
77
|
-
#
|
|
78
|
-
def self.html_response( engine, data,
|
|
79
|
-
code = Gloo::WebSvr::ResponseCode::SUCCESS )
|
|
80
|
-
|
|
81
|
-
return Gloo::WebSvr::Response.new( engine, code, HTML_TYPE, data )
|
|
82
|
-
end
|
|
83
|
-
|
|
84
|
-
#
|
|
85
|
-
# Helper to create a redirect response.
|
|
86
|
-
#
|
|
87
|
-
def self.redirect_response( engine, target )
|
|
88
|
-
code = Gloo::WebSvr::ResponseCode::FOUND
|
|
89
|
-
data = <<~TEXT
|
|
90
|
-
<head>
|
|
91
|
-
<html>
|
|
92
|
-
<body><a href="#{target}">target is here</a></body>
|
|
93
|
-
</html>
|
|
94
|
-
</head>
|
|
95
|
-
TEXT
|
|
96
|
-
|
|
97
|
-
response = Gloo::WebSvr::Response.new( engine, code, HTML_TYPE, data )
|
|
98
|
-
response.location = target
|
|
99
|
-
|
|
100
|
-
return response
|
|
101
|
-
end
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
# ---------------------------------------------------------------------
|
|
105
|
-
# Data Functions
|
|
106
|
-
# ---------------------------------------------------------------------
|
|
107
|
-
|
|
108
|
-
#
|
|
109
|
-
# Add content to the payload.
|
|
110
|
-
#
|
|
111
|
-
def add content
|
|
112
|
-
@data = '' if @data.nil?
|
|
113
|
-
@data << content
|
|
114
|
-
end
|
|
115
|
-
|
|
116
|
-
#
|
|
117
|
-
# Get the headers for the response.
|
|
118
|
-
#
|
|
119
|
-
def headers
|
|
120
|
-
#
|
|
121
|
-
# TO DO: Add more cookie headers here.
|
|
122
|
-
#
|
|
123
|
-
# https://stackoverflow.com/questions/3295083/how-do-i-set-a-cookie-with-a-ruby-rack-middleware-component
|
|
124
|
-
# https://www.rubydoc.info/gems/rack/1.4.7/Rack/Session/Cookie
|
|
125
|
-
#
|
|
126
|
-
|
|
127
|
-
headers = { CONTENT_TYPE => @type }
|
|
128
|
-
|
|
129
|
-
if @location
|
|
130
|
-
headers[ 'Location' ] = @location
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
if @assetCache || @file_name
|
|
134
|
-
headers[ 'Cache-Control' ] = 'public, max-age=604800'
|
|
135
|
-
headers[ 'Expires' ] = (Time.now.utc + 604800).to_s
|
|
136
|
-
end
|
|
137
|
-
|
|
138
|
-
if @file_name
|
|
139
|
-
disp = @download ? 'attachment' : 'inline'
|
|
140
|
-
headers[ 'Content-Disposition' ] = "#{disp}; filename=#{@file_name}"
|
|
141
|
-
headers[ 'Content-Length' ] = @data.length.to_s
|
|
142
|
-
end
|
|
143
|
-
|
|
144
|
-
session = @engine&.running_app&.obj&.session
|
|
145
|
-
headers = session.add_session_for_response( headers ) if session
|
|
146
|
-
|
|
147
|
-
# Clear out session data after the response is prepared.
|
|
148
|
-
@engine&.running_app&.obj&.reset_session_data
|
|
149
|
-
|
|
150
|
-
return headers
|
|
151
|
-
end
|
|
152
|
-
|
|
153
|
-
#
|
|
154
|
-
# Get the final result that will be returned as the
|
|
155
|
-
# response to the web request.
|
|
156
|
-
#
|
|
157
|
-
def result
|
|
158
|
-
return [ @code, headers, @data ]
|
|
159
|
-
end
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
# ---------------------------------------------------------------------
|
|
163
|
-
# Helper functions
|
|
164
|
-
# ---------------------------------------------------------------------
|
|
165
|
-
|
|
166
|
-
#
|
|
167
|
-
# Write the result information to the log.
|
|
168
|
-
#
|
|
169
|
-
def log
|
|
170
|
-
return unless @log
|
|
171
|
-
|
|
172
|
-
@log.info "Response #{@code} #{@type}"
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
end
|
|
176
|
-
end
|
|
177
|
-
end
|
|
@@ -1,69 +0,0 @@
|
|
|
1
|
-
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
-
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
|
3
|
-
#
|
|
4
|
-
# Standard Response Codes.
|
|
5
|
-
#
|
|
6
|
-
# See:
|
|
7
|
-
# https://en.wikipedia.org/wiki/List_of_HTTP_status_codes
|
|
8
|
-
# https://www.geeksforgeeks.org/10-most-common-http-status-codes/
|
|
9
|
-
#
|
|
10
|
-
|
|
11
|
-
module Gloo
|
|
12
|
-
module WebSvr
|
|
13
|
-
class ResponseCode
|
|
14
|
-
|
|
15
|
-
# Gloo::WebSvr::ResponseCode::SUCCESS
|
|
16
|
-
SUCCESS = 200.freeze
|
|
17
|
-
CODE_200 = 'Success/OK'.freeze
|
|
18
|
-
|
|
19
|
-
CREATED = 201.freeze
|
|
20
|
-
CODE_201 = 'Created'.freeze
|
|
21
|
-
|
|
22
|
-
ACCEPTED = 202.freeze
|
|
23
|
-
CODE_202 = 'Accepted'.freeze
|
|
24
|
-
|
|
25
|
-
NO_CONTENT = 204.freeze
|
|
26
|
-
CODE_204 = 'No Content'.freeze
|
|
27
|
-
|
|
28
|
-
PARTIAL_CONTENT = 206.freeze
|
|
29
|
-
CODE_206 = 'Partial Content'.freeze
|
|
30
|
-
|
|
31
|
-
MOVED_PERM = 301.freeze
|
|
32
|
-
CODE_301 = 'Moved Permanently'.freeze
|
|
33
|
-
|
|
34
|
-
FOUND = 302.freeze
|
|
35
|
-
CODE_302 = 'Found'.freeze
|
|
36
|
-
|
|
37
|
-
SEE_OTHER = 303.freeze
|
|
38
|
-
CODE_303 = 'See Other'.freeze
|
|
39
|
-
|
|
40
|
-
NOT_MODIFIED = 304.freeze
|
|
41
|
-
CODE_304 = 'Not Modified'.freeze
|
|
42
|
-
|
|
43
|
-
TEMP_REDIRECT = 307.freeze
|
|
44
|
-
CODE_307 = 'Temporary Redirect'.freeze
|
|
45
|
-
|
|
46
|
-
PERM_REDIRECT = 308.freeze
|
|
47
|
-
CODE_308 = 'Permanent Redirect'.freeze
|
|
48
|
-
|
|
49
|
-
BAD_REQUEST = 400.freeze
|
|
50
|
-
CODE_400 = 'Bad Request'.freeze
|
|
51
|
-
|
|
52
|
-
UNAUTHORIZED = 401.freeze
|
|
53
|
-
CODE_401 = 'Unauthorized'.freeze
|
|
54
|
-
|
|
55
|
-
FORBIDDEN = 403.freeze
|
|
56
|
-
CODE_403 = 'Forbidden'.freeze
|
|
57
|
-
|
|
58
|
-
NOT_FOUND = 404.freeze
|
|
59
|
-
CODE_404 = 'Not Found'.freeze
|
|
60
|
-
|
|
61
|
-
SERVER_ERR = 500.freeze
|
|
62
|
-
CODE_500 = 'Internal Server Error'.freeze
|
|
63
|
-
|
|
64
|
-
NOT_IMPLEMENTED = 501.freeze
|
|
65
|
-
CODE_501 = 'Not Implemented'.freeze
|
|
66
|
-
|
|
67
|
-
end
|
|
68
|
-
end
|
|
69
|
-
end
|
|
@@ -1,47 +0,0 @@
|
|
|
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
|
|
@@ -1,232 +0,0 @@
|
|
|
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 page routing.
|
|
5
|
-
#
|
|
6
|
-
|
|
7
|
-
module Gloo
|
|
8
|
-
module WebSvr
|
|
9
|
-
module Routing
|
|
10
|
-
class Router
|
|
11
|
-
|
|
12
|
-
PAGE_CONTAINER = 'page'.freeze
|
|
13
|
-
SEGMENT_DIVIDER = '/'.freeze
|
|
14
|
-
|
|
15
|
-
attr_reader :route_segments
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
# ---------------------------------------------------------------------
|
|
19
|
-
# Initialization
|
|
20
|
-
# ---------------------------------------------------------------------
|
|
21
|
-
|
|
22
|
-
#
|
|
23
|
-
# Set up the web server.
|
|
24
|
-
#
|
|
25
|
-
def initialize( engine, web_svr_obj )
|
|
26
|
-
@engine = engine
|
|
27
|
-
@log = @engine.log
|
|
28
|
-
|
|
29
|
-
@web_svr_obj = web_svr_obj
|
|
30
|
-
@show_routes = ShowRoutes.new( @engine )
|
|
31
|
-
end
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
# ---------------------------------------------------------------------
|
|
35
|
-
# Routing
|
|
36
|
-
# ---------------------------------------------------------------------
|
|
37
|
-
|
|
38
|
-
#
|
|
39
|
-
# Find and return the page for the given route.
|
|
40
|
-
#
|
|
41
|
-
def page_for_route( path, method )
|
|
42
|
-
@log.info "routing to #{path} for method #{method}"
|
|
43
|
-
@method = method
|
|
44
|
-
route_params = nil
|
|
45
|
-
@id = nil
|
|
46
|
-
|
|
47
|
-
detect_segments path
|
|
48
|
-
|
|
49
|
-
return @web_svr_obj.home_page if is_root_path?
|
|
50
|
-
|
|
51
|
-
pages = @web_svr_obj.pages_container
|
|
52
|
-
if pages
|
|
53
|
-
# If the method is POST and the last segment is NOT 'create',
|
|
54
|
-
# we'll add create to the route segments.
|
|
55
|
-
if Gloo::WebSvr::Routing::ResourceRouter.is_implicit_create?( method, @route_segments.last )
|
|
56
|
-
@route_segments << Gloo::WebSvr::Routing::ResourceRouter::POST_ROUTE
|
|
57
|
-
page = find_route_segment( pages.children )
|
|
58
|
-
return [ page, @id, route_params ] if page
|
|
59
|
-
|
|
60
|
-
# We didn't find the page, so remove the last segment and try again
|
|
61
|
-
# posting to the resource.
|
|
62
|
-
@route_segments.pop
|
|
63
|
-
end
|
|
64
|
-
|
|
65
|
-
page = find_route_segment( pages.children )
|
|
66
|
-
|
|
67
|
-
# Are there any remaining segments to be added as route parameters?
|
|
68
|
-
if @route_segments.count > 0
|
|
69
|
-
route_params = @route_segments
|
|
70
|
-
end
|
|
71
|
-
|
|
72
|
-
return [ page, @id, route_params ] if page
|
|
73
|
-
end
|
|
74
|
-
|
|
75
|
-
return nil
|
|
76
|
-
end
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
# ---------------------------------------------------------------------
|
|
80
|
-
# Dynamic Add Page Routes
|
|
81
|
-
# ---------------------------------------------------------------------
|
|
82
|
-
|
|
83
|
-
#
|
|
84
|
-
# Get the root level page container.
|
|
85
|
-
#
|
|
86
|
-
def page_container
|
|
87
|
-
pn = Gloo::Core::Pn.new( @engine, PAGE_CONTAINER )
|
|
88
|
-
return pn.resolve
|
|
89
|
-
end
|
|
90
|
-
|
|
91
|
-
#
|
|
92
|
-
# Add all page routes to the web server pages (routes).
|
|
93
|
-
#
|
|
94
|
-
def add_page_routes
|
|
95
|
-
can = page_container
|
|
96
|
-
return unless can
|
|
97
|
-
|
|
98
|
-
@log.debug 'Adding page routes to web server…'
|
|
99
|
-
@factory = @engine.factory
|
|
100
|
-
|
|
101
|
-
add_pages can, @web_svr_obj.pages_container
|
|
102
|
-
end
|
|
103
|
-
|
|
104
|
-
#
|
|
105
|
-
# Add the pages to the web server pages.
|
|
106
|
-
# This is a recursive function that will add all
|
|
107
|
-
# pages in the folder and subfolders.
|
|
108
|
-
#
|
|
109
|
-
def add_pages can, parent
|
|
110
|
-
# for each file in the page container
|
|
111
|
-
# create a page object and add it to the routes
|
|
112
|
-
can.children.each do |obj|
|
|
113
|
-
if obj.class == Gloo::Objs::Container
|
|
114
|
-
child_can = parent.find_add_child( obj.name, 'container' )
|
|
115
|
-
add_pages( obj, child_can )
|
|
116
|
-
elsif obj.class == Gloo::Objs::Page
|
|
117
|
-
add_route_alias( parent, obj.name, obj.pn )
|
|
118
|
-
end
|
|
119
|
-
end
|
|
120
|
-
end
|
|
121
|
-
|
|
122
|
-
#
|
|
123
|
-
# Add route alias to the page.
|
|
124
|
-
#
|
|
125
|
-
def add_route_alias( parent, name, pn )
|
|
126
|
-
name = name.gsub( '.', '_' )
|
|
127
|
-
|
|
128
|
-
# First make sure the child doesn't already exist.
|
|
129
|
-
child = parent.find_child( name )
|
|
130
|
-
return if child
|
|
131
|
-
|
|
132
|
-
@factory.create_alias( name, pn, parent )
|
|
133
|
-
end
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
# ---------------------------------------------------------------------
|
|
137
|
-
# Helper funcions
|
|
138
|
-
# ---------------------------------------------------------------------
|
|
139
|
-
|
|
140
|
-
#
|
|
141
|
-
# Show the routes in the running app.
|
|
142
|
-
# This uses the ShowRoutes helper class.
|
|
143
|
-
#
|
|
144
|
-
def show_routes
|
|
145
|
-
@show_routes.show page_container
|
|
146
|
-
end
|
|
147
|
-
|
|
148
|
-
#
|
|
149
|
-
# Find the route segment in the object container.
|
|
150
|
-
#
|
|
151
|
-
def find_route_segment objs
|
|
152
|
-
this_segment = next_segment
|
|
153
|
-
|
|
154
|
-
if this_segment.blank? # && Gloo::WebSvr::WebMethod.is_post?( @method )
|
|
155
|
-
this_segment = Gloo::WebSvr::Routing::ResourceRouter::INDEX
|
|
156
|
-
end
|
|
157
|
-
|
|
158
|
-
objs.each do |o|
|
|
159
|
-
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
|
160
|
-
|
|
161
|
-
if o.name == this_segment
|
|
162
|
-
if o.class == Gloo::Objs::Page
|
|
163
|
-
@log.debug "found page for route: #{o.pn}"
|
|
164
|
-
return o
|
|
165
|
-
elsif o.class == Gloo::Objs::FileHandle
|
|
166
|
-
@log.debug "found static file for route: #{o.pn}"
|
|
167
|
-
return o
|
|
168
|
-
else
|
|
169
|
-
return nil unless o.child_count > 0
|
|
170
|
-
|
|
171
|
-
return find_route_segment( o.children )
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
end
|
|
175
|
-
|
|
176
|
-
return nil
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
#
|
|
180
|
-
# Get the next segment in the route.
|
|
181
|
-
#
|
|
182
|
-
def next_segment
|
|
183
|
-
this_segment = @route_segments.shift
|
|
184
|
-
return nil if this_segment.nil?
|
|
185
|
-
|
|
186
|
-
# A URL might include a dot in a name, but we can't do that
|
|
187
|
-
# because dot is a reserve path thing. So we replace it with
|
|
188
|
-
# an underscore.
|
|
189
|
-
this_segment = this_segment.gsub( '.', '_' )
|
|
190
|
-
|
|
191
|
-
return this_segment
|
|
192
|
-
end
|
|
193
|
-
|
|
194
|
-
#
|
|
195
|
-
# Is this the root path?
|
|
196
|
-
def is_root_path?
|
|
197
|
-
return @route_segments.count == 0
|
|
198
|
-
end
|
|
199
|
-
|
|
200
|
-
#
|
|
201
|
-
# Create a list of path segments.
|
|
202
|
-
#
|
|
203
|
-
def detect_segments path
|
|
204
|
-
# For Assets, substitute the published name with fingerprint
|
|
205
|
-
# for the simple asset name (if it is found).
|
|
206
|
-
asset_info = Gloo::WebSvr::AssetInfo.find_info_for( path )
|
|
207
|
-
unless asset_info.blank?
|
|
208
|
-
path = asset_info.pn
|
|
209
|
-
end
|
|
210
|
-
|
|
211
|
-
# Split the path into segments.
|
|
212
|
-
@route_segments = path.split SEGMENT_DIVIDER
|
|
213
|
-
|
|
214
|
-
# Remove the first segment if it is empty.
|
|
215
|
-
@route_segments.shift if @route_segments.first.blank?
|
|
216
|
-
|
|
217
|
-
@route_segments.each do |seg|
|
|
218
|
-
if seg.to_i.to_s == seg
|
|
219
|
-
@id = seg.to_i
|
|
220
|
-
@log.info "found id for route: #{@id}"
|
|
221
|
-
@route_segments.delete seg
|
|
222
|
-
@route_segments << ResourceRouter.segment_for_method( @method )
|
|
223
|
-
end
|
|
224
|
-
end
|
|
225
|
-
|
|
226
|
-
return @route_segments
|
|
227
|
-
end
|
|
228
|
-
|
|
229
|
-
end
|
|
230
|
-
end
|
|
231
|
-
end
|
|
232
|
-
end
|