angelo 0.4.1 → 0.5.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/.travis.yml +2 -6
- data/CHANGELOG.md +15 -1
- data/Gemfile +3 -7
- data/LICENSE +1 -1
- data/README.md +42 -5
- data/angelo.gemspec +1 -1
- data/code_of_conduct.md +50 -0
- data/lib/angelo.rb +18 -12
- data/lib/angelo/base.rb +81 -77
- data/lib/angelo/minitest/helpers.rb +10 -4
- data/lib/angelo/params_parser.rb +12 -3
- data/lib/angelo/responder.rb +14 -10
- data/lib/angelo/responder/eventsource.rb +2 -2
- data/lib/angelo/responder/websocket.rb +3 -12
- data/lib/angelo/server.rb +16 -5
- data/lib/angelo/stash.rb +8 -3
- data/lib/angelo/templates.rb +166 -0
- data/lib/angelo/tilt/erb.rb +15 -100
- data/lib/angelo/version.rb +1 -1
- data/test/angelo/erb_spec.rb +6 -0
- data/test/angelo/filter_spec.rb +17 -0
- data/test/angelo/params_spec.rb +21 -0
- data/test/angelo/stash_spec.rb +33 -3
- data/test/angelo/websocket_spec.rb +12 -12
- data/test/angelo_spec.rb +50 -8
- data/test/spec_helper.rb +2 -2
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 29657358947009a8401893f8db01b0c3522706ed
|
4
|
+
data.tar.gz: 721f0e9ef56f280f761518a620aa2a7ef562ae57
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6519c472ea84aa9098fd2bb186323a21b7c216d7e3b6e4927666b77f0226bb57c379159784a38d83305cf64908defb2d9c3ebcfb0d126c59916ec35c00ea5069
|
7
|
+
data.tar.gz: 110fffc25ad3e75c459aa0a484f52b2c73b8b9a318b5c8c904ec45135abfdd5aca658219910a0d993c6befe1493e9286e76b895528eeadd0fe79eeb74be58c30
|
data/.travis.yml
CHANGED
data/CHANGELOG.md
CHANGED
@@ -1,7 +1,21 @@
|
|
1
1
|
changelog
|
2
2
|
=========
|
3
3
|
|
4
|
-
### 0.
|
4
|
+
### 0.5.0 mar 2016
|
5
|
+
|
6
|
+
thanks: @tommay, @gunnarmarten, @nagius
|
7
|
+
|
8
|
+
* add Angelo::Templates as a better interface to Tilt
|
9
|
+
* haml / markdown support
|
10
|
+
* JSON array post body support (#48)
|
11
|
+
* add `request_body` helper for access to JSON array post bodies or `request.body.to_s`
|
12
|
+
* move `reload_templates!` to `Angelo::Base::DSL`
|
13
|
+
* support `Regexp` as only arg to `before` and `after` filters
|
14
|
+
* add post override support via `X-Angelo-PostOverride` header
|
15
|
+
* update celluloid API usage (#58)
|
16
|
+
* add `default_headers` DSL method (#61)
|
17
|
+
|
18
|
+
### 0.4.1 8 feb 2015
|
5
19
|
|
6
20
|
thanks: @tommay
|
7
21
|
|
data/Gemfile
CHANGED
@@ -1,14 +1,10 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
-
gem 'reel', '~>0.
|
4
|
-
|
5
|
-
gem 'mime-types', '~>2.4'
|
6
|
-
gem 'websocket-driver', '~>0.3'
|
7
|
-
gem 'mustermann', '~>0.4'
|
3
|
+
gem 'reel', '~>0.6.1'
|
4
|
+
gemspec
|
8
5
|
|
9
6
|
group :development do
|
10
7
|
gem 'pry', '~>0.10'
|
11
|
-
gem 'pry-nav', '~>0.2'
|
12
8
|
end
|
13
9
|
|
14
10
|
group :profile do
|
@@ -22,6 +18,6 @@ group :test do
|
|
22
18
|
gem 'minitest', '~>5.4'
|
23
19
|
|
24
20
|
platform :mri do
|
25
|
-
gem 'simplecov', '~>0.
|
21
|
+
gem 'simplecov', '~>0.11'
|
26
22
|
end
|
27
23
|
end
|
data/LICENSE
CHANGED
data/README.md
CHANGED
@@ -12,7 +12,7 @@ A [Sinatra](https://github.com/sinatra/sinatra)-like DSL for [Reel](https://gith
|
|
12
12
|
* contextual websocket/sse stashing via `websockets` and `sses` helpers
|
13
13
|
* `task` handling via `async` and `future` helpers
|
14
14
|
* no rack
|
15
|
-
*
|
15
|
+
* erb, haml, and markdown support
|
16
16
|
* mustermann support
|
17
17
|
|
18
18
|
### What is Angelo?
|
@@ -22,7 +22,7 @@ notable differences, but the basics remain the same: you can either create a "cl
|
|
22
22
|
by requiring 'angelo/main' and using the DSL at the top level of your script, or a "modular"
|
23
23
|
application by requiring 'angelo', subclassing `Angelo::Base`, and calling `.run!` on that class for the
|
24
24
|
service to start.
|
25
|
-
In addition, and perhaps more importantly, **Angelo is built
|
25
|
+
In addition, and perhaps more importantly, **Angelo is built on Reel, which is built on
|
26
26
|
Celluloid::IO and gives you a reactor with evented IO in Ruby!**
|
27
27
|
|
28
28
|
Things will feel very familiar to anyone experienced with Sinatra. You can define
|
@@ -525,6 +525,21 @@ end
|
|
525
525
|
HelloApp.run!
|
526
526
|
```
|
527
527
|
|
528
|
+
### JSON HTTP API
|
529
|
+
|
530
|
+
If you post JSON data with a JSON Content-Type, angelo will:
|
531
|
+
|
532
|
+
* merge objects into the `params` SymHash
|
533
|
+
* parse arrays and make them available via `request_body`
|
534
|
+
|
535
|
+
N.B. `request_body` is functionally equivalent to `request.body.to_s` otherwise.
|
536
|
+
|
537
|
+
If your `content_type` is set to `:json`, angelo will convert:
|
538
|
+
|
539
|
+
* anything returned from a route block that `respond_to? :to_json`
|
540
|
+
* `RequestError` message data
|
541
|
+
* `halt` data
|
542
|
+
|
528
543
|
### Documentation
|
529
544
|
|
530
545
|
**I'm bad at documentation and I feel bad.**
|
@@ -665,11 +680,33 @@ Foo.run!
|
|
665
680
|
|
666
681
|
### Contributing
|
667
682
|
|
668
|
-
|
683
|
+
Anyone is welcome to contribute. Conduct is guided by the [Contributor Covenant](http://contributor-covenant.org).
|
684
|
+
See `code_of_conduct.md`.
|
685
|
+
|
686
|
+
To contribute to Angelo, please:
|
687
|
+
|
688
|
+
* fork the repository to your GitHub account
|
689
|
+
* create a branch for the feature or fix
|
690
|
+
* commit your changes to that branch, please include tests if applicable
|
691
|
+
* submit a Pull Request back to the main repository's `master` branch
|
669
692
|
|
670
|
-
|
671
|
-
|
693
|
+
After review and acceptance, your changes will be merged and noted in `CHANGLOG.md`.
|
694
|
+
|
695
|
+
### Testing
|
696
|
+
|
697
|
+
Unit tests are done with Minitest. Run them with :
|
698
|
+
|
699
|
+
```
|
700
|
+
bundle install
|
701
|
+
rake test
|
702
|
+
```
|
672
703
|
|
673
704
|
### License
|
674
705
|
|
675
706
|
[Apache 2.0](LICENSE)
|
707
|
+
|
708
|
+
### Name
|
709
|
+
|
710
|
+
Why the name "Angelo"? Since the project mimics Sinatra's DSL, I thought it best to keep a reference to
|
711
|
+
The Chairman in the name. It turns out that Frank Sinatra won an Academy Award for his role 'Angelo
|
712
|
+
Maggio' in 'From Here to Eternity'. I appropriated the name since this is like Sinatra on Reel (film).
|
data/angelo.gemspec
CHANGED
@@ -13,7 +13,7 @@ Gem::Specification.new do |gem|
|
|
13
13
|
gem.version = Angelo::VERSION
|
14
14
|
gem.license = 'apache'
|
15
15
|
gem.required_ruby_version = '>= 2.1.0'
|
16
|
-
gem.add_runtime_dependency 'reel', '~>0.
|
16
|
+
gem.add_runtime_dependency 'reel', '~>0.6.1'
|
17
17
|
gem.add_runtime_dependency 'tilt', '~>2.0'
|
18
18
|
gem.add_runtime_dependency 'mustermann', '~>0.4'
|
19
19
|
gem.add_runtime_dependency 'mime-types', '~>2.4'
|
data/code_of_conduct.md
ADDED
@@ -0,0 +1,50 @@
|
|
1
|
+
# Contributor Code of Conduct
|
2
|
+
|
3
|
+
As contributors and maintainers of this project, and in the interest of
|
4
|
+
fostering an open and welcoming community, we pledge to respect all people who
|
5
|
+
contribute through reporting issues, posting feature requests, updating
|
6
|
+
documentation, submitting pull requests or patches, and other activities.
|
7
|
+
|
8
|
+
We are committed to making participation in this project a harassment-free
|
9
|
+
experience for everyone, regardless of level of experience, gender, gender
|
10
|
+
identity and expression, sexual orientation, disability, personal appearance,
|
11
|
+
body size, race, ethnicity, age, religion, or nationality.
|
12
|
+
|
13
|
+
Examples of unacceptable behavior by participants include:
|
14
|
+
|
15
|
+
* The use of sexualized language or imagery
|
16
|
+
* Personal attacks
|
17
|
+
* Trolling or insulting/derogatory comments
|
18
|
+
* Public or private harassment
|
19
|
+
* Publishing other's private information, such as physical or electronic
|
20
|
+
addresses, without explicit permission
|
21
|
+
* Other unethical or unprofessional conduct
|
22
|
+
|
23
|
+
Project maintainers have the right and responsibility to remove, edit, or
|
24
|
+
reject comments, commits, code, wiki edits, issues, and other contributions
|
25
|
+
that are not aligned to this Code of Conduct, or to ban temporarily or
|
26
|
+
permanently any contributor for other behaviors that they deem inappropriate,
|
27
|
+
threatening, offensive, or harmful.
|
28
|
+
|
29
|
+
By adopting this Code of Conduct, project maintainers commit themselves to
|
30
|
+
fairly and consistently applying these principles to every aspect of managing
|
31
|
+
this project. Project maintainers who do not follow or enforce the Code of
|
32
|
+
Conduct may be permanently removed from the project team.
|
33
|
+
|
34
|
+
This Code of Conduct applies both within project spaces and in public spaces
|
35
|
+
when an individual is representing the project or its community.
|
36
|
+
|
37
|
+
Instances of abusive, harassing, or otherwise unacceptable behavior may be
|
38
|
+
reported by contacting the project <a href="mailto:kenichi.nakamura@gmail.com">maintainer</a>. All
|
39
|
+
complaints will be reviewed and investigated and will result in a response that
|
40
|
+
is deemed necessary and appropriate to the circumstances. Maintainers are
|
41
|
+
obligated to maintain confidentiality with regard to the reporter of an
|
42
|
+
incident.
|
43
|
+
|
44
|
+
|
45
|
+
This Code of Conduct is adapted from the [Contributor Covenant][homepage],
|
46
|
+
version 1.3.0, available at
|
47
|
+
[http://contributor-covenant.org/version/1/3/0/][version]
|
48
|
+
|
49
|
+
[homepage]: http://contributor-covenant.org
|
50
|
+
[version]: http://contributor-covenant.org/version/1/3/0/
|
data/lib/angelo.rb
CHANGED
@@ -18,9 +18,13 @@ module Angelo
|
|
18
18
|
|
19
19
|
HTTPABLE = [:get, :post, :put, :delete, :options]
|
20
20
|
STATICABLE = [:get, :head]
|
21
|
+
POST_OVERRIDABLE = [:put, :delete]
|
21
22
|
|
22
23
|
ACCEPT_REQUEST_HEADER_KEY = 'Accept'
|
23
24
|
|
25
|
+
POST_OVERRIDE_REQUEST_HEADER_KEY = 'X-Angelo-PostOverride'
|
26
|
+
REAL_IP_REQUEST_HEADER_KEY = 'X-Real-IP'
|
27
|
+
|
24
28
|
CONTENT_TYPE_HEADER_KEY = 'Content-Type'
|
25
29
|
CONTENT_DISPOSITION_HEADER_KEY = 'Content-Disposition'
|
26
30
|
CONTENT_LENGTH_HEADER_KEY = 'Content-Length'
|
@@ -79,22 +83,23 @@ module Angelo
|
|
79
83
|
|
80
84
|
end
|
81
85
|
|
82
|
-
def self.log connection, request, socket, status, body_size = '-'
|
86
|
+
def self.log meth, connection, request, socket, status, body_size = '-'
|
83
87
|
|
84
|
-
remote_ip =
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
88
|
+
remote_ip = case
|
89
|
+
when request.headers[REAL_IP_REQUEST_HEADER_KEY]
|
90
|
+
request.headers[REAL_IP_REQUEST_HEADER_KEY]
|
91
|
+
when socket
|
92
|
+
socket.peeraddr(false)[3]
|
93
|
+
else
|
94
|
+
connection.remote_ip rescue 'unknown'
|
95
|
+
end
|
91
96
|
|
92
|
-
Celluloid::Logger.__send__ Angelo.response_log_level, LOG_FORMAT % [
|
93
|
-
remote_ip
|
94
|
-
request.method,
|
97
|
+
Celluloid::Internals::Logger.__send__ Angelo.response_log_level, LOG_FORMAT % [
|
98
|
+
remote_ip,
|
99
|
+
(meth && meth.upcase) || request.method,
|
95
100
|
request.url,
|
96
101
|
request.version,
|
97
|
-
Symbol === status ? HTTP::Response::
|
102
|
+
Symbol === status ? HTTP::Response::Status::SYMBOL_CODES[status] : status,
|
98
103
|
body_size
|
99
104
|
]
|
100
105
|
|
@@ -133,6 +138,7 @@ require 'angelo/server'
|
|
133
138
|
require 'angelo/responder'
|
134
139
|
require 'angelo/responder/eventsource'
|
135
140
|
require 'angelo/responder/websocket'
|
141
|
+
require 'angelo/templates'
|
136
142
|
require 'angelo/tilt/erb'
|
137
143
|
require 'angelo/base'
|
138
144
|
require 'angelo/stash'
|
data/lib/angelo/base.rb
CHANGED
@@ -3,60 +3,21 @@ module Angelo
|
|
3
3
|
class Base
|
4
4
|
extend Forwardable
|
5
5
|
include ParamsParser
|
6
|
-
include Celluloid::Logger
|
6
|
+
include Celluloid::Internals::Logger
|
7
|
+
include Templates
|
7
8
|
include Tilt::ERB
|
8
9
|
include Mustermann
|
9
10
|
|
10
|
-
def_delegators :@responder, :content_type, :headers, :mustermann, :redirect, :request, :transfer_encoding
|
11
|
+
def_delegators :@responder, :content_type, :headers, :mustermann, :redirect, :redirect!, :request, :transfer_encoding
|
11
12
|
def_delegators :@klass, :public_dir, :report_errors?, :sse_event, :sse_message, :sses, :websockets
|
12
13
|
|
13
14
|
attr_accessor :responder
|
14
|
-
|
15
|
-
class << self
|
16
|
-
|
17
|
-
attr_accessor :app_file, :server
|
18
|
-
|
19
|
-
def inherited subclass
|
20
|
-
|
21
|
-
# Set app_file by groveling up the caller stack until we find
|
22
|
-
# the first caller from a directory different from __FILE__.
|
23
|
-
# This allows base.rb to be required from an arbitrarily deep
|
24
|
-
# nesting of require "angelo/<whatever>" and still set
|
25
|
-
# app_file correctly.
|
26
|
-
#
|
27
|
-
subclass.app_file = caller_locations.map(&:absolute_path).find do |f|
|
28
|
-
!f.start_with?(File.dirname(__FILE__) + File::SEPARATOR)
|
29
|
-
end
|
30
|
-
|
31
|
-
# bring RequestError into this namespace
|
32
|
-
#
|
33
|
-
subclass.class_eval 'class RequestError < Angelo::RequestError; end'
|
34
|
-
|
35
|
-
subclass.addr DEFAULT_ADDR
|
36
|
-
subclass.port DEFAULT_PORT
|
37
|
-
|
38
|
-
subclass.ping_time DEFAULT_PING_TIME
|
39
|
-
subclass.log_level DEFAULT_LOG_LEVEL
|
40
|
-
|
41
|
-
# Parse command line options if angelo/main has been required.
|
42
|
-
# They could also be parsed in run, but this makes them
|
43
|
-
# available to and overridable by the DSL.
|
44
|
-
#
|
45
|
-
subclass.parse_options(ARGV.dup) if @angelo_main
|
46
|
-
|
47
|
-
class << subclass
|
48
|
-
|
49
|
-
def root
|
50
|
-
@root ||= File.expand_path '..', app_file
|
51
|
-
end
|
52
|
-
|
53
|
-
end
|
54
|
-
|
55
|
-
end
|
56
|
-
end
|
15
|
+
attr_writer :request_body
|
57
16
|
|
58
17
|
# Methods defined in module DSL will be available in the DSL both
|
59
|
-
# in Angelo::Base subclasses
|
18
|
+
# in Angelo::Base subclasses as class methods and, if angelo/main
|
19
|
+
# is required, in the top level DSL by forwarding to an anonymous
|
20
|
+
# Angelo::Base subclass.
|
60
21
|
|
61
22
|
module DSL
|
62
23
|
def addr a = nil
|
@@ -64,6 +25,11 @@ module Angelo
|
|
64
25
|
@addr
|
65
26
|
end
|
66
27
|
|
28
|
+
def port p = nil
|
29
|
+
@port = p if p
|
30
|
+
@port
|
31
|
+
end
|
32
|
+
|
67
33
|
def log_level ll = nil
|
68
34
|
@log_level = ll if ll
|
69
35
|
@log_level
|
@@ -74,20 +40,17 @@ module Angelo
|
|
74
40
|
@ping_time
|
75
41
|
end
|
76
42
|
|
77
|
-
def port p = nil
|
78
|
-
@port = p if p
|
79
|
-
@port
|
80
|
-
end
|
81
|
-
|
82
43
|
def views_dir d = nil
|
83
44
|
@views_dir = d if d
|
84
|
-
@views_dir ||= DEFAULT_VIEWS_DIR
|
85
45
|
File.join root, @views_dir
|
86
46
|
end
|
87
47
|
|
48
|
+
def reload_templates!(on = true)
|
49
|
+
@reload_templates = on
|
50
|
+
end
|
51
|
+
|
88
52
|
def public_dir d = nil
|
89
53
|
@public_dir = d if d
|
90
|
-
@public_dir ||= DEFAULT_PUBLIC_DIR
|
91
54
|
File.join root, @public_dir
|
92
55
|
end
|
93
56
|
|
@@ -98,13 +61,13 @@ module Angelo
|
|
98
61
|
HTTPABLE.each do |m|
|
99
62
|
define_method m do |path, opts = {}, &block|
|
100
63
|
path = ::Mustermann.new path, opts
|
101
|
-
routes[m][path] = Responder.new &block
|
64
|
+
routes[m][path] = Responder.new m, &block
|
102
65
|
end
|
103
66
|
end
|
104
67
|
|
105
68
|
def websocket path, &block
|
106
69
|
path = ::Mustermann.new path
|
107
|
-
routes[:websocket][path] = Responder::Websocket.new &block
|
70
|
+
routes[:websocket][path] = Responder::Websocket.new nil, &block
|
108
71
|
end
|
109
72
|
|
110
73
|
def eventsource path, headers = nil, &block
|
@@ -125,21 +88,61 @@ module Angelo
|
|
125
88
|
end
|
126
89
|
|
127
90
|
def on_pong &block
|
128
|
-
|
91
|
+
@on_pong = block if block
|
92
|
+
@on_pong
|
129
93
|
end
|
130
94
|
|
131
95
|
def content_type type
|
132
96
|
Responder.content_type type
|
133
97
|
end
|
134
98
|
|
99
|
+
def default_headers hs
|
100
|
+
Responder.default_headers = Responder.default_headers.merge hs
|
101
|
+
end
|
135
102
|
end
|
136
103
|
|
137
|
-
|
138
|
-
|
104
|
+
class << self
|
105
|
+
include DSL
|
139
106
|
|
140
|
-
|
107
|
+
attr_accessor :app_file, :server
|
108
|
+
|
109
|
+
def inherited subclass
|
110
|
+
|
111
|
+
# Set app_file by groveling up the caller stack until we find
|
112
|
+
# the first caller from a directory different from __FILE__.
|
113
|
+
# This allows base.rb to be required from an arbitrarily deep
|
114
|
+
# nesting of require "angelo/<whatever>" and still set
|
115
|
+
# app_file correctly.
|
116
|
+
#
|
117
|
+
subclass.app_file = caller_locations.map(&:absolute_path).find do |f|
|
118
|
+
!f.start_with?(File.dirname(__FILE__) + File::SEPARATOR)
|
119
|
+
end
|
120
|
+
|
121
|
+
# bring RequestError into this namespace
|
122
|
+
#
|
123
|
+
subclass.class_eval 'class RequestError < Angelo::RequestError; end'
|
124
|
+
|
125
|
+
subclass.addr DEFAULT_ADDR
|
126
|
+
subclass.port DEFAULT_PORT
|
127
|
+
|
128
|
+
subclass.ping_time DEFAULT_PING_TIME
|
129
|
+
subclass.log_level DEFAULT_LOG_LEVEL
|
130
|
+
|
131
|
+
subclass.views_dir DEFAULT_VIEWS_DIR
|
132
|
+
subclass.public_dir DEFAULT_PUBLIC_DIR
|
133
|
+
|
134
|
+
# Parse command line options if angelo/main has been required.
|
135
|
+
# They could also be parsed in run, but this makes them
|
136
|
+
# available to and overridable by the DSL.
|
137
|
+
#
|
138
|
+
subclass.parse_options(ARGV.dup) if @angelo_main
|
139
|
+
|
140
|
+
end
|
141
|
+
|
142
|
+
def root
|
143
|
+
@root ||= File.expand_path '..', app_file
|
144
|
+
end
|
141
145
|
|
142
|
-
class << self
|
143
146
|
def report_errors?
|
144
147
|
!!@report_errors
|
145
148
|
end
|
@@ -149,12 +152,15 @@ module Angelo
|
|
149
152
|
end
|
150
153
|
|
151
154
|
def filters
|
152
|
-
@filters ||= {
|
155
|
+
@filters ||= {
|
156
|
+
before: Hash.new{|h,k| h[k] = []},
|
157
|
+
after: Hash.new{|h,k| h[k] = []},
|
158
|
+
}
|
153
159
|
end
|
154
160
|
|
155
161
|
def filter which, opts = {}, &block
|
156
162
|
case opts
|
157
|
-
when String
|
163
|
+
when String, Regexp
|
158
164
|
filter_by which, opts, block
|
159
165
|
when Hash
|
160
166
|
if opts[:path]
|
@@ -167,7 +173,6 @@ module Angelo
|
|
167
173
|
|
168
174
|
def filter_by which, path, block
|
169
175
|
pattern = ::Mustermann.new path
|
170
|
-
filters[which][pattern] ||= []
|
171
176
|
filters[which][pattern] << block
|
172
177
|
end
|
173
178
|
|
@@ -247,12 +252,16 @@ module Angelo
|
|
247
252
|
if Symbol === key
|
248
253
|
k = key.to_s.upcase
|
249
254
|
k.gsub! UNDERSCORE, DASH
|
250
|
-
|
251
|
-
hash[key] =
|
255
|
+
_, value = request.headers.find {|header_key,v| header_key.upcase == k}
|
256
|
+
hash[key] = value
|
252
257
|
end
|
253
258
|
end
|
254
259
|
end
|
255
260
|
|
261
|
+
def request_body
|
262
|
+
@request_body ||= request.body.to_s
|
263
|
+
end
|
264
|
+
|
256
265
|
task :handle_websocket do |ws|
|
257
266
|
begin
|
258
267
|
while !ws.closed? do
|
@@ -266,9 +275,7 @@ module Angelo
|
|
266
275
|
|
267
276
|
task :ping_websockets do
|
268
277
|
every(@base.ping_time) do
|
269
|
-
websockets.all_each
|
270
|
-
ws.socket << ::WebSocket::Message.ping.to_data
|
271
|
-
end
|
278
|
+
websockets.all_each {|ws| ws.ping &@base.on_pong }
|
272
279
|
end
|
273
280
|
end
|
274
281
|
|
@@ -353,11 +360,11 @@ module Angelo
|
|
353
360
|
when :default
|
354
361
|
filters.each {|filter| instance_eval &filter}
|
355
362
|
when ::Mustermann
|
356
|
-
if pattern.
|
357
|
-
|
358
|
-
@params =
|
363
|
+
if mustermann_params = pattern.params(request.path)
|
364
|
+
pre_filter_params = params
|
365
|
+
@params = pre_filter_params.merge mustermann_params
|
359
366
|
filters.each {|filter| instance_eval &filter}
|
360
|
-
@params =
|
367
|
+
@params = pre_filter_params
|
361
368
|
end
|
362
369
|
end
|
363
370
|
end
|
@@ -402,11 +409,8 @@ module Angelo
|
|
402
409
|
end
|
403
410
|
|
404
411
|
def [] route
|
405
|
-
responder =
|
406
|
-
|
407
|
-
responder = @hash.fetch mustermann
|
408
|
-
responder.mustermann = mustermann
|
409
|
-
end
|
412
|
+
mustermann, responder = @hash.find {|k,v| k.match(route)}
|
413
|
+
responder.mustermann = mustermann if mustermann
|
410
414
|
responder
|
411
415
|
end
|
412
416
|
|