gloo-web 1.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.
- checksums.yaml +7 -0
- data/lib/gloo-web.rb +48 -0
- data/lib/objs/element.rb +252 -0
- data/lib/objs/field.rb +428 -0
- data/lib/objs/form.rb +269 -0
- data/lib/objs/page.rb +560 -0
- data/lib/objs/partial.rb +208 -0
- data/lib/objs/svr.rb +711 -0
- data/lib/routing/resource_router.rb +43 -0
- data/lib/routing/router.rb +228 -0
- data/lib/routing/show_routes.rb +90 -0
- data/lib/web_svr/asset.rb +405 -0
- data/lib/web_svr/asset_info.rb +114 -0
- data/lib/web_svr/config.rb +55 -0
- data/lib/web_svr/embedded_renderer.rb +152 -0
- data/lib/web_svr/handler.rb +152 -0
- data/lib/web_svr/request.rb +141 -0
- data/lib/web_svr/request_params.rb +179 -0
- data/lib/web_svr/response.rb +175 -0
- data/lib/web_svr/response_code.rb +67 -0
- data/lib/web_svr/server.rb +102 -0
- data/lib/web_svr/session.rb +213 -0
- data/lib/web_svr/table_renderer.rb +149 -0
- data/lib/web_svr/web_method.rb +52 -0
- metadata +81 -0
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A helper class used to render parameters (ERB) in text.
|
|
5
|
+
# Also uses helper functions to render.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module WebSvr
|
|
9
|
+
class EmbeddedRenderer
|
|
10
|
+
|
|
11
|
+
HELPER = 'helper'.freeze
|
|
12
|
+
|
|
13
|
+
attr_reader :engine, :log, :web_svr_obj
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
# ---------------------------------------------------------------------
|
|
17
|
+
# Initialization
|
|
18
|
+
# ---------------------------------------------------------------------
|
|
19
|
+
|
|
20
|
+
#
|
|
21
|
+
# Set up the web server.
|
|
22
|
+
#
|
|
23
|
+
def initialize( engine, web_svr_obj )
|
|
24
|
+
@engine = engine
|
|
25
|
+
@log = @engine.log
|
|
26
|
+
|
|
27
|
+
@web_svr_obj = web_svr_obj
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# ---------------------------------------------------------------------
|
|
32
|
+
# Tag Helpers
|
|
33
|
+
# ---------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Render a favicon tag.
|
|
37
|
+
# By default the name is 'favicon.ico' and does not need to be provided
|
|
38
|
+
# if that is the correct file name.
|
|
39
|
+
#
|
|
40
|
+
def favicon_tag( name = 'favicon.ico' )
|
|
41
|
+
icon_path = "/#{Asset::ASSET_FOLDER}/#{Asset::IMAGE_FOLDER}/#{name}"
|
|
42
|
+
published_name = @engine.running_app.obj.asset.published_name( icon_path )
|
|
43
|
+
return "<link rel='shortcut icon' type='image/x-icon' href='#{published_name}' />"
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Render a Apple Touch Icon tag.
|
|
48
|
+
# By default the name is 'apple-touch-icon.png' and does not need to be provided
|
|
49
|
+
# if that is the correct file name.
|
|
50
|
+
#
|
|
51
|
+
def apple_touch_icon_tag( name = 'apple-touch-icon.png', type = 'image/png' )
|
|
52
|
+
icon_path = "/#{Asset::ASSET_FOLDER}/#{Asset::IMAGE_FOLDER}/#{name}"
|
|
53
|
+
published_name = @engine.running_app.obj.asset.published_name( icon_path )
|
|
54
|
+
return "<link rel='apple-touch-icon' type='#{type}' href='#{published_name}' />"
|
|
55
|
+
end
|
|
56
|
+
|
|
57
|
+
#
|
|
58
|
+
# Render an image tag for the given image name.
|
|
59
|
+
# Include optional proterties as part of the tag.
|
|
60
|
+
#
|
|
61
|
+
def image_tag( img_name, properties = '' )
|
|
62
|
+
image_path = "/#{Asset::ASSET_FOLDER}/#{Asset::IMAGE_FOLDER}/#{img_name}"
|
|
63
|
+
published_name = @engine.running_app.obj.asset.published_name( image_path )
|
|
64
|
+
return "<image src='#{published_name}' #{properties} />"
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
#
|
|
68
|
+
# Render a script tag for the given script name.
|
|
69
|
+
#
|
|
70
|
+
def js_tag( name )
|
|
71
|
+
js_path = "/#{Asset::ASSET_FOLDER}/#{Asset::JAVASCRIPT_FOLDER}/#{name}"
|
|
72
|
+
published_name = @engine.running_app.obj.asset.published_name( js_path )
|
|
73
|
+
return "<script src='#{published_name}'></script>"
|
|
74
|
+
end
|
|
75
|
+
|
|
76
|
+
#
|
|
77
|
+
# Render a stylesheet tag for the given stylesheet name.
|
|
78
|
+
#
|
|
79
|
+
def css_tag( name )
|
|
80
|
+
css_path = "/#{Asset::ASSET_FOLDER}/#{Asset::STYLESHEET_FOLDER}/#{name}"
|
|
81
|
+
published_name = @engine.running_app.obj.asset.published_name( css_path )
|
|
82
|
+
return "<link rel='stylesheet' media='all' href='#{published_name}' />"
|
|
83
|
+
end
|
|
84
|
+
|
|
85
|
+
#
|
|
86
|
+
# Embed a hidden field with the autenticity token.
|
|
87
|
+
#
|
|
88
|
+
def autenticity_token_tag
|
|
89
|
+
session_id = @engine.running_app.obj&.session&.get_session_id
|
|
90
|
+
return Gloo::Objs::CsrfToken.get_csrf_token_hidden_field( session_id )
|
|
91
|
+
end
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
# ---------------------------------------------------------------------
|
|
95
|
+
# Obj Helper Functions
|
|
96
|
+
# ---------------------------------------------------------------------
|
|
97
|
+
|
|
98
|
+
#
|
|
99
|
+
# Handle a missing method by looking for a helper function.
|
|
100
|
+
# If there is one, then call it and return the result.
|
|
101
|
+
# If not, log an error and return nil.
|
|
102
|
+
#
|
|
103
|
+
def method_missing( method_name, *args )
|
|
104
|
+
@log.debug "missing method '#{method_name}' with args #{args}"
|
|
105
|
+
|
|
106
|
+
helper_pn = "#{HELPER}.#{method_name}"
|
|
107
|
+
@log.debug "looking for function: #{helper_pn}"
|
|
108
|
+
|
|
109
|
+
pn = Gloo::Core::Pn.new( @engine, helper_pn )
|
|
110
|
+
obj = pn.resolve
|
|
111
|
+
if obj
|
|
112
|
+
@log.debug "found obj: #{obj.pn}"
|
|
113
|
+
return obj.invoke args
|
|
114
|
+
else
|
|
115
|
+
@log.error "Function not found: #{helper_pn}"
|
|
116
|
+
end
|
|
117
|
+
|
|
118
|
+
return nil
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# ---------------------------------------------------------------------
|
|
123
|
+
# Renderer
|
|
124
|
+
# ---------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# Render content with the given params.
|
|
128
|
+
# Params might be nil, in which case the content
|
|
129
|
+
# is returned with no changes.
|
|
130
|
+
#
|
|
131
|
+
def render content, params
|
|
132
|
+
# If the params is nil, let's make it an empty hash.
|
|
133
|
+
params = {} unless params
|
|
134
|
+
|
|
135
|
+
# Get the binding context for this render.
|
|
136
|
+
b = binding
|
|
137
|
+
|
|
138
|
+
# Add the params to the binding context.
|
|
139
|
+
params.each_pair do |key, value|
|
|
140
|
+
b.local_variable_set key.to_sym, value
|
|
141
|
+
end
|
|
142
|
+
|
|
143
|
+
# Render in the current binding content.
|
|
144
|
+
renderer = ERB.new( content )
|
|
145
|
+
content = renderer.result( b )
|
|
146
|
+
|
|
147
|
+
return content
|
|
148
|
+
end
|
|
149
|
+
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
end
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# Web application request handler.
|
|
5
|
+
# Takes a request and does what is needed to create a response.
|
|
6
|
+
#
|
|
7
|
+
|
|
8
|
+
module WebSvr
|
|
9
|
+
class Handler
|
|
10
|
+
|
|
11
|
+
attr_reader :server_obj
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
# ---------------------------------------------------------------------
|
|
15
|
+
# Initialization
|
|
16
|
+
# ---------------------------------------------------------------------
|
|
17
|
+
|
|
18
|
+
#
|
|
19
|
+
# Set up the web server.
|
|
20
|
+
#
|
|
21
|
+
def initialize( engine, obj )
|
|
22
|
+
@engine = engine
|
|
23
|
+
@log = @engine.log
|
|
24
|
+
@server_obj = obj
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
# ---------------------------------------------------------------------
|
|
29
|
+
# Process Request
|
|
30
|
+
# ---------------------------------------------------------------------
|
|
31
|
+
|
|
32
|
+
#
|
|
33
|
+
# Process the request and return a result.
|
|
34
|
+
#
|
|
35
|
+
def handle request
|
|
36
|
+
@request = request
|
|
37
|
+
page_obj = nil
|
|
38
|
+
route_params = nil
|
|
39
|
+
|
|
40
|
+
page, id, route_params = @server_obj.router.page_for_route( @request.path, @request.method )
|
|
41
|
+
@engine.log.debug "Found Page: #{page&.name}" if page
|
|
42
|
+
|
|
43
|
+
request.request_params.id = id
|
|
44
|
+
request.request_params.route_params = route_params
|
|
45
|
+
request.request_params.log_id_keys
|
|
46
|
+
|
|
47
|
+
if page
|
|
48
|
+
# Run the on_request script with the found page.
|
|
49
|
+
@server_obj.run_on_request( page )
|
|
50
|
+
|
|
51
|
+
if page.is_a? Gloo::Objs::FileHandle
|
|
52
|
+
result = handle_file page
|
|
53
|
+
else
|
|
54
|
+
result = handle_page page
|
|
55
|
+
page_obj = page
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
result = server_error_result
|
|
59
|
+
end
|
|
60
|
+
|
|
61
|
+
return result, page_obj
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
#
|
|
65
|
+
# Handle request for a page.
|
|
66
|
+
# Render the page, with possible redirect.
|
|
67
|
+
#
|
|
68
|
+
def handle_page page
|
|
69
|
+
result = page.render @request
|
|
70
|
+
if redirect_hard_set?
|
|
71
|
+
result = server_redirect_result
|
|
72
|
+
@engine.running_app.obj.redirect_hard = nil
|
|
73
|
+
elsif redirect_set?
|
|
74
|
+
page = @engine.running_app.obj.redirect
|
|
75
|
+
@log.debug "Redirecting to: #{page.pn}"
|
|
76
|
+
@engine.running_app.obj.redirect = nil
|
|
77
|
+
result = page.render
|
|
78
|
+
end
|
|
79
|
+
return result
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
#
|
|
83
|
+
# Handle a request for a static file such as an image.
|
|
84
|
+
#
|
|
85
|
+
def handle_file file
|
|
86
|
+
pn = @server_obj.asset.path_for_file file
|
|
87
|
+
|
|
88
|
+
# Check to make sure it is a valid file
|
|
89
|
+
# return error if it is not
|
|
90
|
+
return file_error_result unless File.exist? pn
|
|
91
|
+
|
|
92
|
+
return @server_obj.asset.render_file pn
|
|
93
|
+
end
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
# ---------------------------------------------------------------------
|
|
97
|
+
# Errors
|
|
98
|
+
# ---------------------------------------------------------------------
|
|
99
|
+
|
|
100
|
+
#
|
|
101
|
+
# Return a server error result.
|
|
102
|
+
# Use the app's error if there is one, otherwise a generic message.
|
|
103
|
+
#
|
|
104
|
+
def server_error_result
|
|
105
|
+
err_page = @server_obj.err_page
|
|
106
|
+
return err_page.render if err_page
|
|
107
|
+
|
|
108
|
+
# Last resort, just return a generic error message.
|
|
109
|
+
return WebSvr::Response.text_response( @engine,
|
|
110
|
+
"Server error!", WebSvr::ResponseCode::SERVER_ERR )
|
|
111
|
+
end
|
|
112
|
+
|
|
113
|
+
#
|
|
114
|
+
# Get a file not found error result.
|
|
115
|
+
#
|
|
116
|
+
def file_error_result
|
|
117
|
+
return WebSvr::Response.text_response( @engine,
|
|
118
|
+
"File not found!", WebSvr::ResponseCode::NOT_FOUND )
|
|
119
|
+
end
|
|
120
|
+
|
|
121
|
+
|
|
122
|
+
# ---------------------------------------------------------------------
|
|
123
|
+
# Redirect Helper functions
|
|
124
|
+
# ---------------------------------------------------------------------
|
|
125
|
+
|
|
126
|
+
#
|
|
127
|
+
# Is there a redirect page set in the running app?
|
|
128
|
+
#
|
|
129
|
+
def redirect_set?
|
|
130
|
+
return false unless @engine.app_running?
|
|
131
|
+
return @engine.running_app.obj.redirect
|
|
132
|
+
end
|
|
133
|
+
|
|
134
|
+
#
|
|
135
|
+
# Is there a redirect page set in the running app?
|
|
136
|
+
#
|
|
137
|
+
def redirect_hard_set?
|
|
138
|
+
return false unless @engine.app_running?
|
|
139
|
+
return @engine.running_app.obj.redirect_hard
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
#
|
|
143
|
+
# Return a redirect result.
|
|
144
|
+
#
|
|
145
|
+
def server_redirect_result
|
|
146
|
+
target = @engine.running_app.obj.redirect_hard
|
|
147
|
+
|
|
148
|
+
return WebSvr::Response.redirect_response( @engine, target )
|
|
149
|
+
end
|
|
150
|
+
|
|
151
|
+
end
|
|
152
|
+
end
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
|
2
|
+
# Copyright:: Copyright (c) 2024 Eric Crane. All rights reserved.
|
|
3
|
+
#
|
|
4
|
+
# A web Request for a page, action, or static resource.
|
|
5
|
+
#
|
|
6
|
+
# Kinds of Resources
|
|
7
|
+
# Web Page
|
|
8
|
+
# Action - does something and redirects to a page (or returns nothing)
|
|
9
|
+
# API - returns JSON instead of HTML (but is that different from Web Page?)
|
|
10
|
+
# Static Resource - File, PDF, Image, etc.
|
|
11
|
+
#
|
|
12
|
+
#
|
|
13
|
+
# See More doc here:
|
|
14
|
+
# https://www.rubydoc.info/gems/rack/Rack/Request/Helpers#path-instance_method
|
|
15
|
+
#
|
|
16
|
+
|
|
17
|
+
module WebSvr
|
|
18
|
+
class Request
|
|
19
|
+
|
|
20
|
+
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
|
21
|
+
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
|
22
|
+
HTTP_HOST = 'HTTP_HOST'.freeze
|
|
23
|
+
QUERY_STRING = 'QUERY_STRING'.freeze
|
|
24
|
+
|
|
25
|
+
attr_reader :method, :host, :path, :ip, :query
|
|
26
|
+
attr_reader :db, :elapsed
|
|
27
|
+
attr_accessor :request_params
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
# ---------------------------------------------------------------------
|
|
31
|
+
# Initialization
|
|
32
|
+
# ---------------------------------------------------------------------
|
|
33
|
+
|
|
34
|
+
#
|
|
35
|
+
# Set up the web server.
|
|
36
|
+
#
|
|
37
|
+
def initialize( engine, handler, env = nil )
|
|
38
|
+
@engine = engine
|
|
39
|
+
@log = @engine.log
|
|
40
|
+
@request_params = RequestParams.new( @log )
|
|
41
|
+
|
|
42
|
+
@handler = handler
|
|
43
|
+
|
|
44
|
+
@env = env
|
|
45
|
+
detect_env
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
# ---------------------------------------------------------------------
|
|
50
|
+
# Process Request
|
|
51
|
+
# ---------------------------------------------------------------------
|
|
52
|
+
|
|
53
|
+
#
|
|
54
|
+
# Process the request and return a result.
|
|
55
|
+
#
|
|
56
|
+
def process
|
|
57
|
+
start_timer
|
|
58
|
+
|
|
59
|
+
# Run the on_request script if there is one.
|
|
60
|
+
@handler.server_obj.set_request_data self
|
|
61
|
+
|
|
62
|
+
# Check authenticity token if it's given.
|
|
63
|
+
if @request_params.check_authenticity_token( @engine )
|
|
64
|
+
result, page_obj = @handler.handle self
|
|
65
|
+
else
|
|
66
|
+
# Render the error page.
|
|
67
|
+
result = @handler.server_error_result
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
finish_timer
|
|
71
|
+
|
|
72
|
+
# Run the on_response script if there is one.
|
|
73
|
+
@handler.server_obj.set_response_data( self, result, page_obj )
|
|
74
|
+
@handler.server_obj.run_on_response
|
|
75
|
+
|
|
76
|
+
return result
|
|
77
|
+
end
|
|
78
|
+
|
|
79
|
+
|
|
80
|
+
# ---------------------------------------------------------------------
|
|
81
|
+
# ENV
|
|
82
|
+
# ---------------------------------------------------------------------
|
|
83
|
+
|
|
84
|
+
#
|
|
85
|
+
# Write the request information to the log.
|
|
86
|
+
#
|
|
87
|
+
def detect_env
|
|
88
|
+
req = Rack::Request.new( @env )
|
|
89
|
+
|
|
90
|
+
@method = req.request_method
|
|
91
|
+
@path = req.path
|
|
92
|
+
@host = req.host_with_port
|
|
93
|
+
@query = req.query_string
|
|
94
|
+
|
|
95
|
+
@request_params.init_query_params( @query )
|
|
96
|
+
@ip = req.ip
|
|
97
|
+
@handler.server_obj.session.set_session_data_for_request( @env )
|
|
98
|
+
|
|
99
|
+
@request_params.init_body_params( @env[ 'rack.input' ].read )
|
|
100
|
+
@method = @request_params.get_body_method_override @method
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ---------------------------------------------------------------------
|
|
105
|
+
# Request timer
|
|
106
|
+
# ---------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
#
|
|
109
|
+
# Keep track of the request start time.
|
|
110
|
+
#
|
|
111
|
+
def start_timer
|
|
112
|
+
@start = Time.now
|
|
113
|
+
@engine.running_app.reset_db_time
|
|
114
|
+
end
|
|
115
|
+
|
|
116
|
+
#
|
|
117
|
+
# Write the request completion time to the log.
|
|
118
|
+
#
|
|
119
|
+
def finish_timer
|
|
120
|
+
@finish = Time.now
|
|
121
|
+
@elapsed = ( ( @finish - @start ) * 1000.0 ).round(2)
|
|
122
|
+
@db = @engine.running_app.db_time
|
|
123
|
+
@log.info "*** Web request complete. DB: #{@db} ms. Elapsed time: #{@elapsed} ms"
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# ---------------------------------------------------------------------
|
|
128
|
+
# Helper functions
|
|
129
|
+
# ---------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
#
|
|
132
|
+
# Write the request information to the log.
|
|
133
|
+
#
|
|
134
|
+
def log
|
|
135
|
+
@log.info "#{@method} #{@host}#{@path}"
|
|
136
|
+
|
|
137
|
+
@request_params.log_params
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
end
|
|
141
|
+
end
|
|
@@ -0,0 +1,179 @@
|
|
|
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 WebSvr
|
|
14
|
+
class RequestParams
|
|
15
|
+
|
|
16
|
+
attr_accessor :id, :route_params
|
|
17
|
+
attr_reader :query_params, :body_params, :body_binary
|
|
18
|
+
|
|
19
|
+
# ---------------------------------------------------------------------
|
|
20
|
+
# Initialization
|
|
21
|
+
# ---------------------------------------------------------------------
|
|
22
|
+
|
|
23
|
+
#
|
|
24
|
+
# Set up the web server.
|
|
25
|
+
#
|
|
26
|
+
def initialize( log )
|
|
27
|
+
@log = log
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
# ---------------------------------------------------------------------
|
|
32
|
+
# Value Detection
|
|
33
|
+
# ---------------------------------------------------------------------
|
|
34
|
+
|
|
35
|
+
#
|
|
36
|
+
# Detect the parameters from query string.
|
|
37
|
+
#
|
|
38
|
+
def init_query_params query_string
|
|
39
|
+
if query_string
|
|
40
|
+
@query_params = Rack::Utils.parse_query( query_string )
|
|
41
|
+
else
|
|
42
|
+
@query_params = {}
|
|
43
|
+
end
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
#
|
|
47
|
+
# Detect the parameters from the body of the request.
|
|
48
|
+
#
|
|
49
|
+
def init_body_params body
|
|
50
|
+
if body && body.length > 0
|
|
51
|
+
# if body is binary, then it is not a query string
|
|
52
|
+
begin
|
|
53
|
+
@body_params = Rack::Utils.parse_query body
|
|
54
|
+
rescue => exception
|
|
55
|
+
init_multipart body
|
|
56
|
+
end
|
|
57
|
+
else
|
|
58
|
+
@body_params = {}
|
|
59
|
+
end
|
|
60
|
+
end
|
|
61
|
+
|
|
62
|
+
#
|
|
63
|
+
# Set the body to a binary file.
|
|
64
|
+
#
|
|
65
|
+
# TODO: find a lib or method to handle this.
|
|
66
|
+
# This is very rough and will need to be fixed.
|
|
67
|
+
#
|
|
68
|
+
def init_multipart body
|
|
69
|
+
# puts "*********** first lines: *********** "
|
|
70
|
+
# body.lines[0..3].each { |line| puts line }
|
|
71
|
+
# puts "*********** last lines: *********** "
|
|
72
|
+
# body.lines.last(5).each { |line| puts line }
|
|
73
|
+
# puts "************************************"
|
|
74
|
+
|
|
75
|
+
# boundary = body.lines.first
|
|
76
|
+
# puts "boundary: #{boundary}"
|
|
77
|
+
|
|
78
|
+
header = body.lines[1..3].join
|
|
79
|
+
# puts "header: #{header}"
|
|
80
|
+
|
|
81
|
+
footer = body.lines.last(5).join
|
|
82
|
+
# puts "footer: #{footer}"
|
|
83
|
+
|
|
84
|
+
binary_data = body.lines[4..-6].join
|
|
85
|
+
# puts "binary_data length: #{binary_data.length}"
|
|
86
|
+
# puts "binary first line: #{binary_data.lines.first}"
|
|
87
|
+
# puts "binary last line: #{binary_data.lines.last}"
|
|
88
|
+
|
|
89
|
+
i = header.lines.first.index( 'filename=' )
|
|
90
|
+
filename = header.lines.first[ i+10..-4 ]
|
|
91
|
+
content_type = header.lines.second[14..-3]
|
|
92
|
+
# puts "filename: #{filename}"
|
|
93
|
+
# puts "content_type: #{content_type}"
|
|
94
|
+
|
|
95
|
+
@body_binary = body
|
|
96
|
+
@body_params = {}
|
|
97
|
+
@body_params[ 'content_type' ] = content_type
|
|
98
|
+
@body_params[ 'file_name' ] = filename
|
|
99
|
+
@body_params[ 'file_size' ] = binary_data.length
|
|
100
|
+
@body_params[ 'file_data' ] = binary_data
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
|
|
104
|
+
# ---------------------------------------------------------------------
|
|
105
|
+
# Authenticity Token checking
|
|
106
|
+
# ---------------------------------------------------------------------
|
|
107
|
+
|
|
108
|
+
#
|
|
109
|
+
# Check the authenticity token if it is present.
|
|
110
|
+
# Returns true if it is present and valid, and
|
|
111
|
+
# also if it is not present.
|
|
112
|
+
# Returns false if it is present but not valid.
|
|
113
|
+
#
|
|
114
|
+
def check_authenticity_token engine
|
|
115
|
+
auth_token = @query_params[ Gloo::Objs::CsrfToken::AUTHENTICITY_TOKEN ]
|
|
116
|
+
if auth_token
|
|
117
|
+
session_id = engine.running_app.obj&.session&.get_session_id
|
|
118
|
+
return false unless session_id
|
|
119
|
+
|
|
120
|
+
return Gloo::Objs::CsrfToken.valid_csrf_token?( session_id, auth_token )
|
|
121
|
+
end
|
|
122
|
+
|
|
123
|
+
return true
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
# ---------------------------------------------------------------------
|
|
128
|
+
# Helper functions
|
|
129
|
+
# ---------------------------------------------------------------------
|
|
130
|
+
|
|
131
|
+
#
|
|
132
|
+
# Check the body to see if there is a PATCH or a PUT in
|
|
133
|
+
# the method override.
|
|
134
|
+
#
|
|
135
|
+
def get_body_method_override orig_method
|
|
136
|
+
if @body_params[ '_method' ]
|
|
137
|
+
return @body_params[ '_method' ].upcase
|
|
138
|
+
end
|
|
139
|
+
return orig_method
|
|
140
|
+
end
|
|
141
|
+
|
|
142
|
+
#
|
|
143
|
+
# Write the querey and body params to the log.
|
|
144
|
+
#
|
|
145
|
+
def log_params
|
|
146
|
+
return unless @log
|
|
147
|
+
|
|
148
|
+
if @query_params && ! @query_params.empty?
|
|
149
|
+
@log.info "--- Query Parameters: #{@query_params}"
|
|
150
|
+
end
|
|
151
|
+
|
|
152
|
+
if @body_params && ! @body_params.empty?
|
|
153
|
+
if @body_params[ 'file_data' ]
|
|
154
|
+
# exclude the file data from the params shown
|
|
155
|
+
params = @body_params.dup
|
|
156
|
+
params.delete( 'file_data' )
|
|
157
|
+
params[ 'file_data' ] = '...'
|
|
158
|
+
@log.info "--- Body Parameters: #{params}"
|
|
159
|
+
else
|
|
160
|
+
@log.info "--- Body Parameters: #{@body_params}"
|
|
161
|
+
end
|
|
162
|
+
end
|
|
163
|
+
end
|
|
164
|
+
|
|
165
|
+
#
|
|
166
|
+
# Write the id and route params to the log.
|
|
167
|
+
#
|
|
168
|
+
def log_id_keys
|
|
169
|
+
return unless @log
|
|
170
|
+
|
|
171
|
+
@log.info "--- ID Parameter: #{@id}" if @id
|
|
172
|
+
|
|
173
|
+
if @route_params && ! @route_params.empty?
|
|
174
|
+
@log.info "--- Route Parameters: #{@route_params}"
|
|
175
|
+
end
|
|
176
|
+
end
|
|
177
|
+
|
|
178
|
+
end
|
|
179
|
+
end
|