gloo 3.0.1 → 3.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 +4 -4
- data/gloo.gemspec +1 -0
- data/lib/VERSION +1 -1
- data/lib/VERSION_NOTES +6 -0
- data/lib/gloo/app/engine.rb +37 -4
- data/lib/gloo/app/log.rb +1 -2
- data/lib/gloo/app/running_app.rb +41 -0
- data/lib/gloo/core/factory.rb +1 -2
- data/lib/gloo/core/gloo_system.rb +5 -0
- data/lib/gloo/objs/basic/function.rb +169 -0
- data/lib/gloo/objs/basic/untyped.rb +1 -1
- data/lib/gloo/objs/web/json.rb +14 -1
- data/lib/gloo/objs/web/uri.rb +13 -1
- data/lib/gloo/objs/web_svr/element.rb +244 -0
- data/lib/gloo/objs/web_svr/page.rb +389 -0
- data/lib/gloo/objs/web_svr/partial.rb +204 -0
- data/lib/gloo/objs/web_svr/svr.rb +299 -0
- data/lib/gloo/verbs/cls.rb +1 -1
- data/lib/gloo/verbs/redirect.rb +56 -0
- data/lib/gloo/web_svr/asset.rb +194 -0
- data/lib/gloo/web_svr/config.rb +56 -0
- data/lib/gloo/web_svr/embedded_renderer.rb +91 -0
- data/lib/gloo/web_svr/handler.rb +120 -0
- data/lib/gloo/web_svr/request.rb +107 -0
- data/lib/gloo/web_svr/response.rb +118 -0
- data/lib/gloo/web_svr/response_code.rb +69 -0
- data/lib/gloo/web_svr/router.rb +179 -0
- data/lib/gloo/web_svr/server.rb +97 -0
- metadata +32 -2
@@ -0,0 +1,120 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 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 Gloo
|
9
|
+
module WebSvr
|
10
|
+
class Handler
|
11
|
+
|
12
|
+
attr_reader :server_obj
|
13
|
+
|
14
|
+
|
15
|
+
# ---------------------------------------------------------------------
|
16
|
+
# Initialization
|
17
|
+
# ---------------------------------------------------------------------
|
18
|
+
|
19
|
+
#
|
20
|
+
# Set up the web server.
|
21
|
+
#
|
22
|
+
def initialize( engine, obj )
|
23
|
+
@engine = engine
|
24
|
+
@log = @engine.log
|
25
|
+
@server_obj = obj
|
26
|
+
end
|
27
|
+
|
28
|
+
|
29
|
+
# ---------------------------------------------------------------------
|
30
|
+
# Process Request
|
31
|
+
# ---------------------------------------------------------------------
|
32
|
+
|
33
|
+
#
|
34
|
+
# Process the request and return a result.
|
35
|
+
#
|
36
|
+
def handle request
|
37
|
+
@request = request
|
38
|
+
|
39
|
+
page = @server_obj.router.page_for_route @request.path
|
40
|
+
if page
|
41
|
+
if page.is_a? Gloo::Objs::FileHandle
|
42
|
+
return handle_file page
|
43
|
+
else
|
44
|
+
return handle_page page
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
return server_error_result
|
49
|
+
end
|
50
|
+
|
51
|
+
#
|
52
|
+
# Handle request for a page.
|
53
|
+
# Render the page, with possible redirect.
|
54
|
+
#
|
55
|
+
def handle_page page
|
56
|
+
result = page.render
|
57
|
+
if redirect_set?
|
58
|
+
page = @engine.running_app.obj.redirect
|
59
|
+
@log.debug "Redirecting to: #{page.pn}"
|
60
|
+
@engine.running_app.obj.redirect = nil
|
61
|
+
result = page.render
|
62
|
+
end
|
63
|
+
return result
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# Handle a request for a static file such as an image.
|
68
|
+
#
|
69
|
+
def handle_file file
|
70
|
+
pn = @server_obj.asset.path_for_file file
|
71
|
+
|
72
|
+
# Check to make sure it is a valid file
|
73
|
+
# return error if it is not
|
74
|
+
return file_error_result unless File.exist? pn
|
75
|
+
|
76
|
+
return @server_obj.asset.render_file pn
|
77
|
+
end
|
78
|
+
|
79
|
+
|
80
|
+
# ---------------------------------------------------------------------
|
81
|
+
# Errors
|
82
|
+
# ---------------------------------------------------------------------
|
83
|
+
|
84
|
+
#
|
85
|
+
# Return a server error result.
|
86
|
+
# Use the app's error if there is one, otherwise a generic message.
|
87
|
+
#
|
88
|
+
def server_error_result
|
89
|
+
err_page = @server_obj.err_page
|
90
|
+
return err_page.render if err_page
|
91
|
+
|
92
|
+
# Last resort, just return a generic error message.
|
93
|
+
return Gloo::WebSvr::Response.text_response( @engine,
|
94
|
+
"Server error!", Gloo::WebSvr::ResponseCode::SERVER_ERR )
|
95
|
+
end
|
96
|
+
|
97
|
+
#
|
98
|
+
# Get a file not found error result.
|
99
|
+
#
|
100
|
+
def file_error_result
|
101
|
+
return Gloo::WebSvr::Response.text_response( @engine,
|
102
|
+
"File not found!", Gloo::WebSvr::ResponseCode::NOT_FOUND )
|
103
|
+
end
|
104
|
+
|
105
|
+
|
106
|
+
# ---------------------------------------------------------------------
|
107
|
+
# Helper functions
|
108
|
+
# ---------------------------------------------------------------------
|
109
|
+
|
110
|
+
#
|
111
|
+
# Is there a redirect page set in the running app?
|
112
|
+
#
|
113
|
+
def redirect_set?
|
114
|
+
return false unless @engine.app_running?
|
115
|
+
return @engine.running_app.obj.redirect
|
116
|
+
end
|
117
|
+
|
118
|
+
end
|
119
|
+
end
|
120
|
+
end
|
@@ -0,0 +1,107 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 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
|
+
module Gloo
|
14
|
+
module WebSvr
|
15
|
+
class Request
|
16
|
+
|
17
|
+
REQUEST_METHOD = 'REQUEST_METHOD'.freeze
|
18
|
+
REQUEST_PATH = 'REQUEST_PATH'.freeze
|
19
|
+
HTTP_HOST = 'HTTP_HOST'.freeze
|
20
|
+
QUERY_STRING = 'QUERY_STRING'.freeze
|
21
|
+
|
22
|
+
attr_reader :method, :host, :path, :query
|
23
|
+
|
24
|
+
|
25
|
+
# ---------------------------------------------------------------------
|
26
|
+
# Initialization
|
27
|
+
# ---------------------------------------------------------------------
|
28
|
+
|
29
|
+
#
|
30
|
+
# Set up the web server.
|
31
|
+
#
|
32
|
+
def initialize( engine, handler, env = nil )
|
33
|
+
@engine = engine
|
34
|
+
@log = @engine.log
|
35
|
+
|
36
|
+
@handler = handler
|
37
|
+
|
38
|
+
@env = env
|
39
|
+
detect_env
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# ---------------------------------------------------------------------
|
44
|
+
# Process Request
|
45
|
+
# ---------------------------------------------------------------------
|
46
|
+
|
47
|
+
#
|
48
|
+
# Process the request and return a result.
|
49
|
+
#
|
50
|
+
def process
|
51
|
+
start_timer
|
52
|
+
result = @handler.handle self
|
53
|
+
finish_timer
|
54
|
+
return result
|
55
|
+
end
|
56
|
+
|
57
|
+
# ---------------------------------------------------------------------
|
58
|
+
# ENV
|
59
|
+
# ---------------------------------------------------------------------
|
60
|
+
|
61
|
+
#
|
62
|
+
# Write the request information to the log.
|
63
|
+
#
|
64
|
+
def detect_env
|
65
|
+
@method = @env[ REQUEST_METHOD ]
|
66
|
+
@path = @env[ REQUEST_PATH ]
|
67
|
+
@host = @env[ HTTP_HOST ]
|
68
|
+
@query = @env[ QUERY_STRING ]
|
69
|
+
end
|
70
|
+
|
71
|
+
|
72
|
+
# ---------------------------------------------------------------------
|
73
|
+
# Request timer
|
74
|
+
# ---------------------------------------------------------------------
|
75
|
+
|
76
|
+
#
|
77
|
+
# Keep track of the request start time.
|
78
|
+
#
|
79
|
+
def start_timer
|
80
|
+
@start = Time.now
|
81
|
+
end
|
82
|
+
|
83
|
+
#
|
84
|
+
# Write the request completion time to the log.
|
85
|
+
#
|
86
|
+
def finish_timer
|
87
|
+
@finish = Time.now
|
88
|
+
@elapsed = ( ( @finish - @start ) * 1000.0 ).round(2)
|
89
|
+
@log.info "Web request complete. Elapsed time: #{@elapsed} ms"
|
90
|
+
end
|
91
|
+
|
92
|
+
|
93
|
+
# ---------------------------------------------------------------------
|
94
|
+
# Helper functions
|
95
|
+
# ---------------------------------------------------------------------
|
96
|
+
|
97
|
+
#
|
98
|
+
# Write the request information to the log.
|
99
|
+
#
|
100
|
+
def log
|
101
|
+
@log.info "#{@method} #{@host}#{@path}"
|
102
|
+
@log.info "Parameters: #{@query}"
|
103
|
+
end
|
104
|
+
|
105
|
+
end
|
106
|
+
end
|
107
|
+
end
|
@@ -0,0 +1,118 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 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
|
+
|
22
|
+
|
23
|
+
# ---------------------------------------------------------------------
|
24
|
+
# Initialization
|
25
|
+
# ---------------------------------------------------------------------
|
26
|
+
|
27
|
+
#
|
28
|
+
# Set up the web server.
|
29
|
+
#
|
30
|
+
def initialize( engine = nil,
|
31
|
+
code = Gloo::WebSvr::ResponseCode::SUCCESS,
|
32
|
+
type = HTML_TYPE, data = nil )
|
33
|
+
|
34
|
+
@engine = engine
|
35
|
+
@log = @engine.log if @engine
|
36
|
+
|
37
|
+
@code = code
|
38
|
+
@type = type
|
39
|
+
@data = data
|
40
|
+
end
|
41
|
+
|
42
|
+
|
43
|
+
# ---------------------------------------------------------------------
|
44
|
+
# Static Helper Functions
|
45
|
+
# ---------------------------------------------------------------------
|
46
|
+
|
47
|
+
#
|
48
|
+
# Helper to create a successful JSON response with the given data.
|
49
|
+
#
|
50
|
+
def self.json_response( engine, data,
|
51
|
+
code = Gloo::WebSvr::ResponseCode::SUCCESS )
|
52
|
+
|
53
|
+
return Gloo::WebSvr::Response.new( engine, code, JSON_TYPE, data )
|
54
|
+
end
|
55
|
+
|
56
|
+
#
|
57
|
+
# Helper to create a successful text response with the given data.
|
58
|
+
#
|
59
|
+
def self.text_response( engine, data,
|
60
|
+
code = Gloo::WebSvr::ResponseCode::SUCCESS )
|
61
|
+
|
62
|
+
return Gloo::WebSvr::Response.new( engine, code, TEXT_TYPE, data )
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Helper to create a successful web response with the given data.
|
67
|
+
#
|
68
|
+
def self.html_response( engine, data,
|
69
|
+
code = Gloo::WebSvr::ResponseCode::SUCCESS )
|
70
|
+
|
71
|
+
return Gloo::WebSvr::Response.new( engine, code, HTML_TYPE, data )
|
72
|
+
end
|
73
|
+
|
74
|
+
|
75
|
+
# ---------------------------------------------------------------------
|
76
|
+
# Data Functions
|
77
|
+
# ---------------------------------------------------------------------
|
78
|
+
|
79
|
+
#
|
80
|
+
# Add content to the payload.
|
81
|
+
#
|
82
|
+
def add content
|
83
|
+
@data = '' if @data.nil?
|
84
|
+
@data << content
|
85
|
+
end
|
86
|
+
|
87
|
+
#
|
88
|
+
# Get the headers for the response.
|
89
|
+
#
|
90
|
+
def headers
|
91
|
+
return { CONTENT_TYPE => @type }
|
92
|
+
end
|
93
|
+
|
94
|
+
#
|
95
|
+
# Get the final result that will be returned as the
|
96
|
+
# response to the web request.
|
97
|
+
#
|
98
|
+
def result
|
99
|
+
return [ @code, headers, @data ]
|
100
|
+
end
|
101
|
+
|
102
|
+
|
103
|
+
# ---------------------------------------------------------------------
|
104
|
+
# Helper functions
|
105
|
+
# ---------------------------------------------------------------------
|
106
|
+
|
107
|
+
#
|
108
|
+
# Write the result information to the log.
|
109
|
+
#
|
110
|
+
def log
|
111
|
+
return unless @log
|
112
|
+
|
113
|
+
@log.info "Response #{@code} #{@type}"
|
114
|
+
end
|
115
|
+
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|
@@ -0,0 +1,69 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 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 = 307.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
|
@@ -0,0 +1,179 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# A helper class for page routing.
|
5
|
+
#
|
6
|
+
|
7
|
+
module Gloo
|
8
|
+
module WebSvr
|
9
|
+
class Router
|
10
|
+
|
11
|
+
PAGE_CONTAINER = 'page'.freeze
|
12
|
+
INDEX = 'index'.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
|
+
end
|
31
|
+
|
32
|
+
|
33
|
+
# ---------------------------------------------------------------------
|
34
|
+
# Routing
|
35
|
+
# ---------------------------------------------------------------------
|
36
|
+
|
37
|
+
#
|
38
|
+
# Find and return the page for the given route.
|
39
|
+
#
|
40
|
+
def page_for_route path
|
41
|
+
@engine.log.info "routing to #{path}"
|
42
|
+
detect_segments path
|
43
|
+
|
44
|
+
return @web_svr_obj.home_page if is_root_path?
|
45
|
+
|
46
|
+
pages = @web_svr_obj.pages_container
|
47
|
+
return find_route_segment( pages.children ) if pages
|
48
|
+
|
49
|
+
return nil
|
50
|
+
end
|
51
|
+
|
52
|
+
|
53
|
+
# ---------------------------------------------------------------------
|
54
|
+
# Dynamic Add Page Routes
|
55
|
+
# ---------------------------------------------------------------------
|
56
|
+
|
57
|
+
#
|
58
|
+
# Get the root level page container.
|
59
|
+
#
|
60
|
+
def page_container
|
61
|
+
pn = Gloo::Core::Pn.new( @engine, PAGE_CONTAINER )
|
62
|
+
return pn.resolve
|
63
|
+
end
|
64
|
+
|
65
|
+
#
|
66
|
+
# Add all page routes to the web server pages (routes).
|
67
|
+
#
|
68
|
+
def add_page_routes
|
69
|
+
can = page_container
|
70
|
+
return unless can
|
71
|
+
|
72
|
+
@log.debug 'Adding page routes to web server…'
|
73
|
+
@factory = @engine.factory
|
74
|
+
|
75
|
+
add_pages can, @web_svr_obj.pages_container
|
76
|
+
end
|
77
|
+
|
78
|
+
#
|
79
|
+
# Add the pages to the web server pages.
|
80
|
+
# This is a recursive function that will add all
|
81
|
+
# pages in the folder and subfolders.
|
82
|
+
#
|
83
|
+
def add_pages can, parent
|
84
|
+
# for each file in the page container
|
85
|
+
# create a page object and add it to the routes
|
86
|
+
can.children.each do |obj|
|
87
|
+
if obj.class == Gloo::Objs::Container
|
88
|
+
child_can = parent.find_add_child( obj.name, 'container' )
|
89
|
+
add_pages( obj, child_can )
|
90
|
+
elsif obj.class == Gloo::Objs::Page
|
91
|
+
add_route_alias( parent, obj.name, obj.pn )
|
92
|
+
end
|
93
|
+
end
|
94
|
+
end
|
95
|
+
|
96
|
+
#
|
97
|
+
# Add route alias to the page.
|
98
|
+
#
|
99
|
+
def add_route_alias( parent, name, pn )
|
100
|
+
name = name.gsub( '.', '_' )
|
101
|
+
|
102
|
+
# First make sure the child doesn't already exist.
|
103
|
+
child = parent.find_child( name )
|
104
|
+
return if child
|
105
|
+
|
106
|
+
@factory.create_alias( name, pn, parent )
|
107
|
+
end
|
108
|
+
|
109
|
+
|
110
|
+
# ---------------------------------------------------------------------
|
111
|
+
# Helper funcions
|
112
|
+
# ---------------------------------------------------------------------
|
113
|
+
|
114
|
+
#
|
115
|
+
# Find the route segment in the object container.
|
116
|
+
#
|
117
|
+
def find_route_segment objs
|
118
|
+
this_segment = next_segment
|
119
|
+
|
120
|
+
this_segment = INDEX if this_segment.blank?
|
121
|
+
|
122
|
+
objs.each do |o|
|
123
|
+
o = Gloo::Objs::Alias.resolve_alias( @engine, o )
|
124
|
+
|
125
|
+
if o.name == this_segment
|
126
|
+
if o.class == Gloo::Objs::Page
|
127
|
+
@engine.log.debug "found page for route: #{o.pn}"
|
128
|
+
return o
|
129
|
+
elsif o.class == Gloo::Objs::FileHandle
|
130
|
+
@engine.log.debug "found static file for route: #{o.pn}"
|
131
|
+
return o
|
132
|
+
else
|
133
|
+
return nil unless o.child_count > 0
|
134
|
+
|
135
|
+
return find_route_segment( o.children )
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
139
|
+
|
140
|
+
return nil
|
141
|
+
end
|
142
|
+
|
143
|
+
#
|
144
|
+
# Get the next segment in the route.
|
145
|
+
#
|
146
|
+
def next_segment
|
147
|
+
this_segment = @route_segments.shift
|
148
|
+
return nil if this_segment.nil?
|
149
|
+
|
150
|
+
# A URL might include a dot in a name, but we can't do that
|
151
|
+
# because dot is a reserve path thing. So we replace it with
|
152
|
+
# an underscore.
|
153
|
+
this_segment = this_segment.gsub( '.', '_' )
|
154
|
+
|
155
|
+
return this_segment
|
156
|
+
end
|
157
|
+
|
158
|
+
#
|
159
|
+
# Is this the root path?
|
160
|
+
def is_root_path?
|
161
|
+
return @route_segments.count == 0
|
162
|
+
end
|
163
|
+
|
164
|
+
#
|
165
|
+
# Create a list of path segments.
|
166
|
+
#
|
167
|
+
def detect_segments path
|
168
|
+
# Split the path into segments.
|
169
|
+
@route_segments = path.split SEGMENT_DIVIDER
|
170
|
+
|
171
|
+
# Remove the first segment if it is empty.
|
172
|
+
@route_segments.shift if @route_segments.first.blank?
|
173
|
+
|
174
|
+
return @route_segments
|
175
|
+
end
|
176
|
+
|
177
|
+
end
|
178
|
+
end
|
179
|
+
end
|
@@ -0,0 +1,97 @@
|
|
1
|
+
# Author:: Eric Crane (mailto:eric.crane@mac.com)
|
2
|
+
# Copyright:: Copyright (c) 20124 Eric Crane. All rights reserved.
|
3
|
+
#
|
4
|
+
# Starting work on web server inside gloo.
|
5
|
+
#
|
6
|
+
# UNDER CONSTRUCTION!
|
7
|
+
#
|
8
|
+
# Simple tests:
|
9
|
+
# > curl http://localhost:8087/test/
|
10
|
+
# > curl http://localhost:8087/web/
|
11
|
+
# > curl http://localhost:8087/test/1
|
12
|
+
# > curl http://localhost:8087/test?param=123
|
13
|
+
#
|
14
|
+
# Run in loop:
|
15
|
+
# for i in {1..99}; do curl http://localhost:8087/; done
|
16
|
+
#
|
17
|
+
# Links:
|
18
|
+
# https://github.com/rack/rack
|
19
|
+
# https://github.com/rack/rack/blob/main/lib/rack/builder.rb
|
20
|
+
# https://thoughtbot.com/blog/ruby-rack-tutorial
|
21
|
+
# https://www.rubydoc.info/gems/rack/1.5.5/Rack/Runtime
|
22
|
+
#
|
23
|
+
|
24
|
+
require 'rack'
|
25
|
+
|
26
|
+
module Gloo
|
27
|
+
module WebSvr
|
28
|
+
class Server
|
29
|
+
|
30
|
+
# ---------------------------------------------------------------------
|
31
|
+
# Initialization
|
32
|
+
# ---------------------------------------------------------------------
|
33
|
+
|
34
|
+
#
|
35
|
+
# Set up the web server.
|
36
|
+
#
|
37
|
+
def initialize( engine, handler, config = nil )
|
38
|
+
@config = config ? config : Gloo::WebSvr::Config.new
|
39
|
+
@engine = engine
|
40
|
+
@log = @engine.log
|
41
|
+
@handler = handler
|
42
|
+
|
43
|
+
@log.debug 'Gloo web server intialized…'
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
# ---------------------------------------------------------------------
|
48
|
+
# Start and Stop the server.
|
49
|
+
# ---------------------------------------------------------------------
|
50
|
+
|
51
|
+
#
|
52
|
+
# Start the web server.
|
53
|
+
#
|
54
|
+
def start
|
55
|
+
opts = {
|
56
|
+
:Port => @config.port,
|
57
|
+
:Host => @config.host
|
58
|
+
}
|
59
|
+
Thread.abort_on_exception = true
|
60
|
+
@server_thread = Thread.new { Rack::Handler::Thin.run( self, **options=opts ) }
|
61
|
+
@log.debug 'Web server has started.'
|
62
|
+
end
|
63
|
+
|
64
|
+
#
|
65
|
+
# Stop the web server
|
66
|
+
#
|
67
|
+
def stop
|
68
|
+
@log.debug 'Stopping the web server…'
|
69
|
+
|
70
|
+
@server_thread.kill
|
71
|
+
|
72
|
+
@log.debug 'The web server has been stopped.'
|
73
|
+
end
|
74
|
+
|
75
|
+
|
76
|
+
# ---------------------------------------------------------------------
|
77
|
+
# Handle events
|
78
|
+
# ---------------------------------------------------------------------
|
79
|
+
|
80
|
+
#
|
81
|
+
# Handle a request for a resource.
|
82
|
+
#
|
83
|
+
def call( env )
|
84
|
+
request = Gloo::WebSvr::Request.new( @engine, @handler, env )
|
85
|
+
request.log
|
86
|
+
|
87
|
+
response = request.process
|
88
|
+
response.log if response
|
89
|
+
|
90
|
+
return response ? response.result : nil
|
91
|
+
end
|
92
|
+
|
93
|
+
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|