tynn 1.2.0 → 1.3.0
Sign up to get free protection for your applications and to get access to all the features.
- 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 [![Build Status](https://travis-ci.org/frodsan/tynn.svg)](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
|