simple-httpd 0.3.5 → 0.4.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/.rubocop.yml +1 -1
- data/.ruby-version +1 -0
- data/README.md +6 -17
- data/VERSION +1 -1
- data/examples/README.md +6 -6
- data/examples/ex1/{root.rb → routes.rb} +8 -0
- data/examples/{ex1.services → ex1/services}/ex1_service_module.rb +0 -0
- data/examples/ex2/{ex2_helpers.rb → helpers/ex2_helpers.rb} +0 -0
- data/examples/ex2/helpers/helpers.rb +0 -0
- data/examples/ex2/routes.rb +22 -0
- data/examples/ex3/{example_service.rb → routes.rb} +0 -0
- data/examples/v2/{v2_helpers.rb → helpers/v2_helpers.rb} +0 -0
- data/examples/v2/{jobs.rb → routes.rb} +6 -2
- data/lib/simple/httpd/rack/dynamic_mount.rb +12 -50
- data/lib/simple/httpd/reloader.rb +16 -4
- data/lib/simple/httpd/service_integration.rb +11 -2
- data/spec/simple/httpd/base_spec.rb +1 -1
- data/spec/simple/httpd/dynamic_mounting_spec.rb +4 -4
- data/spec/simple/httpd/static_mounting_spec.rb +1 -1
- data/spec/spec_helper.rb +1 -1
- metadata +10 -12
- data/examples/ex1/spec.rb +0 -7
- data/examples/ex2/helpers.rb +0 -15
- data/examples/ex2/info.rb +0 -6
- data/examples/ex2/root.rb +0 -3
- data/examples/v2/root.rb +0 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 02564f089db886a8701424a42bedbe88bb6401febc4eb397b5630560bd82595a
|
4
|
+
data.tar.gz: 139371909bee1f7045f51d5ad6a0ee4b18f080eb461e8a8770c16ad506fb7e73
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 52fdf766ce5cd92ef52426f739c4fb3ec3af76703c6e2190bc20873d0a3f01c28ed6e0f22aa3d79870fb8e13d755b61cf0280935747429d693278d175036766d
|
7
|
+
data.tar.gz: 7b88cdc01ea262105f25dbdb5fcd28c75d464cd5d0e1bda597e51002355310f2dc96ccecedd64bb5e1266306e01fcadfc6ea98609352b9a56eb1db2a0d1ce298
|
data/.rubocop.yml
CHANGED
data/.ruby-version
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
2.5.7
|
data/README.md
CHANGED
@@ -30,13 +30,9 @@ They become available at the location specified by their filename and extension.
|
|
30
30
|
|
31
31
|
### Dynamic assets
|
32
32
|
|
33
|
-
Each mounted directory
|
33
|
+
Each mounted directory might contain a "routes.rb" ruby source file which is loaded in the context of a Sinatra controller to set up routes. Example:
|
34
34
|
|
35
|
-
|
36
|
-
|
37
|
-
All other ruby files implement HTTP handlers in typical sinatra fashion:
|
38
|
-
|
39
|
-
# in v2/jobs.rb
|
35
|
+
# in v2/routes.rb
|
40
36
|
get "/queue/:id/events" do
|
41
37
|
events = [
|
42
38
|
{ job_id: params[:id], id: "event1" },
|
@@ -46,16 +42,10 @@ All other ruby files implement HTTP handlers in typical sinatra fashion:
|
|
46
42
|
json events
|
47
43
|
end
|
48
44
|
|
49
|
-
|
50
|
-
|
51
|
-
To implement a action on the mountpoint itself one uses the `root.rb` file. The following
|
52
|
-
|
53
|
-
# in v2/root.rb
|
54
|
-
get "/" do
|
55
|
-
json version: "123"
|
56
|
-
end
|
45
|
+
Ruby files below `./helpers` in the dynamically loaded directory is loaded as a helper file when setting up a dynamic mount, e.g. `examples/ex1/helpers/ex1_helpers.rb` are executed in the context of a directory tree's root controller and provide functionality
|
46
|
+
available in the `routes.rb` file.
|
57
47
|
|
58
|
-
|
48
|
+
[TODO] describe service usage.
|
59
49
|
|
60
50
|
## Command line usage
|
61
51
|
|
@@ -77,8 +67,7 @@ The arguments `ex1` and `ex2` serve at the `/` location. This notation really is
|
|
77
67
|
port = 12345
|
78
68
|
|
79
69
|
app = ::Simple::Httpd.build("/" => httpd_root_dir)
|
80
|
-
::Simple::Httpd.listen! app, port: port,
|
81
|
-
logger: ::Logger.new(STDERR)
|
70
|
+
::Simple::Httpd.listen! app, port: port, logger: ::Logger.new(STDERR)
|
82
71
|
|
83
72
|
|
84
73
|
## The example application
|
data/VERSION
CHANGED
@@ -1 +1 @@
|
|
1
|
-
0.
|
1
|
+
0.4.0
|
data/examples/README.md
CHANGED
@@ -18,14 +18,14 @@ The following explanations assume you started a server with the configuration me
|
|
18
18
|
|
19
19
|
This directory currently contains these files:
|
20
20
|
|
21
|
-
- ex1/
|
21
|
+
- ex1/routes.rb
|
22
22
|
- ex1/ex1_helpers.rb
|
23
23
|
- ex2/helpers.rb
|
24
|
-
- ex2/
|
24
|
+
- ex2/routes.rb
|
25
25
|
- ex2/info.rb
|
26
26
|
- ex2/ex2_helpers.rb
|
27
27
|
- ex2/README.txt
|
28
|
-
- v2/
|
28
|
+
- v2/routes.rb
|
29
29
|
- v2/jobs.rb
|
30
30
|
- v2/v2_helpers.rb
|
31
31
|
- v2/api.js
|
@@ -34,8 +34,8 @@ This directory currently contains these files:
|
|
34
34
|
|
35
35
|
The following lists some routes and where they are implemented:
|
36
36
|
|
37
|
-
GET "/" .. in ex1/
|
38
|
-
GET "/debug" .. in ex2/
|
37
|
+
GET "/" .. in ex1/routes.rb
|
38
|
+
GET "/debug" .. in ex2/routes.rb
|
39
39
|
GET "/info/inspect" .. in ex2/info.rb
|
40
|
-
GET "/api/v2/" .. in v2/
|
40
|
+
GET "/api/v2/" .. in v2/routes.rb
|
41
41
|
GET "/api/v2/jobs/:id/events" .. in v2/jobs.rb
|
File without changes
|
File without changes
|
File without changes
|
@@ -0,0 +1,22 @@
|
|
1
|
+
get "/debug" do
|
2
|
+
debug params
|
3
|
+
end
|
4
|
+
|
5
|
+
[:get, :post, :put, :delete, :head].each do |verb|
|
6
|
+
send verb, "/info/inspect" do
|
7
|
+
content_type :text
|
8
|
+
request.env.map { |key, value| "#{key}=#{value}\n" }.grep(/^[A-Z]/).sort.join
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
get "/helpers/ex1" do
|
13
|
+
ex1_helper
|
14
|
+
rescue NameError
|
15
|
+
not_found! "ex1_helper cannot be run"
|
16
|
+
end
|
17
|
+
|
18
|
+
get "/helpers/ex2" do
|
19
|
+
ex2_helper
|
20
|
+
rescue NameError
|
21
|
+
not_found! "ex2_helper cannot be run"
|
22
|
+
end
|
File without changes
|
File without changes
|
@@ -1,9 +1,13 @@
|
|
1
|
-
get "/
|
1
|
+
get "/" do
|
2
|
+
json version: "v2"
|
3
|
+
end
|
4
|
+
|
5
|
+
get "/jobs/info" do
|
2
6
|
content_type :text
|
3
7
|
"info"
|
4
8
|
end
|
5
9
|
|
6
|
-
get "/:id/events" do
|
10
|
+
get "/jobs/:id/events" do
|
7
11
|
events = [
|
8
12
|
{ job_id: params[:id], id: "event1" },
|
9
13
|
{ job_id: params[:id], id: "event2" }
|
@@ -5,7 +5,6 @@ require "expectation"
|
|
5
5
|
# existing static files.
|
6
6
|
class Simple::Httpd::Rack::DynamicMount
|
7
7
|
H = ::Simple::Httpd::Helpers
|
8
|
-
Rack = ::Simple::Httpd::Rack
|
9
8
|
|
10
9
|
extend Forwardable
|
11
10
|
|
@@ -27,13 +26,15 @@ class Simple::Httpd::Rack::DynamicMount
|
|
27
26
|
@mount_point = mount_point
|
28
27
|
@path = path.gsub(/\/\z/, "") # remove trailing "/"
|
29
28
|
|
30
|
-
setup_paths!
|
31
29
|
::Simple::Httpd::Reloader.attach self, paths: service_files, reloading_instance: nil
|
32
30
|
|
33
|
-
@
|
34
|
-
|
31
|
+
@rack_app = H.subclass ::Simple::Httpd::BaseController,
|
32
|
+
paths: helper_files + ["#{path}/routes.rb"],
|
33
|
+
description: "<controller:#{H.shorten_path(path)}>"
|
35
34
|
|
36
|
-
@rack_app
|
35
|
+
@rack_app.route_descriptions.each do |route|
|
36
|
+
describe_route! route.prefix(@mount_point)
|
37
|
+
end
|
37
38
|
end
|
38
39
|
|
39
40
|
# RouteDescriptions are being built during build_url_map
|
@@ -41,54 +42,15 @@ class Simple::Httpd::Rack::DynamicMount
|
|
41
42
|
|
42
43
|
private
|
43
44
|
|
44
|
-
def logger
|
45
|
-
::Simple::Httpd.logger
|
46
|
-
end
|
47
|
-
|
48
|
-
def setup_paths!
|
49
|
-
@source_paths = Dir.glob("#{path}/**/*.rb")
|
50
|
-
@helper_paths, @controller_paths = @source_paths.partition { |str| /_helper(s?)\.rb$/ =~ str }
|
51
|
-
|
52
|
-
logger.info "#{path}: found #{@source_paths.count} sources, #{@helper_paths.count} helpers"
|
53
|
-
end
|
54
|
-
|
55
45
|
def service_files
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
def _service_files
|
60
|
-
return [] if path == "." # i.e. mounting current directory
|
61
|
-
|
62
|
-
service_path = "#{path}.services"
|
63
|
-
return [] unless Dir.exist?(service_path)
|
64
|
-
|
65
|
-
service_files = Dir.glob("#{service_path}/**/*.rb").sort
|
66
|
-
logger.info "#{service_path}: loading #{service_files.count} service file(s)"
|
46
|
+
service_files = Dir.glob("#{path}/services/**/*.rb").sort
|
47
|
+
::Simple::Httpd.logger.info "#{path}: loading #{service_files.count} service file(s)" if service_files.count > 0
|
67
48
|
service_files
|
68
49
|
end
|
69
50
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
description: "<root controller: #{H.shorten_path path}>"
|
75
|
-
end
|
76
|
-
|
77
|
-
def build_url_map
|
78
|
-
@controller_paths.sort.each_with_object({}) do |absolute_path, hsh|
|
79
|
-
relative_path = absolute_path[(path.length)..-1]
|
80
|
-
|
81
|
-
relative_mount_point = relative_path == "/root.rb" ? "/" : relative_path.gsub(/\.rb$/, "")
|
82
|
-
controller_class = H.subclass @root_controller,
|
83
|
-
paths: absolute_path,
|
84
|
-
description: "<controller:#{H.shorten_absolute_path(absolute_path)}>"
|
85
|
-
|
86
|
-
controller_class.route_descriptions.each do |route|
|
87
|
-
route = route.prefix(@mount_point, relative_mount_point)
|
88
|
-
describe_route! route
|
89
|
-
end
|
90
|
-
|
91
|
-
hsh.update relative_mount_point => controller_class
|
92
|
-
end
|
51
|
+
def helper_files
|
52
|
+
helper_files = Dir.glob("#{path}/helpers/**/*.rb").sort
|
53
|
+
::Simple::Httpd.logger.info "#{path}: loading #{helper_files.count} helper file(s)" if helper_files.count > 0
|
54
|
+
helper_files
|
93
55
|
end
|
94
56
|
end
|
@@ -50,12 +50,24 @@ module Simple::Httpd::Reloader
|
|
50
50
|
"#{verb} #{H.shorten_path path}"
|
51
51
|
end
|
52
52
|
|
53
|
-
|
54
|
-
@__reloading_instance__
|
55
|
-
|
56
|
-
|
53
|
+
silence_warnings do
|
54
|
+
if @__reloading_instance__
|
55
|
+
@__reloading_instance__.instance_eval File.read(path), path, 1
|
56
|
+
else
|
57
|
+
load path
|
58
|
+
end
|
57
59
|
end
|
58
60
|
|
59
61
|
@__source_mtimes_by_path__[path] = mtime
|
60
62
|
end
|
63
|
+
|
64
|
+
def silence_warnings(&block)
|
65
|
+
_ = block
|
66
|
+
|
67
|
+
warn_level = $VERBOSE
|
68
|
+
$VERBOSE = nil
|
69
|
+
yield
|
70
|
+
ensure
|
71
|
+
$VERBOSE = warn_level
|
72
|
+
end
|
61
73
|
end
|
@@ -1,3 +1,6 @@
|
|
1
|
+
# rubocop:disable Lint/RescueException
|
2
|
+
# rubocop:disable Metrics/AbcSize
|
3
|
+
|
1
4
|
require "simple-service"
|
2
5
|
|
3
6
|
module Simple::Httpd::ServiceIntegration
|
@@ -86,8 +89,11 @@ module Simple::Httpd::ServiceIntegration
|
|
86
89
|
::Simple::Service.with_context(context) do
|
87
90
|
result = service.invoke(action_name, args: parsed_body, flags: stringified_params)
|
88
91
|
encode_result(result)
|
92
|
+
rescue Errno::ENOENT => e
|
93
|
+
Simple::Httpd.logger.warn e.to_s
|
94
|
+
raise
|
89
95
|
rescue Exception => e
|
90
|
-
Simple::Httpd.logger.warn "#{e}, from\n #{e.backtrace[0,10].join("\n ")}"
|
96
|
+
Simple::Httpd.logger.warn "#{e}, from\n #{e.backtrace[0, 10].join("\n ")}"
|
91
97
|
raise
|
92
98
|
end
|
93
99
|
end
|
@@ -103,8 +109,11 @@ module Simple::Httpd::ServiceIntegration
|
|
103
109
|
result = encode_result(result)
|
104
110
|
end
|
105
111
|
result
|
112
|
+
rescue Errno::ENOENT => e
|
113
|
+
Simple::Httpd.logger.warn e.to_s
|
114
|
+
raise
|
106
115
|
rescue Exception => e
|
107
|
-
Simple::Httpd.logger.warn "#{e}, from\n #{e.backtrace[0,10].join("\n ")}"
|
116
|
+
Simple::Httpd.logger.warn "#{e}, from\n #{e.backtrace[0, 10].join("\n ")}"
|
108
117
|
raise
|
109
118
|
end
|
110
119
|
end
|
@@ -1,13 +1,13 @@
|
|
1
1
|
require "spec_helper"
|
2
2
|
|
3
3
|
describe "dynamic mounting" do
|
4
|
-
it "resolves routes from
|
4
|
+
it "resolves routes from routes.rb" do
|
5
5
|
http.get "/"
|
6
6
|
expect_response "root"
|
7
7
|
end
|
8
8
|
|
9
9
|
# mounting not at root level
|
10
|
-
it "gets deep route from a
|
10
|
+
it "gets deep route from a routes.rb file not mounted at /" do
|
11
11
|
http.get "/api/v2"
|
12
12
|
expect(http.content).to eq("version" => "v2")
|
13
13
|
expect(http.response.headers["content-type"]).to match(/application\/json/)
|
@@ -19,13 +19,13 @@ describe "dynamic mounting" do
|
|
19
19
|
expect(http.response.headers["content-type"]).to match(/application\/javascript/)
|
20
20
|
end
|
21
21
|
|
22
|
-
it "gets deep route from non-
|
22
|
+
it "gets deep route from non-routes.rb file" do
|
23
23
|
http.get "/api/v2/jobs/info"
|
24
24
|
expect_response "info"
|
25
25
|
expect(http.response.headers["content-type"]).to match(/text\/plain/)
|
26
26
|
end
|
27
27
|
|
28
|
-
it "gets deep route with params from non-
|
28
|
+
it "gets deep route with params from non-routes.rb file" do
|
29
29
|
http.get "/api/v2/jobs/12/events"
|
30
30
|
expect(http.response.headers["content-type"]).to match(/application\/json/)
|
31
31
|
expect(http.content).to eq([{ "job_id" => "12", "id" => "event1" }, { "job_id" => "12", "id" => "event2" }])
|
data/spec/spec_helper.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-httpd
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- radiospiel
|
@@ -90,6 +90,7 @@ files:
|
|
90
90
|
- ".envrc"
|
91
91
|
- ".gitignore"
|
92
92
|
- ".rubocop.yml"
|
93
|
+
- ".ruby-version"
|
93
94
|
- ".tm_properties"
|
94
95
|
- Gemfile
|
95
96
|
- Makefile
|
@@ -102,21 +103,18 @@ files:
|
|
102
103
|
- bin/rspec
|
103
104
|
- bin/simple-httpd
|
104
105
|
- examples/README.md
|
105
|
-
- examples/ex1.services/ex1_service_module.rb
|
106
106
|
- examples/ex1/ex1_helpers.rb
|
107
|
-
- examples/ex1/
|
108
|
-
- examples/ex1/
|
107
|
+
- examples/ex1/routes.rb
|
108
|
+
- examples/ex1/services/ex1_service_module.rb
|
109
109
|
- examples/ex2/README.txt
|
110
|
-
- examples/ex2/ex2_helpers.rb
|
111
|
-
- examples/ex2/helpers.rb
|
112
|
-
- examples/ex2/
|
113
|
-
- examples/
|
114
|
-
- examples/ex3/example_service.rb
|
110
|
+
- examples/ex2/helpers/ex2_helpers.rb
|
111
|
+
- examples/ex2/helpers/helpers.rb
|
112
|
+
- examples/ex2/routes.rb
|
113
|
+
- examples/ex3/routes.rb
|
115
114
|
- examples/services/explicit_example_service.rb
|
116
115
|
- examples/v2/api.js
|
117
|
-
- examples/v2/
|
118
|
-
- examples/v2/
|
119
|
-
- examples/v2/v2_helpers.rb
|
116
|
+
- examples/v2/helpers/v2_helpers.rb
|
117
|
+
- examples/v2/routes.rb
|
120
118
|
- lib/simple-httpd.rb
|
121
119
|
- lib/simple-service.rb
|
122
120
|
- lib/simple.rb
|
data/examples/ex1/spec.rb
DELETED
data/examples/ex2/helpers.rb
DELETED
data/examples/ex2/info.rb
DELETED
data/examples/ex2/root.rb
DELETED
data/examples/v2/root.rb
DELETED