tynn 1.2.0 → 1.3.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/README.md +13 -16
- data/lib/tynn.rb +5 -4
- data/lib/tynn/protection.rb +4 -12
- data/lib/tynn/session.rb +5 -3
- data/lib/tynn/ssl.rb +115 -0
- data/lib/tynn/version.rb +1 -1
- data/test/ssl_test.rb +60 -0
- metadata +5 -11
- data/lib/tynn/force_ssl.rb +0 -55
- data/lib/tynn/hsts.rb +0 -64
- data/lib/tynn/matchers.rb +0 -60
- data/test/force_ssl_test.rb +0 -32
- data/test/hsts_test.rb +0 -29
- data/test/matchers_test.rb +0 -40
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: c01166fc9c243f8e396f2b5f0f9007681524c7f0
|
4
|
+
data.tar.gz: f09380715acf0839c39dba34ead60ff161ec4aaf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 8e14f1f08ec671c79ed112f81b1420569498ea7e172a4e6faf6ecc2ed45aea7ac1cdc6c7307183fc71944c0c4ddf947ebf2e7b95d2f24544a0880efca47682e1
|
7
|
+
data.tar.gz: f99c0c15c44108e86a2cc8514fea0f16d323671a706209b5a05a6e1d8f297b5b8828e369483fbf1aaff70fcef37a81c43cd347656d01ca17bc66bb0cc5d441e6
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
|
1
|
+
Tynn [](https://travis-ci.org/frodsan/tynn)
|
2
2
|
====
|
3
3
|
|
4
4
|
A thin library for web development.
|
@@ -27,27 +27,24 @@ end
|
|
27
27
|
run(Tynn)
|
28
28
|
```
|
29
29
|
|
30
|
-
|
31
|
-
message.
|
30
|
+
Check [Getting Started][start] for more information.
|
32
31
|
|
33
|
-
|
34
|
-
|
32
|
+
Documentation
|
33
|
+
-------------
|
35
34
|
|
36
|
-
|
37
|
-
$ gem install tynn
|
38
|
-
```
|
35
|
+
See our website: <http://tynn.xyz/>.
|
39
36
|
|
40
37
|
Contributing
|
41
38
|
------------
|
42
39
|
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
40
|
+
Please see the [CONTRIBUTING][contributing] file for more information.
|
41
|
+
|
42
|
+
License
|
43
|
+
-------
|
47
44
|
|
48
|
-
|
49
|
-
[gst][gst] if you're using chruby) to keep things isolated.
|
45
|
+
Tynn is released under the [MIT License][mit].
|
50
46
|
|
47
|
+
[contributing]: https://github.com/frodsan/tynn/blob/master/CONTRIBUTING.md
|
48
|
+
[mit]: http://www.opensource.org/licenses/MIT
|
49
|
+
[start]: http://tynn.xyz/getting-started.html
|
51
50
|
[syro]: http://soveran.github.io/syro/
|
52
|
-
[gs]: https://github.com/soveran/gs
|
53
|
-
[gst]: https://github.com/tonchis/gst
|
data/lib/tynn.rb
CHANGED
@@ -69,7 +69,7 @@ class Tynn
|
|
69
69
|
# Tynn.use(Rack::ShowExceptions)
|
70
70
|
#
|
71
71
|
def self.use(middleware, *args, &block)
|
72
|
-
|
72
|
+
self.middleware << proc { |app| middleware.new(app, *args, &block) }
|
73
73
|
end
|
74
74
|
|
75
75
|
def self.call(env) # :nodoc:
|
@@ -77,14 +77,15 @@ class Tynn
|
|
77
77
|
end
|
78
78
|
|
79
79
|
def self.build_app(syro) # :nodoc:
|
80
|
-
if
|
80
|
+
if middleware.empty?
|
81
81
|
@app = syro
|
82
82
|
else
|
83
|
-
@app =
|
83
|
+
@app = middleware.reverse.inject(syro) { |a, m| m.call(a) }
|
84
84
|
end
|
85
85
|
end
|
86
86
|
|
87
|
-
|
87
|
+
# Internal: Returns middleware stack.
|
88
|
+
def self.middleware
|
88
89
|
return @middleware ||= []
|
89
90
|
end
|
90
91
|
|
data/lib/tynn/protection.rb
CHANGED
@@ -26,27 +26,19 @@ class Tynn
|
|
26
26
|
#
|
27
27
|
# If the +:ssl+ option is +true+, includes:
|
28
28
|
#
|
29
|
-
# - Tynn::
|
30
|
-
#
|
31
|
-
# - Tynn::ForceSSL
|
29
|
+
# - Tynn::SSL
|
32
30
|
#
|
33
31
|
module Protection
|
34
32
|
# Internal: Configures security related plugins.
|
35
|
-
def self.setup(app, ssl: false,
|
33
|
+
def self.setup(app, ssl: false, hsts: {})
|
36
34
|
app.plugin(Tynn::SecureHeaders)
|
37
35
|
|
38
36
|
if ssl
|
39
37
|
app.settings[:ssl] = true
|
40
38
|
|
41
|
-
require_relative "
|
42
|
-
|
43
|
-
app.plugin(Tynn::HSTS, hsts)
|
44
|
-
end
|
45
|
-
|
46
|
-
if force_ssl
|
47
|
-
require_relative "force_ssl"
|
39
|
+
require_relative "ssl"
|
48
40
|
|
49
|
-
app.plugin(Tynn::
|
41
|
+
app.plugin(Tynn::SSL, hsts: hsts)
|
50
42
|
end
|
51
43
|
end
|
52
44
|
end
|
data/lib/tynn/session.rb
CHANGED
@@ -62,9 +62,11 @@ class Tynn
|
|
62
62
|
module Session
|
63
63
|
# Internal: Configures Rack::Session::Cookie middleware.
|
64
64
|
def self.setup(app, options = {})
|
65
|
-
|
65
|
+
if app.settings[:ssl]
|
66
|
+
options = { secure: true }.merge(options)
|
67
|
+
end
|
66
68
|
|
67
|
-
app.use(Rack::Session::Cookie,
|
69
|
+
app.use(Rack::Session::Cookie, options)
|
68
70
|
end
|
69
71
|
|
70
72
|
module InstanceMethods
|
@@ -78,7 +80,7 @@ class Tynn
|
|
78
80
|
# session[:foo] # => "foo"
|
79
81
|
#
|
80
82
|
def session
|
81
|
-
return
|
83
|
+
return req.session
|
82
84
|
end
|
83
85
|
end
|
84
86
|
end
|
data/lib/tynn/ssl.rb
ADDED
@@ -0,0 +1,115 @@
|
|
1
|
+
class Tynn
|
2
|
+
# Public: Enforces secure HTTP requests by:
|
3
|
+
#
|
4
|
+
# 1. Redirecting HTTP requests to their HTTPS counterparts.
|
5
|
+
#
|
6
|
+
# 2. Setting the +Strict-Transport-Security+ header. This ensures the
|
7
|
+
# browser never visits the http version of a website. This reduces
|
8
|
+
# the impact of leaking session data through cookies and external
|
9
|
+
# links, and defends against Man-in-the-middle attacks.
|
10
|
+
#
|
11
|
+
# Examples
|
12
|
+
#
|
13
|
+
# require "tynn"
|
14
|
+
# require "tynn/ssl"
|
15
|
+
# require "tynn/test"
|
16
|
+
#
|
17
|
+
# Tynn.plugin(Tynn::SSL)
|
18
|
+
#
|
19
|
+
# Tynn.define { }
|
20
|
+
#
|
21
|
+
# app = Tynn::Test.new
|
22
|
+
# app.get("/", {}, "HTTP_HOST" => "tynn.xyz")
|
23
|
+
#
|
24
|
+
# app.res.headers["Location"]
|
25
|
+
# # => "https://tynn.xyz/"
|
26
|
+
#
|
27
|
+
# You can configure HSTS with <tt>{ hsts: { ... } }</tt>. It supports the
|
28
|
+
# following options:
|
29
|
+
#
|
30
|
+
# expires - The time, in seconds, that the browser access the site only
|
31
|
+
# by HTTPS. Defaults to 180 days.
|
32
|
+
# subdomains - If this is +true+, the rule applies to all the site's
|
33
|
+
# subdomains as well. Defaults to +true+.
|
34
|
+
# preload - A limitation of HSTS is that the initial request remains
|
35
|
+
# unprotected if it uses HTTP. The same applies to the first
|
36
|
+
# request after the activity period specified by +max-age+.
|
37
|
+
# Modern browsers implements a "STS preloaded list", which
|
38
|
+
# contains known sites supporting HSTS. If you would like to
|
39
|
+
# include your website into the list, set this options to +true+
|
40
|
+
# and submit your domain to this {form}[https://hstspreload.appspot.com/].
|
41
|
+
# Supported by Chrome, Firefox, IE11+ and IE Edge.
|
42
|
+
#
|
43
|
+
# Examples
|
44
|
+
#
|
45
|
+
# Tynn.plugin(
|
46
|
+
# Tynn::SSL,
|
47
|
+
# hsts: {
|
48
|
+
# expires: 31_536_000,
|
49
|
+
# includeSubdomains: true,
|
50
|
+
# preload: true
|
51
|
+
# }
|
52
|
+
# )
|
53
|
+
#
|
54
|
+
# app = Tynn::Test.new
|
55
|
+
# app.get("/", {}, "HTTPS" => "on")
|
56
|
+
#
|
57
|
+
# app.res.headers["Strict-Transport-Security"]
|
58
|
+
# # => "max-age=31536000; includeSubdomains; preload"
|
59
|
+
#
|
60
|
+
# To disable HSTS, you will need to tell the browser to expire it
|
61
|
+
# immediately.
|
62
|
+
#
|
63
|
+
# Examples
|
64
|
+
#
|
65
|
+
# Tynn.plugin(Tynn::SSL, hsts: { expires: 0 })
|
66
|
+
#
|
67
|
+
class SSL
|
68
|
+
def self.setup(app, hsts: {}) # :nodoc:
|
69
|
+
app.use(self, hsts: hsts)
|
70
|
+
end
|
71
|
+
|
72
|
+
def initialize(app, hsts: {}) # :nodoc:
|
73
|
+
@app = app
|
74
|
+
@hsts_header = build_hsts_header(hsts)
|
75
|
+
end
|
76
|
+
|
77
|
+
def call(env) # :nodoc:
|
78
|
+
request = Rack::Request.new(env)
|
79
|
+
|
80
|
+
if request.ssl?
|
81
|
+
response = @app.call(env)
|
82
|
+
|
83
|
+
set_hsts_header!(response[1])
|
84
|
+
|
85
|
+
return response
|
86
|
+
else
|
87
|
+
return [301, redirect_headers(request), []]
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
private
|
92
|
+
|
93
|
+
def build_hsts_header(options)
|
94
|
+
header = sprintf("max-age=%i", options.fetch(:expires, 15_552_000))
|
95
|
+
header << "; includeSubdomains" if options.fetch(:subdomains, true)
|
96
|
+
header << "; preload" if options[:preload]
|
97
|
+
|
98
|
+
return header
|
99
|
+
end
|
100
|
+
|
101
|
+
def set_hsts_header!(headers)
|
102
|
+
headers["Strict-Transport-Security".freeze] ||= @hsts_header
|
103
|
+
end
|
104
|
+
|
105
|
+
def redirect_headers(request)
|
106
|
+
return { "Location" => https_location(request) }
|
107
|
+
end
|
108
|
+
|
109
|
+
HTTPS_LOCATION = "https://%s%s".freeze
|
110
|
+
|
111
|
+
def https_location(request)
|
112
|
+
return sprintf(HTTPS_LOCATION, request.host, request.fullpath)
|
113
|
+
end
|
114
|
+
end
|
115
|
+
end
|
data/lib/tynn/version.rb
CHANGED
data/test/ssl_test.rb
ADDED
@@ -0,0 +1,60 @@
|
|
1
|
+
require_relative "../lib/tynn/ssl"
|
2
|
+
|
3
|
+
setup do
|
4
|
+
Tynn::Test.new
|
5
|
+
end
|
6
|
+
|
7
|
+
test "redirects to https" do |app|
|
8
|
+
Tynn.plugin(Tynn::SSL)
|
9
|
+
|
10
|
+
Tynn.define do
|
11
|
+
end
|
12
|
+
|
13
|
+
app.get("/")
|
14
|
+
|
15
|
+
assert_equal 301, app.res.status
|
16
|
+
assert_equal "https://example.org/", app.res.location
|
17
|
+
end
|
18
|
+
|
19
|
+
test "https request" do |app|
|
20
|
+
Tynn.plugin(Tynn::SSL)
|
21
|
+
|
22
|
+
Tynn.define do
|
23
|
+
root do
|
24
|
+
res.write("secure")
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
app.get("/", {}, "HTTPS" => "on")
|
29
|
+
|
30
|
+
assert_equal 200, app.res.status
|
31
|
+
assert_equal "secure", app.res.body
|
32
|
+
end
|
33
|
+
|
34
|
+
test "hsts header" do |app|
|
35
|
+
Tynn.plugin(Tynn::SSL)
|
36
|
+
|
37
|
+
Tynn.define do
|
38
|
+
end
|
39
|
+
|
40
|
+
app = Tynn::Test.new
|
41
|
+
app.get("/", {}, "HTTPS" => "on")
|
42
|
+
|
43
|
+
header = app.res.headers["Strict-Transport-Security"]
|
44
|
+
|
45
|
+
assert_equal "max-age=15552000; includeSubdomains", header
|
46
|
+
end
|
47
|
+
|
48
|
+
test "hsts header options" do |app|
|
49
|
+
Tynn.plugin(Tynn::SSL, hsts: { expires: 1, subdomains: false, preload: true })
|
50
|
+
|
51
|
+
Tynn.define do
|
52
|
+
end
|
53
|
+
|
54
|
+
app = Tynn::Test.new
|
55
|
+
app.get("/", {}, "HTTPS" => "on")
|
56
|
+
|
57
|
+
header = app.res.headers["Strict-Transport-Security"]
|
58
|
+
|
59
|
+
assert_equal "max-age=1; preload", header
|
60
|
+
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tynn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.3.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francesco Rodríguez
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-10
|
11
|
+
date: 2015-11-10 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -106,11 +106,8 @@ files:
|
|
106
106
|
- lib/tynn.rb
|
107
107
|
- lib/tynn/all_methods.rb
|
108
108
|
- lib/tynn/environment.rb
|
109
|
-
- lib/tynn/force_ssl.rb
|
110
109
|
- lib/tynn/hmote.rb
|
111
|
-
- lib/tynn/hsts.rb
|
112
110
|
- lib/tynn/json.rb
|
113
|
-
- lib/tynn/matchers.rb
|
114
111
|
- lib/tynn/not_found.rb
|
115
112
|
- lib/tynn/protection.rb
|
116
113
|
- lib/tynn/render.rb
|
@@ -119,6 +116,7 @@ files:
|
|
119
116
|
- lib/tynn/secure_headers.rb
|
120
117
|
- lib/tynn/session.rb
|
121
118
|
- lib/tynn/settings.rb
|
119
|
+
- lib/tynn/ssl.rb
|
122
120
|
- lib/tynn/static.rb
|
123
121
|
- lib/tynn/test.rb
|
124
122
|
- lib/tynn/version.rb
|
@@ -126,18 +124,16 @@ files:
|
|
126
124
|
- test/core_test.rb
|
127
125
|
- test/default_headers_test.rb
|
128
126
|
- test/environment_test.rb
|
129
|
-
- test/force_ssl_test.rb
|
130
127
|
- test/helper.rb
|
131
128
|
- test/hmote_test.rb
|
132
|
-
- test/hsts_test.rb
|
133
129
|
- test/json_test.rb
|
134
|
-
- test/matchers_test.rb
|
135
130
|
- test/middleware_test.rb
|
136
131
|
- test/not_found_test.rb
|
137
132
|
- test/protection_test.rb
|
138
133
|
- test/render_test.rb
|
139
134
|
- test/secure_headers_test.rb
|
140
135
|
- test/session_test.rb
|
136
|
+
- test/ssl_test.rb
|
141
137
|
- test/static_test.rb
|
142
138
|
homepage: https://github.com/frodsan/tynn
|
143
139
|
licenses:
|
@@ -168,17 +164,15 @@ test_files:
|
|
168
164
|
- test/core_test.rb
|
169
165
|
- test/default_headers_test.rb
|
170
166
|
- test/environment_test.rb
|
171
|
-
- test/force_ssl_test.rb
|
172
167
|
- test/helper.rb
|
173
168
|
- test/hmote_test.rb
|
174
|
-
- test/hsts_test.rb
|
175
169
|
- test/json_test.rb
|
176
|
-
- test/matchers_test.rb
|
177
170
|
- test/middleware_test.rb
|
178
171
|
- test/not_found_test.rb
|
179
172
|
- test/protection_test.rb
|
180
173
|
- test/render_test.rb
|
181
174
|
- test/secure_headers_test.rb
|
182
175
|
- test/session_test.rb
|
176
|
+
- test/ssl_test.rb
|
183
177
|
- test/static_test.rb
|
184
178
|
has_rdoc:
|
data/lib/tynn/force_ssl.rb
DELETED
@@ -1,55 +0,0 @@
|
|
1
|
-
class Tynn
|
2
|
-
# Public: HTTP requests are permanently redirected to their HTTPS
|
3
|
-
# counterparts.
|
4
|
-
#
|
5
|
-
# Examples
|
6
|
-
#
|
7
|
-
# require "tynn"
|
8
|
-
# require "tynn/force_ssl"
|
9
|
-
# require "tynn/test"
|
10
|
-
#
|
11
|
-
# Tynn.plugin(Tynn::ForceSSL)
|
12
|
-
#
|
13
|
-
# Tynn.define { }
|
14
|
-
#
|
15
|
-
# app = Tynn::Test.new
|
16
|
-
# app.get("/", {}, "HTTP_HOST" => "tynn.xyz")
|
17
|
-
#
|
18
|
-
# app.res.headers["Location"]
|
19
|
-
# # => "https://tynn.xyz/"
|
20
|
-
#
|
21
|
-
module ForceSSL
|
22
|
-
# Internal: Sets the HTTPS redirect middleware.
|
23
|
-
def self.setup(app)
|
24
|
-
app.use(Tynn::ForceSSL::Middleware)
|
25
|
-
end
|
26
|
-
|
27
|
-
class Middleware # :nodoc:
|
28
|
-
def initialize(app)
|
29
|
-
@app = app
|
30
|
-
end
|
31
|
-
|
32
|
-
def call(env)
|
33
|
-
request = Rack::Request.new(env)
|
34
|
-
|
35
|
-
if request.ssl?
|
36
|
-
return @app.call(env)
|
37
|
-
else
|
38
|
-
return [301, redirect_headers(request), []]
|
39
|
-
end
|
40
|
-
end
|
41
|
-
|
42
|
-
private
|
43
|
-
|
44
|
-
def redirect_headers(request)
|
45
|
-
return { "Location" => https_location(request) }
|
46
|
-
end
|
47
|
-
|
48
|
-
HTTPS_LOCATION = "https://%s%s".freeze
|
49
|
-
|
50
|
-
def https_location(request)
|
51
|
-
return sprintf(HTTPS_LOCATION, request.host, request.fullpath)
|
52
|
-
end
|
53
|
-
end
|
54
|
-
end
|
55
|
-
end
|
data/lib/tynn/hsts.rb
DELETED
@@ -1,64 +0,0 @@
|
|
1
|
-
class Tynn
|
2
|
-
# Public: Sets the +Strict-Transport-Security+ header. This ensures the
|
3
|
-
# browser never visits the http version of a website. This reduces the
|
4
|
-
# impact of leaking session data through cookies and external links, and
|
5
|
-
# defends against Man-in-the-middle attacks.
|
6
|
-
#
|
7
|
-
# Examples
|
8
|
-
#
|
9
|
-
# require "tynn"
|
10
|
-
# require "tynn/hsts"
|
11
|
-
#
|
12
|
-
# Tynn.plugin(Tynn::HSTS)
|
13
|
-
#
|
14
|
-
# Tynn.define { }
|
15
|
-
#
|
16
|
-
# Tynn.call("PATH_INFO" => "/")[1]["Strict-Transport-Security"]
|
17
|
-
# # => "max-age=15552000; includeSubdomains"
|
18
|
-
#
|
19
|
-
# It supports the following options:
|
20
|
-
#
|
21
|
-
# expires - The time, in seconds, that the browser access the site only
|
22
|
-
# by HTTPS. Defaults to 180 days.
|
23
|
-
# subdomains - If this is +true+, the rule applies to all the site's
|
24
|
-
# subdomains as well. Defaults to +true+.
|
25
|
-
# preload - A limitation of HSTS is that the initial request remains
|
26
|
-
# unprotected if it uses HTTP. The same applies to the first
|
27
|
-
# request after the activity period specified by +max-age+.
|
28
|
-
# Modern browsers implements a "STS preloaded list", which
|
29
|
-
# contains known sites supporting HSTS. If you would like to
|
30
|
-
# include your website into the list, set this options to +true+
|
31
|
-
# and submit your domain to this {form}[https://hstspreload.appspot.com/].
|
32
|
-
# Supported by Chrome, Firefox, IE11+ and IE Edge.
|
33
|
-
#
|
34
|
-
# Examples
|
35
|
-
#
|
36
|
-
# Tynn.plugin(
|
37
|
-
# Tynn::HSTS,
|
38
|
-
# expires: 31_536_000,
|
39
|
-
# includeSubdomains: true,
|
40
|
-
# preload: true
|
41
|
-
# )
|
42
|
-
#
|
43
|
-
# Tynn.define { }
|
44
|
-
#
|
45
|
-
# Tynn.call("PATH_INFO" => "/")[1]["Strict-Transport-Security"]
|
46
|
-
# # => "max-age=31536000; includeSubdomains; preload"
|
47
|
-
#
|
48
|
-
# To disable HSTS, you will need to tell the browser to expire it immediately.
|
49
|
-
#
|
50
|
-
# Examples
|
51
|
-
#
|
52
|
-
# Tynn.plugin(Tynn::HSTS, expires: 0)
|
53
|
-
#
|
54
|
-
module HSTS
|
55
|
-
# Internal: Sets the HSTS header as a default header.
|
56
|
-
def self.setup(app, options = {})
|
57
|
-
header = sprintf("max-age=%i", options.fetch(:expires, 15_552_000))
|
58
|
-
header << "; includeSubdomains" if options.fetch(:subdomains, true)
|
59
|
-
header << "; preload" if options[:preload]
|
60
|
-
|
61
|
-
app.settings[:default_headers]["Strict-Transport-Security"] = header
|
62
|
-
end
|
63
|
-
end
|
64
|
-
end
|
data/lib/tynn/matchers.rb
DELETED
@@ -1,60 +0,0 @@
|
|
1
|
-
class Tynn
|
2
|
-
# Public: Adds extra matchers to Tynn.
|
3
|
-
#
|
4
|
-
# Examples
|
5
|
-
#
|
6
|
-
# require "tynn"
|
7
|
-
# require "tynn/matchers"
|
8
|
-
#
|
9
|
-
# Tynn.plugin(Tynn::Matchers)
|
10
|
-
#
|
11
|
-
module Matchers
|
12
|
-
module InstanceMethods
|
13
|
-
# Public: A catch-all matcher. Always executes the given block.
|
14
|
-
#
|
15
|
-
# Examples
|
16
|
-
#
|
17
|
-
# Tynn.define do
|
18
|
-
# authenticated? do
|
19
|
-
# # ...
|
20
|
-
# end
|
21
|
-
#
|
22
|
-
# default do # on true
|
23
|
-
# # ...
|
24
|
-
# end
|
25
|
-
# end
|
26
|
-
#
|
27
|
-
def default
|
28
|
-
yield
|
29
|
-
|
30
|
-
halt(res.finish)
|
31
|
-
end
|
32
|
-
|
33
|
-
# Public: Executes the given block if +key+ is present in +req.params+.
|
34
|
-
#
|
35
|
-
# key - Any object that responds to +to_s+.
|
36
|
-
#
|
37
|
-
# Examples
|
38
|
-
#
|
39
|
-
# Tynn.define do
|
40
|
-
# param(:user) do |params|
|
41
|
-
# user = User.create(params)
|
42
|
-
#
|
43
|
-
# # ...
|
44
|
-
# end
|
45
|
-
#
|
46
|
-
# default do
|
47
|
-
# res.write("missing [user] param")
|
48
|
-
# end
|
49
|
-
# end
|
50
|
-
#
|
51
|
-
def param(key)
|
52
|
-
if (v = req[key]) && !v.empty?
|
53
|
-
yield(v)
|
54
|
-
|
55
|
-
halt(res.finish)
|
56
|
-
end
|
57
|
-
end
|
58
|
-
end
|
59
|
-
end
|
60
|
-
end
|
data/test/force_ssl_test.rb
DELETED
@@ -1,32 +0,0 @@
|
|
1
|
-
require_relative "../lib/tynn/force_ssl"
|
2
|
-
|
3
|
-
setup do
|
4
|
-
Tynn::Test.new
|
5
|
-
end
|
6
|
-
|
7
|
-
test "redirects to https" do |app|
|
8
|
-
Tynn.plugin(Tynn::ForceSSL)
|
9
|
-
|
10
|
-
Tynn.define do
|
11
|
-
end
|
12
|
-
|
13
|
-
app.get("/")
|
14
|
-
|
15
|
-
assert_equal 301, app.res.status
|
16
|
-
assert_equal "https://example.org/", app.res.location
|
17
|
-
end
|
18
|
-
|
19
|
-
test "https request" do |app|
|
20
|
-
Tynn.plugin(Tynn::ForceSSL)
|
21
|
-
|
22
|
-
Tynn.define do
|
23
|
-
root do
|
24
|
-
res.write("secure")
|
25
|
-
end
|
26
|
-
end
|
27
|
-
|
28
|
-
app.get("/", {}, "HTTPS" => "on")
|
29
|
-
|
30
|
-
assert_equal 200, app.res.status
|
31
|
-
assert_equal "secure", app.res.body
|
32
|
-
end
|
data/test/hsts_test.rb
DELETED
@@ -1,29 +0,0 @@
|
|
1
|
-
require_relative "../lib/tynn/hsts"
|
2
|
-
|
3
|
-
test "hsts header" do |app|
|
4
|
-
Tynn.plugin(Tynn::HSTS)
|
5
|
-
|
6
|
-
Tynn.define do
|
7
|
-
end
|
8
|
-
|
9
|
-
app = Tynn::Test.new
|
10
|
-
app.get("/", {})
|
11
|
-
|
12
|
-
header = app.res.headers["Strict-Transport-Security"]
|
13
|
-
|
14
|
-
assert_equal "max-age=15552000; includeSubdomains", header
|
15
|
-
end
|
16
|
-
|
17
|
-
test "hsts header options" do |app|
|
18
|
-
Tynn.plugin(Tynn::HSTS, expires: 1, subdomains: false, preload: true)
|
19
|
-
|
20
|
-
Tynn.define do
|
21
|
-
end
|
22
|
-
|
23
|
-
app = Tynn::Test.new
|
24
|
-
app.get("/", {})
|
25
|
-
|
26
|
-
header = app.res.headers["Strict-Transport-Security"]
|
27
|
-
|
28
|
-
assert_equal "max-age=1; preload", header
|
29
|
-
end
|
data/test/matchers_test.rb
DELETED
@@ -1,40 +0,0 @@
|
|
1
|
-
require_relative "../lib/tynn/matchers"
|
2
|
-
|
3
|
-
setup do
|
4
|
-
Tynn.plugin(Tynn::Matchers)
|
5
|
-
|
6
|
-
Tynn::Test.new
|
7
|
-
end
|
8
|
-
|
9
|
-
test "default" do |app|
|
10
|
-
Tynn.define do
|
11
|
-
default do
|
12
|
-
res.write("foo")
|
13
|
-
end
|
14
|
-
end
|
15
|
-
|
16
|
-
app.get("/")
|
17
|
-
|
18
|
-
assert_equal 200, app.res.status
|
19
|
-
assert_equal "foo", app.res.body
|
20
|
-
end
|
21
|
-
|
22
|
-
test "param" do |app|
|
23
|
-
Tynn.define do
|
24
|
-
param(:foo) do |foo|
|
25
|
-
res.write(foo)
|
26
|
-
end
|
27
|
-
|
28
|
-
param("bar") do |bar|
|
29
|
-
res.write(bar)
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
app.get("/", foo: "foo")
|
34
|
-
|
35
|
-
assert_equal "foo", app.res.body
|
36
|
-
|
37
|
-
app.get("/", foo: "bar")
|
38
|
-
|
39
|
-
assert_equal "bar", app.res.body
|
40
|
-
end
|