gloo 3.0.0 → 3.1.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/gloo.gemspec +1 -0
- data/lib/VERSION +1 -1
- data/lib/VERSION_NOTES +10 -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 +3 -0
- 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
|
+
|