tynn 2.0.0.beta2 → 2.0.0.beta3
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 +0 -5
- data/lib/tynn/render.rb +13 -5
- data/lib/tynn/response.rb +0 -74
- data/lib/tynn/session.rb +1 -1
- data/lib/tynn/version.rb +1 -1
- data/test/render_test.rb +2 -1
- data/test/response_test.rb +0 -94
- data/test/ssl_test.rb +9 -3
- metadata +18 -4
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 1f568dca09bcd12ce698740d952349f3fd5b8384
|
4
|
+
data.tar.gz: bf36f7702d0a0eb6c0684a67429cac3c98b8595c
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 5791a202646ee5e484d2606da3aa0fec2f9f9c547092fbe3df39e748997b966f3348ad4055654924988967c1af4c5e35f8f4ce07caa57c322595a694e0240b26
|
7
|
+
data.tar.gz: 4c983c263c8c4c0f87317cf3ceda25fbfe63a3cd3dbcb4250d9986d9dad3f52984e971d3ded76d5ef4b0b76fa148c2a6c1bb8020d0476c045ad4374afa3cb478
|
data/README.md
CHANGED
@@ -26,7 +26,6 @@ A thin library for web development in Ruby.
|
|
26
26
|
* [Setting HTTP Headers](#setting-http-headers)
|
27
27
|
* [Redirecting a Request](#redirecting-a-request)
|
28
28
|
* [Halting a Request](#halting-a-request)
|
29
|
-
* [Cookies](#cookies)
|
30
29
|
* [Extending Tynn](#extending-tynn)
|
31
30
|
* [Middleware](#middleware)
|
32
31
|
* [Plugins](#plugins)
|
@@ -301,10 +300,6 @@ end
|
|
301
300
|
# This won't be reached if current_user is nil
|
302
301
|
```
|
303
302
|
|
304
|
-
### Cookies
|
305
|
-
|
306
|
-
TODO.
|
307
|
-
|
308
303
|
## Extending Tynn
|
309
304
|
|
310
305
|
TODO.
|
data/lib/tynn/render.rb
CHANGED
@@ -1,12 +1,14 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "
|
3
|
+
require "tilt"
|
4
4
|
|
5
5
|
class Tynn
|
6
6
|
module Render
|
7
7
|
def self.setup(app, options = {}) # :nodoc:
|
8
8
|
app.set(:render, {
|
9
9
|
content_type: "text/html",
|
10
|
+
engine: "erb",
|
11
|
+
engine_opts: { escape_html: true },
|
10
12
|
layout: "layout",
|
11
13
|
root: Dir.pwd,
|
12
14
|
views: "views"
|
@@ -14,8 +16,6 @@ class Tynn
|
|
14
16
|
end
|
15
17
|
|
16
18
|
module InstanceMethods
|
17
|
-
include ::HMote::Helpers
|
18
|
-
|
19
19
|
# Renders <tt>template</tt> within the default layout. An optional hash of
|
20
20
|
# local variables can be passed to make available inside the template. It
|
21
21
|
# automatically sets the <tt>Content-Type</tt> header to <tt>"text/html"</tt>.
|
@@ -43,19 +43,27 @@ class Tynn
|
|
43
43
|
# res.write(partial("about", name: "John Doe"))
|
44
44
|
#
|
45
45
|
def partial(template, locals = {})
|
46
|
-
|
46
|
+
tilt(template_path(template), locals.merge(app: self), render_opts[:engine_opts])
|
47
47
|
end
|
48
48
|
|
49
49
|
private
|
50
50
|
|
51
51
|
def template_path(template)
|
52
|
-
File.join(views_path, "#{ template }
|
52
|
+
File.join(views_path, "#{ template }.#{ render_opts[:engine] }")
|
53
53
|
end
|
54
54
|
|
55
55
|
def views_path
|
56
56
|
File.expand_path(render_opts[:views], render_opts[:root])
|
57
57
|
end
|
58
58
|
|
59
|
+
def tilt(file, locals = {}, opts = {})
|
60
|
+
tilt_cache.fetch(file) { Tilt.new(file, 1, opts) }.render(self, locals)
|
61
|
+
end
|
62
|
+
|
63
|
+
def tilt_cache
|
64
|
+
Thread.current[:tilt_cache] ||= Tilt::Cache.new
|
65
|
+
end
|
66
|
+
|
59
67
|
def render_opts
|
60
68
|
self.class.settings[:render]
|
61
69
|
end
|
data/lib/tynn/response.rb
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
require "rack/utils"
|
4
|
-
|
5
3
|
class Tynn
|
6
4
|
# It provides convenience methods to construct a Rack response.
|
7
5
|
#
|
@@ -185,77 +183,5 @@ class Tynn
|
|
185
183
|
self.status = status
|
186
184
|
self.location = path
|
187
185
|
end
|
188
|
-
|
189
|
-
# Sets a cookie into the response. The following options are supported:
|
190
|
-
#
|
191
|
-
# [domain and path]
|
192
|
-
# Define the scope of the cookie. They tell the browser what website
|
193
|
-
# the cookie belongs to. If a cookie's domain and path are not specified,
|
194
|
-
# they default to the domain and path of the resource that was requested.
|
195
|
-
#
|
196
|
-
# [expires]
|
197
|
-
# Defines a specific date and time for when the browser should delete
|
198
|
-
# the cookie.
|
199
|
-
#
|
200
|
-
# [max_age]
|
201
|
-
# Sets the cookie’s expiration as an interval of seconds in the future,
|
202
|
-
# relative to the time the browser received the cookie.
|
203
|
-
#
|
204
|
-
# [httponly]
|
205
|
-
# If <tt>true</tt>, sets the <tt>HttpOnly</tt> flag. This mitigates the
|
206
|
-
# risk of client side scripting accessing the cookie.
|
207
|
-
#
|
208
|
-
# [secure]
|
209
|
-
# If <tt>true</tt>, sets the <tt>Secure</tt> flag. This tells the browser
|
210
|
-
# to only transmit the cookie over HTTPS.
|
211
|
-
#
|
212
|
-
# [same_site]
|
213
|
-
# Disables third-party usage for cookies. There are two possible values
|
214
|
-
# <tt>:Lax</tt> and <tt>:Strict</tt>. In <tt>Strict</tt> mode, the cookie
|
215
|
-
# is restrain to any cross-site usage; in <tt>Lax</tt> mode, some cross-site
|
216
|
-
# usage is allowed.
|
217
|
-
#
|
218
|
-
# <tt></tt>
|
219
|
-
#
|
220
|
-
# res.set_cookie("foo", "bar")
|
221
|
-
# res.headers["Set-Cookie"] # => "foo=bar"
|
222
|
-
#
|
223
|
-
# res.set_cookie("foo2", "bar2")
|
224
|
-
# res.headers["Set-Cookie"] # => "foo=bar\nfoo2=bar2"
|
225
|
-
#
|
226
|
-
# res.set_cookie("bar", "bar", {
|
227
|
-
# domain: ".example.com",
|
228
|
-
# path: "/",
|
229
|
-
# # max_age: 0,
|
230
|
-
# # expires: Time.now + 10_000,
|
231
|
-
# secure: true,
|
232
|
-
# httponly: true,
|
233
|
-
# same_site: :Lax
|
234
|
-
# })
|
235
|
-
#
|
236
|
-
# res.headers["Set-Cookie"].split("\n").last
|
237
|
-
# # => "bar=bar; domain=.example.com; path=/; secure; HttpOnly; SameSite=Lax"
|
238
|
-
#
|
239
|
-
# *NOTE.* This method doesn't sign and/or encrypt the value of the cookie.
|
240
|
-
#
|
241
|
-
def set_cookie(key, value, options = {})
|
242
|
-
Rack::Utils.set_cookie_header!(headers, key, options.merge(value: value))
|
243
|
-
end
|
244
|
-
|
245
|
-
# Deletes cookie by <tt>key</tt>.
|
246
|
-
#
|
247
|
-
# res.set_cookie("foo", "bar")
|
248
|
-
# res.headers["Set-Cookie"]
|
249
|
-
# # => "foo=bar"
|
250
|
-
#
|
251
|
-
# res.delete_cookie("foo")
|
252
|
-
# res.headers["Set-Cookie"]
|
253
|
-
# # => "foo=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
|
254
|
-
#
|
255
|
-
# Check #set_cookie for supported options.
|
256
|
-
#
|
257
|
-
def delete_cookie(key, options = {})
|
258
|
-
Rack::Utils.delete_cookie_header!(headers, key, options)
|
259
|
-
end
|
260
186
|
end
|
261
187
|
end
|
data/lib/tynn/session.rb
CHANGED
@@ -55,7 +55,7 @@ class Tynn
|
|
55
55
|
# is restrain to any cross-site usage; in <tt>Lax</tt> mode, some cross-site
|
56
56
|
# usage is allowed. Defaults to <tt>:Lax</tt>. If <tt>nil</tt> is passed,
|
57
57
|
# the flag is not included. Check this article[http://www.sjoerdlangkemper.nl/2016/04/14/preventing-csrf-with-samesite-cookie-attribute/]
|
58
|
-
# for more information.
|
58
|
+
# for more information. Supported by Chrome 51+.
|
59
59
|
#
|
60
60
|
# [expire_after]
|
61
61
|
# The lifespan of the cookie. If <tt>nil</tt>, the session cookie is temporary
|
data/lib/tynn/version.rb
CHANGED
data/test/render_test.rb
CHANGED
@@ -2,6 +2,7 @@
|
|
2
2
|
|
3
3
|
require_relative "helper"
|
4
4
|
require_relative "../lib/tynn/render"
|
5
|
+
require "tilt/erubis"
|
5
6
|
|
6
7
|
class RenderTest < Minitest::Test
|
7
8
|
def setup
|
@@ -72,7 +73,7 @@ class RenderTest < Minitest::Test
|
|
72
73
|
ts = Tynn::Test.new(@app)
|
73
74
|
ts.get("/escape")
|
74
75
|
|
75
|
-
assert_equal "<a><
|
76
|
+
assert_equal "<a></a>", ts.res.body.join.strip
|
76
77
|
end
|
77
78
|
|
78
79
|
def test_custom_layout
|
data/test/response_test.rb
CHANGED
@@ -120,98 +120,4 @@ class ResponseTest < Minitest::Test
|
|
120
120
|
|
121
121
|
assert_equal 303, res.status
|
122
122
|
end
|
123
|
-
|
124
|
-
def test_set_cookie
|
125
|
-
res = Tynn::Response.new
|
126
|
-
|
127
|
-
res.set_cookie("foo", "bar")
|
128
|
-
|
129
|
-
assert_equal "foo=bar", res.headers["Set-Cookie"]
|
130
|
-
end
|
131
|
-
|
132
|
-
def test_set_multiple_cookies
|
133
|
-
res = Tynn::Response.new
|
134
|
-
|
135
|
-
res.set_cookie("foo1", "bar1")
|
136
|
-
res.set_cookie("foo2", "bar2")
|
137
|
-
|
138
|
-
assert_equal "foo1=bar1\nfoo2=bar2", res.headers["Set-Cookie"]
|
139
|
-
end
|
140
|
-
|
141
|
-
def test_set_cookie_with_options
|
142
|
-
res = Tynn::Response.new
|
143
|
-
|
144
|
-
time = Time.new(2016)
|
145
|
-
|
146
|
-
res.set_cookie("foo", "bar", {
|
147
|
-
domain: "example.org",
|
148
|
-
path: "/path",
|
149
|
-
max_age: 100, # seconds
|
150
|
-
expires: time,
|
151
|
-
httponly: true,
|
152
|
-
secure: true,
|
153
|
-
same_site: :Lax
|
154
|
-
})
|
155
|
-
|
156
|
-
expected = %W(
|
157
|
-
foo=bar
|
158
|
-
domain=example.org
|
159
|
-
path=/path
|
160
|
-
max-age=100
|
161
|
-
expires=#{ time.gmtime.rfc2822 }
|
162
|
-
secure
|
163
|
-
HttpOnly
|
164
|
-
SameSite=Lax
|
165
|
-
).join("; ")
|
166
|
-
|
167
|
-
assert_equal expected, res.headers["Set-Cookie"]
|
168
|
-
end
|
169
|
-
|
170
|
-
def test_delete_cookie
|
171
|
-
res = Tynn::Response.new
|
172
|
-
|
173
|
-
res.set_cookie("foo1", "bar1")
|
174
|
-
res.set_cookie("foo2", "bar2")
|
175
|
-
|
176
|
-
res.delete_cookie("foo1")
|
177
|
-
|
178
|
-
expected = [
|
179
|
-
"foo2=bar2",
|
180
|
-
"foo1=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
|
181
|
-
].join("\n")
|
182
|
-
|
183
|
-
assert_equal expected, res.headers["Set-Cookie"]
|
184
|
-
end
|
185
|
-
|
186
|
-
def test_delete_cookie_with_multiple_domains
|
187
|
-
res = Tynn::Response.new
|
188
|
-
|
189
|
-
res.set_cookie("foo1", "bar1", domain: "foo1.example.org")
|
190
|
-
res.set_cookie("foo2", "bar2", domain: "foo2.example.org")
|
191
|
-
|
192
|
-
res.delete_cookie("foo1", domain: "foo1.example.org")
|
193
|
-
|
194
|
-
expected = [
|
195
|
-
"foo2=bar2; domain=foo2.example.org",
|
196
|
-
"foo1=; domain=foo1.example.org; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
|
197
|
-
].join("\n")
|
198
|
-
|
199
|
-
assert_equal expected, res.headers["Set-Cookie"]
|
200
|
-
end
|
201
|
-
|
202
|
-
def test_delete_cookie_with_same_domain_and_multiple_paths
|
203
|
-
res = Tynn::Response.new
|
204
|
-
|
205
|
-
res.set_cookie("foo1", "bar1", domain: "example.org", path: "/foo1")
|
206
|
-
res.set_cookie("foo2", "bar2", domain: "example.org", path: "/foo2")
|
207
|
-
|
208
|
-
res.delete_cookie("foo1", domain: "example.org", path: "/foo1")
|
209
|
-
|
210
|
-
expected = [
|
211
|
-
"foo2=bar2; domain=example.org; path=/foo2",
|
212
|
-
"foo1=; domain=example.org; path=/foo1; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 -0000"
|
213
|
-
].join("\n")
|
214
|
-
|
215
|
-
assert_equal expected, res.headers["Set-Cookie"]
|
216
|
-
end
|
217
123
|
end
|
data/test/ssl_test.rb
CHANGED
@@ -112,11 +112,17 @@ class SSLTest < Minitest::Test
|
|
112
112
|
def test_set_secure_flag
|
113
113
|
@app.plugin(Tynn::SSL, hsts: false)
|
114
114
|
|
115
|
+
@app.class_eval do
|
116
|
+
def set_cookie(key, value, opts)
|
117
|
+
Rack::Utils.set_cookie_header!(res.headers, key, opts.merge(value: value))
|
118
|
+
end
|
119
|
+
end
|
120
|
+
|
115
121
|
@app.define do
|
116
122
|
on get do
|
117
|
-
|
118
|
-
|
119
|
-
|
123
|
+
set_cookie("first", "cookie", secure: false)
|
124
|
+
set_cookie("other", "cookie", http_only: true)
|
125
|
+
set_cookie("secure", "cookie", secure: true)
|
120
126
|
end
|
121
127
|
end
|
122
128
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: tynn
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0.0.
|
4
|
+
version: 2.0.0.beta3
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francesco Rodriguez
|
@@ -39,19 +39,19 @@ dependencies:
|
|
39
39
|
- !ruby/object:Gem::Version
|
40
40
|
version: 1.x
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: erubis
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version: '
|
47
|
+
version: '2.7'
|
48
48
|
type: :development
|
49
49
|
prerelease: false
|
50
50
|
version_requirements: !ruby/object:Gem::Requirement
|
51
51
|
requirements:
|
52
52
|
- - "~>"
|
53
53
|
- !ruby/object:Gem::Version
|
54
|
-
version: '
|
54
|
+
version: '2.7'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: minitest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -80,6 +80,20 @@ dependencies:
|
|
80
80
|
- - "~>"
|
81
81
|
- !ruby/object:Gem::Version
|
82
82
|
version: '11.0'
|
83
|
+
- !ruby/object:Gem::Dependency
|
84
|
+
name: tilt
|
85
|
+
requirement: !ruby/object:Gem::Requirement
|
86
|
+
requirements:
|
87
|
+
- - "~>"
|
88
|
+
- !ruby/object:Gem::Version
|
89
|
+
version: '2.0'
|
90
|
+
type: :development
|
91
|
+
prerelease: false
|
92
|
+
version_requirements: !ruby/object:Gem::Requirement
|
93
|
+
requirements:
|
94
|
+
- - "~>"
|
95
|
+
- !ruby/object:Gem::Version
|
96
|
+
version: '2.0'
|
83
97
|
description: A thin library for web development in Ruby
|
84
98
|
email: hello@frodsan.com
|
85
99
|
executables: []
|