tynn 0.0.3 → 0.0.4
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/.gems +4 -2
- data/LICENSE +1 -1
- data/README.md +6 -1
- data/docs/bin/build +38 -0
- data/docs/guides/security.md +1 -0
- data/docs/index.md +89 -0
- data/docs/layout.html +61 -0
- data/docs/public/.gitignore +1 -0
- data/docs/public/css/styles.css +111 -0
- data/docs/public/guides/.gitignore +2 -0
- data/docs/syro/syro.rb +112 -0
- data/examples/composition.ru +1 -3
- data/lib/tynn.rb +13 -13
- data/lib/tynn/not_found.rb +3 -5
- data/lib/tynn/options.rb +9 -0
- data/lib/tynn/secure_headers.rb +2 -5
- data/lib/tynn/version.rb +1 -1
- data/makefile +4 -1
- data/test/core_test.rb +16 -89
- data/test/options_test.rb +16 -0
- data/tynn.gemspec +3 -2
- metadata +30 -9
- data/.gitignore +0 -1
- data/lib/tynn/send_file.rb +0 -12
- data/test/send_file_test.rb +0 -31
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 4782dd0580d83defcbda873cd5cd6286e9471dff
|
4
|
+
data.tar.gz: 4084f3b30cec83e6147b1e2afdde38a381285fe2
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 99d8b65373259f09d6c340ea148c4da3f1c33c55bdd7686b4ac278a5ed609955bed273f31371842b6521e74580e29def9c6c155e26ab8cdda9da2702edba2d65
|
7
|
+
data.tar.gz: e6571863d347e2c749582fa4db18abdf79938727e47cc4b8f1d912b650c26a8464c690995385e6f4fe1a34dd1c22e2add4720c4f7ec248c7b7aeff9acdf085a2
|
data/.gems
CHANGED
data/LICENSE
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
The MIT License (MIT)
|
2
2
|
|
3
|
-
Copyright (c) 2015 Francesco Rodríguez
|
3
|
+
Copyright (c) 2015 Francesco Rodríguez and contributors
|
4
4
|
|
5
5
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
6
6
|
of this software and associated documentation files (the "Software"), to deal
|
data/README.md
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
tynn
|
1
|
+
tynn [](https://rubygems.org/gems/tynn)
|
2
2
|
====
|
3
3
|
|
4
4
|
Simple library to create [Rack][rack] applications.
|
@@ -45,6 +45,11 @@ Contributing
|
|
45
45
|
- Use `make test` to run the test suite.
|
46
46
|
- Create a pull request with your changes.
|
47
47
|
|
48
|
+
You can install the gems globally, but we recommend [gs][gs] (or
|
49
|
+
[gst][gst] if you're using chruby) to keep things isolated.
|
50
|
+
|
48
51
|
[cuba]: https://github.com/soveran/cuba
|
49
52
|
[rack]: https://github.com/rack/rack
|
50
53
|
[syro]: https://github.com/soveran/syro
|
54
|
+
[gs]: https://github.com/soveran/gs
|
55
|
+
[gst]: https://github.com/tonchis/gst
|
data/docs/bin/build
ADDED
@@ -0,0 +1,38 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "redcarpet"
|
4
|
+
|
5
|
+
LAYOUT = File.read("./docs/layout.html")
|
6
|
+
|
7
|
+
def markdown(text)
|
8
|
+
options = {
|
9
|
+
autolink: true,
|
10
|
+
fenced_code_blocks: true,
|
11
|
+
tables: true
|
12
|
+
}
|
13
|
+
|
14
|
+
renderer = Redcarpet::Render::HTML.new
|
15
|
+
markdown = Redcarpet::Markdown.new(renderer, options)
|
16
|
+
|
17
|
+
return markdown.render(text)
|
18
|
+
end
|
19
|
+
|
20
|
+
def title(content)
|
21
|
+
return content.match(/<h1>(.*)<\/h1>/)[1]
|
22
|
+
end
|
23
|
+
|
24
|
+
def render(content)
|
25
|
+
markdown = markdown(content)
|
26
|
+
title = title(markdown)
|
27
|
+
|
28
|
+
return sprintf(LAYOUT, content: markdown, title: title)
|
29
|
+
end
|
30
|
+
|
31
|
+
Dir["./docs/**/*.md"].each do |file|
|
32
|
+
_, name = file.split("./docs")
|
33
|
+
|
34
|
+
name = name.sub(".md", ".html")
|
35
|
+
output = File.join("./docs/public", name)
|
36
|
+
|
37
|
+
File.write(output, render(File.read(file)))
|
38
|
+
end
|
@@ -0,0 +1 @@
|
|
1
|
+
# Security
|
data/docs/index.md
ADDED
@@ -0,0 +1,89 @@
|
|
1
|
+
# Getting Started
|
2
|
+
|
3
|
+
## Subtitle
|
4
|
+
|
5
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
6
|
+
Donec magna sapien, dignissim at tellus lobortis, finibus
|
7
|
+
pulvinar nulla. Nulla non ante ut mauris accumsan
|
8
|
+
vulputate at sed tortor. Integer dignissim massa at elit
|
9
|
+
pretium dapibus. Duis pretium erat dolor, vel luctus quam
|
10
|
+
pretium eget. Fusce imperdiet est in quam semper, ac
|
11
|
+
hendrerit risus hendrerit. Praesent convallis, risus
|
12
|
+
tempor lacinia posuere, quam diam porttitor magna, eget
|
13
|
+
pharetra turpis dui id est. Suspendisse pharetra mauris
|
14
|
+
nulla, eget sagittis risus cursus eget. Donec efficitur
|
15
|
+
odio non risus luctus, nec posuere nulla fermentum.
|
16
|
+
|
17
|
+
## Subtitle
|
18
|
+
|
19
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
20
|
+
Donec magna sapien, dignissim at tellus lobortis, finibus
|
21
|
+
pulvinar nulla. Nulla non ante ut mauris accumsan
|
22
|
+
vulputate at sed tortor. Integer dignissim massa at elit
|
23
|
+
pretium dapibus. Duis pretium erat dolor, vel luctus quam
|
24
|
+
pretium eget. Fusce imperdiet est in quam semper, ac
|
25
|
+
hendrerit risus hendrerit. Praesent convallis, risus
|
26
|
+
tempor lacinia posuere, quam diam porttitor magna, eget
|
27
|
+
pharetra turpis dui id est. Suspendisse pharetra mauris
|
28
|
+
nulla, eget sagittis risus cursus eget. Donec efficitur
|
29
|
+
odio non risus luctus, nec posuere nulla fermentum.
|
30
|
+
|
31
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
32
|
+
Donec magna sapien, dignissim at tellus lobortis, finibus
|
33
|
+
pulvinar nulla. Nulla non ante ut mauris accumsan
|
34
|
+
vulputate at sed tortor. Integer dignissim massa at elit
|
35
|
+
pretium dapibus. Duis pretium erat dolor, vel luctus quam
|
36
|
+
pretium eget. Fusce imperdiet est in quam semper, ac
|
37
|
+
hendrerit risus hendrerit. Praesent convallis, risus
|
38
|
+
tempor lacinia posuere, quam diam porttitor magna, eget
|
39
|
+
pharetra turpis dui id est. Suspendisse pharetra mauris
|
40
|
+
nulla, eget sagittis risus cursus eget. Donec efficitur
|
41
|
+
odio non risus luctus, nec posuere nulla fermentum.
|
42
|
+
|
43
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
44
|
+
Donec magna sapien, dignissim at tellus lobortis, finibus
|
45
|
+
pulvinar nulla. Nulla non ante ut mauris accumsan
|
46
|
+
vulputate at sed tortor. Integer dignissim massa at elit
|
47
|
+
pretium dapibus. Duis pretium erat dolor, vel luctus quam
|
48
|
+
pretium eget. Fusce imperdiet est in quam semper, ac
|
49
|
+
hendrerit risus hendrerit. Praesent convallis, risus
|
50
|
+
tempor lacinia posuere, quam diam porttitor magna, eget
|
51
|
+
pharetra turpis dui id est. Suspendisse pharetra mauris
|
52
|
+
nulla, eget sagittis risus cursus eget. Donec efficitur
|
53
|
+
odio non risus luctus, nec posuere nulla fermentum.
|
54
|
+
|
55
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
56
|
+
Donec magna sapien, dignissim at tellus lobortis, finibus
|
57
|
+
pulvinar nulla. Nulla non ante ut mauris accumsan
|
58
|
+
vulputate at sed tortor. Integer dignissim massa at elit
|
59
|
+
pretium dapibus. Duis pretium erat dolor, vel luctus quam
|
60
|
+
pretium eget. Fusce imperdiet est in quam semper, ac
|
61
|
+
hendrerit risus hendrerit. Praesent convallis, risus
|
62
|
+
tempor lacinia posuere, quam diam porttitor magna, eget
|
63
|
+
pharetra turpis dui id est. Suspendisse pharetra mauris
|
64
|
+
nulla, eget sagittis risus cursus eget. Donec efficitur
|
65
|
+
odio non risus luctus, nec posuere nulla fermentum.
|
66
|
+
|
67
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
68
|
+
Donec magna sapien, dignissim at tellus lobortis, finibus
|
69
|
+
pulvinar nulla. Nulla non ante ut mauris accumsan
|
70
|
+
vulputate at sed tortor. Integer dignissim massa at elit
|
71
|
+
pretium dapibus. Duis pretium erat dolor, vel luctus quam
|
72
|
+
pretium eget. Fusce imperdiet est in quam semper, ac
|
73
|
+
hendrerit risus hendrerit. Praesent convallis, risus
|
74
|
+
tempor lacinia posuere, quam diam porttitor magna, eget
|
75
|
+
pharetra turpis dui id est. Suspendisse pharetra mauris
|
76
|
+
nulla, eget sagittis risus cursus eget. Donec efficitur
|
77
|
+
odio non risus luctus, nec posuere nulla fermentum.
|
78
|
+
|
79
|
+
Lorem ipsum dolor sit amet, consectetur adipiscing elit.
|
80
|
+
Donec magna sapien, dignissim at tellus lobortis, finibus
|
81
|
+
pulvinar nulla. Nulla non ante ut mauris accumsan
|
82
|
+
vulputate at sed tortor. Integer dignissim massa at elit
|
83
|
+
pretium dapibus. Duis pretium erat dolor, vel luctus quam
|
84
|
+
pretium eget. Fusce imperdiet est in quam semper, ac
|
85
|
+
hendrerit risus hendrerit. Praesent convallis, risus
|
86
|
+
tempor lacinia posuere, quam diam porttitor magna, eget
|
87
|
+
pharetra turpis dui id est. Suspendisse pharetra mauris
|
88
|
+
nulla, eget sagittis risus cursus eget. Donec efficitur
|
89
|
+
odio non risus luctus, nec posuere nulla fermentum.
|
data/docs/layout.html
ADDED
@@ -0,0 +1,61 @@
|
|
1
|
+
<!DOCTYPE html>
|
2
|
+
<html lang="en">
|
3
|
+
<head>
|
4
|
+
<meta charset="UTF-8" />
|
5
|
+
<title>tynn | %{title}</title>
|
6
|
+
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7
|
+
<link href="/css/styles.css" rel="stylesheet" media="screen">
|
8
|
+
<link href="//netdna.bootstrapcdn.com/font-awesome/4.0.3/css/font-awesome.css" rel="stylesheet">
|
9
|
+
<link href="//fonts.googleapis.com/css?family=Roboto:400,500" rel="stylesheet">
|
10
|
+
</head>
|
11
|
+
<body>
|
12
|
+
<div class="container">
|
13
|
+
<header>
|
14
|
+
<div class="wrap">
|
15
|
+
<a class="nav-home" href="/">TYNN</a>
|
16
|
+
<a class="nav-github" href="https://github.com/frodsan/tynn">
|
17
|
+
<i class="fa fa-github"></i>
|
18
|
+
</a>
|
19
|
+
</div>
|
20
|
+
</header>
|
21
|
+
|
22
|
+
<section class="content wrap">
|
23
|
+
<div class="nav-docs">
|
24
|
+
<div class="nav-docs-section">
|
25
|
+
<h3>QUICK START</h3>
|
26
|
+
<ul>
|
27
|
+
<li><a href="#">Getting Started</a></li>
|
28
|
+
<li><a href="#">Tutorial</a></li>
|
29
|
+
</ul>
|
30
|
+
</div>
|
31
|
+
<div class="nav-docs-section">
|
32
|
+
<h3>Guides</h3>
|
33
|
+
<ul>
|
34
|
+
<li><a href="#">Link To Something</a></li>
|
35
|
+
<li><a href="#">Link to Something</a>
|
36
|
+
<ul>
|
37
|
+
<li><a href="#">Sublink</a></li>
|
38
|
+
<li><a href="#">Sublink</a></li>
|
39
|
+
</ul>
|
40
|
+
</li>
|
41
|
+
<li><a href="#">Link to Something</a></li>
|
42
|
+
<li><a href="#">Link to Something</a></li>
|
43
|
+
</ul>
|
44
|
+
</div>
|
45
|
+
<div class="nav-docs-section">
|
46
|
+
<h3>Community</h3>
|
47
|
+
<ul>
|
48
|
+
<li><a href="#">Slack</a></li>
|
49
|
+
<li><a href="#">Link to Something</a></li>
|
50
|
+
<li><a href="#">Link to Something</a></li>
|
51
|
+
</ul>
|
52
|
+
</div>
|
53
|
+
</div>
|
54
|
+
|
55
|
+
<div class="inner-content">
|
56
|
+
%{content}
|
57
|
+
</div>
|
58
|
+
</section>
|
59
|
+
</div>
|
60
|
+
</body>
|
61
|
+
</html>
|
@@ -0,0 +1 @@
|
|
1
|
+
*.html
|
@@ -0,0 +1,111 @@
|
|
1
|
+
html {
|
2
|
+
font-family: "Roboto";
|
3
|
+
}
|
4
|
+
|
5
|
+
body {
|
6
|
+
color: rgba(0, 0, 0, 0.87);
|
7
|
+
font-size: 16px;
|
8
|
+
font-weight: 400;
|
9
|
+
margin: 0;
|
10
|
+
padding: 0;
|
11
|
+
}
|
12
|
+
|
13
|
+
.container {
|
14
|
+
padding-top: 64px;
|
15
|
+
min-width: 960px;
|
16
|
+
}
|
17
|
+
|
18
|
+
header {
|
19
|
+
background: #2196F3;
|
20
|
+
box-shadow: 0 0 5px rgba(0, 0, 0, 0.5);
|
21
|
+
height: 64px;
|
22
|
+
position: fixed;
|
23
|
+
top: 0;
|
24
|
+
width: 100%;
|
25
|
+
text-align: right;
|
26
|
+
}
|
27
|
+
|
28
|
+
h1 {
|
29
|
+
color: rgba(0, 0, 0, 0.54);
|
30
|
+
font-size: 34px;
|
31
|
+
font-weight: 400;
|
32
|
+
}
|
33
|
+
|
34
|
+
h2 {
|
35
|
+
font-size: 24px;
|
36
|
+
font-weight: 400;
|
37
|
+
}
|
38
|
+
|
39
|
+
h3 {
|
40
|
+
font-size: 16px;
|
41
|
+
font-weight: 500;
|
42
|
+
}
|
43
|
+
|
44
|
+
.wrap {
|
45
|
+
width: 960px;
|
46
|
+
margin-left: auto;
|
47
|
+
margin-right: auto;
|
48
|
+
padding-left: 20px;
|
49
|
+
padding-right: 20px;
|
50
|
+
}
|
51
|
+
|
52
|
+
header a {
|
53
|
+
color: white;
|
54
|
+
line-height: 64px;
|
55
|
+
text-decoration: none;
|
56
|
+
}
|
57
|
+
|
58
|
+
.nav-home {
|
59
|
+
float: left;
|
60
|
+
font-size: 24px;
|
61
|
+
letter-spacing: 2px;
|
62
|
+
}
|
63
|
+
|
64
|
+
.nav-github {
|
65
|
+
font-size: 32px;
|
66
|
+
}
|
67
|
+
|
68
|
+
.content {
|
69
|
+
padding-top: 20px;
|
70
|
+
}
|
71
|
+
|
72
|
+
.nav-docs {
|
73
|
+
float: left;
|
74
|
+
width: 21.875%;
|
75
|
+
}
|
76
|
+
|
77
|
+
.nav-docs-section {
|
78
|
+
border-top: 1px solid rgba(0, 0, 0, 0.12);
|
79
|
+
padding: 12px 0;
|
80
|
+
}
|
81
|
+
|
82
|
+
.nav-docs-section:first-child {
|
83
|
+
padding-top: 0;
|
84
|
+
border-top: 0;
|
85
|
+
}
|
86
|
+
|
87
|
+
.nav-docs ul {
|
88
|
+
list-style: none;
|
89
|
+
padding: 0;
|
90
|
+
}
|
91
|
+
|
92
|
+
.nav-docs ul a {
|
93
|
+
color: rgba(0, 0, 0, 0.87);
|
94
|
+
font-size: 14px;
|
95
|
+
line-height: 24px;
|
96
|
+
text-decoration: none;
|
97
|
+
}
|
98
|
+
|
99
|
+
.nav-docs ul a:hover {
|
100
|
+
color: #FF4081;
|
101
|
+
}
|
102
|
+
|
103
|
+
.nav-docs ul ul {
|
104
|
+
padding-left: 20px;
|
105
|
+
}
|
106
|
+
|
107
|
+
.inner-content {
|
108
|
+
float: right;
|
109
|
+
line-height: 24px;
|
110
|
+
width: 67.7083%;
|
111
|
+
}
|
data/docs/syro/syro.rb
ADDED
@@ -0,0 +1,112 @@
|
|
1
|
+
class Syro::Response
|
2
|
+
##
|
3
|
+
# :method: []
|
4
|
+
#
|
5
|
+
# Returns the response header corresponding to `key`.
|
6
|
+
#
|
7
|
+
# res["Content-Type"] # => "text/html"
|
8
|
+
# res["Content-Length"] # => "42"
|
9
|
+
|
10
|
+
##
|
11
|
+
# :method: []=
|
12
|
+
# :call-seq: []=(value)
|
13
|
+
#
|
14
|
+
# Sets the given `value` with the header corresponding to `key`.
|
15
|
+
#
|
16
|
+
# res["Content-Type"] = "application/json"
|
17
|
+
# res["Content-Type"] # => "application/json"
|
18
|
+
|
19
|
+
##
|
20
|
+
# :method: body
|
21
|
+
#
|
22
|
+
# Returns the body of the response.
|
23
|
+
#
|
24
|
+
# res.body
|
25
|
+
# # => []
|
26
|
+
#
|
27
|
+
# res.write("there is")
|
28
|
+
# res.write("no try")
|
29
|
+
#
|
30
|
+
# res.body
|
31
|
+
# # => ["there is", "no try"]
|
32
|
+
|
33
|
+
##
|
34
|
+
# :method: finish
|
35
|
+
#
|
36
|
+
# Returns an array with three elements: the status, headers and body.
|
37
|
+
# If the status is not set, the status is set to 404 if empty body,
|
38
|
+
# otherwise the status is set to 200 and updates the `Content-Type`
|
39
|
+
# header to `text/html`.
|
40
|
+
#
|
41
|
+
# res.status = 200
|
42
|
+
# res.finish
|
43
|
+
# # => [200, {}, []]
|
44
|
+
#
|
45
|
+
# res.status = nil
|
46
|
+
# res.finish
|
47
|
+
# # => [404, {}, []]
|
48
|
+
#
|
49
|
+
# res.status = nil
|
50
|
+
# res.write("yo!")
|
51
|
+
# res.finish
|
52
|
+
# # => [200, { "Content-Type" => "text/html" }, ["yo!"]]
|
53
|
+
|
54
|
+
##
|
55
|
+
# :method: headers
|
56
|
+
#
|
57
|
+
# Returns a hash with the response headers.
|
58
|
+
#
|
59
|
+
# res.headers
|
60
|
+
# # => { "Content-Type" => "text/html", "Content-Length" => "42" }
|
61
|
+
|
62
|
+
##
|
63
|
+
# :method: redirect
|
64
|
+
# :call-seq: redirect(path, 302)
|
65
|
+
#
|
66
|
+
# Sets the `Location` header to `path` and updates the status to
|
67
|
+
# `status`. By default, `status` is `302`.
|
68
|
+
#
|
69
|
+
# res.redirect("/path")
|
70
|
+
#
|
71
|
+
# res["Location"] # => "/path"
|
72
|
+
# res.status # => 302
|
73
|
+
#
|
74
|
+
# res.redirect("http://tynn.ru", 303)
|
75
|
+
#
|
76
|
+
# res["Location"] # => "http://tynn.ru"
|
77
|
+
# res.status # => 303
|
78
|
+
|
79
|
+
##
|
80
|
+
# :method: status
|
81
|
+
#
|
82
|
+
# Returns the status of the response.
|
83
|
+
#
|
84
|
+
# res.status # => 200
|
85
|
+
#
|
86
|
+
|
87
|
+
##
|
88
|
+
# :method: status=
|
89
|
+
# :call-seq: status=(status)
|
90
|
+
#
|
91
|
+
# Sets the status of the response.
|
92
|
+
#
|
93
|
+
# res.status = 200
|
94
|
+
#
|
95
|
+
|
96
|
+
##
|
97
|
+
# :method: write
|
98
|
+
# :call-seq: write(str)
|
99
|
+
#
|
100
|
+
# Appends `str` to `body` and updates the `Content-Length` header.
|
101
|
+
#
|
102
|
+
# res.body # => []
|
103
|
+
#
|
104
|
+
# res.write("foo")
|
105
|
+
# res.write("bar")
|
106
|
+
#
|
107
|
+
# res.body
|
108
|
+
# # => ["foo", "bar"]
|
109
|
+
#
|
110
|
+
# res["Content-Length"]
|
111
|
+
# # => 6
|
112
|
+
end
|
data/examples/composition.ru
CHANGED
data/lib/tynn.rb
CHANGED
@@ -9,19 +9,7 @@ class Tynn < Syro::Deck
|
|
9
9
|
end
|
10
10
|
|
11
11
|
def self.use(_middleware, *args, &block)
|
12
|
-
middleware <<
|
13
|
-
end
|
14
|
-
|
15
|
-
def self.helpers(helper, *args)
|
16
|
-
self.include(helper)
|
17
|
-
|
18
|
-
if defined?(helper::ClassMethods)
|
19
|
-
self.extend(helper::ClassMethods)
|
20
|
-
end
|
21
|
-
|
22
|
-
if helper.respond_to?(:setup)
|
23
|
-
helper.setup(self, *args)
|
24
|
-
end
|
12
|
+
middleware << proc { |app| _middleware.new(app, *args, &block) }
|
25
13
|
end
|
26
14
|
|
27
15
|
def self.call(env) # :nodoc:
|
@@ -46,6 +34,18 @@ class Tynn < Syro::Deck
|
|
46
34
|
@syro = nil
|
47
35
|
@middleware = []
|
48
36
|
end
|
37
|
+
|
38
|
+
def self.helpers(helper, *args, &block)
|
39
|
+
self.include(helper)
|
40
|
+
|
41
|
+
if defined?(helper::ClassMethods)
|
42
|
+
self.extend(helper::ClassMethods)
|
43
|
+
end
|
44
|
+
|
45
|
+
if helper.respond_to?(:setup)
|
46
|
+
helper.setup(self, *args, &block)
|
47
|
+
end
|
48
|
+
end
|
49
49
|
end
|
50
50
|
|
51
51
|
require_relative "tynn/version"
|
data/lib/tynn/not_found.rb
CHANGED
@@ -1,10 +1,8 @@
|
|
1
1
|
module Tynn::NotFound
|
2
|
-
def call(
|
3
|
-
result = super
|
2
|
+
def call(*) # :nodoc:
|
3
|
+
result = super
|
4
4
|
|
5
|
-
|
6
|
-
|
7
|
-
if status == 404 && body.empty?
|
5
|
+
if result[0] == 404 && result[2].empty?
|
8
6
|
not_found
|
9
7
|
|
10
8
|
return res.finish
|
data/lib/tynn/options.rb
ADDED
data/lib/tynn/secure_headers.rb
CHANGED
@@ -13,10 +13,7 @@ module Tynn::SecureHeaders
|
|
13
13
|
"X-XSS-Protection" => "1; mode=block"
|
14
14
|
} # :nodoc:
|
15
15
|
|
16
|
-
def
|
17
|
-
|
18
|
-
result[1].merge!(HEADERS)
|
19
|
-
|
20
|
-
return result
|
16
|
+
def default_headers
|
17
|
+
return super.merge(HEADERS)
|
21
18
|
end
|
22
19
|
end
|
data/lib/tynn/version.rb
CHANGED
data/makefile
CHANGED
data/test/core_test.rb
CHANGED
@@ -12,11 +12,24 @@ test "hello" do
|
|
12
12
|
assert_equal "hello", app.res.body
|
13
13
|
end
|
14
14
|
|
15
|
+
test "methods" do
|
16
|
+
[:get, :post, :put, :patch, :delete].each do |method|
|
17
|
+
Tynn.define do
|
18
|
+
send(method) { res.write "" }
|
19
|
+
end
|
20
|
+
|
21
|
+
app = Tynn::Test.new
|
22
|
+
app.send(method, "/")
|
23
|
+
|
24
|
+
assert_equal 200, app.res.status
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
15
28
|
test "captures" do
|
16
29
|
Tynn.define do
|
17
|
-
on :foo do
|
18
|
-
on :bar do
|
19
|
-
res.write(sprintf("%s:%s",
|
30
|
+
on :foo do |foo|
|
31
|
+
on :bar do |bar|
|
32
|
+
res.write(sprintf("%s:%s", foo, bar))
|
20
33
|
end
|
21
34
|
end
|
22
35
|
end
|
@@ -51,21 +64,6 @@ test "composition" do
|
|
51
64
|
assert_equal "42", app.res.body
|
52
65
|
end
|
53
66
|
|
54
|
-
test "settings" do
|
55
|
-
Tynn.settings[:message] = "hello"
|
56
|
-
|
57
|
-
Tynn.define do
|
58
|
-
get do
|
59
|
-
res.write(settings[:message])
|
60
|
-
end
|
61
|
-
end
|
62
|
-
|
63
|
-
app = Tynn::Test.new
|
64
|
-
app.get("/")
|
65
|
-
|
66
|
-
assert_equal "hello", app.res.body
|
67
|
-
end
|
68
|
-
|
69
67
|
test "raise unless application handler is set" do
|
70
68
|
app = Tynn::Test.new
|
71
69
|
|
@@ -159,74 +157,3 @@ scope "middleware" do
|
|
159
157
|
assert_equal "21", app.res.body
|
160
158
|
end
|
161
159
|
end
|
162
|
-
|
163
|
-
scope "helpers" do
|
164
|
-
module Helper
|
165
|
-
def clean(str)
|
166
|
-
return str.strip
|
167
|
-
end
|
168
|
-
|
169
|
-
module Number
|
170
|
-
def self.setup(app, number)
|
171
|
-
app.settings[:number] = number
|
172
|
-
end
|
173
|
-
|
174
|
-
def number
|
175
|
-
return settings[:number]
|
176
|
-
end
|
177
|
-
end
|
178
|
-
|
179
|
-
def self.setup(app, number = 1)
|
180
|
-
app.helpers(Number, number)
|
181
|
-
end
|
182
|
-
|
183
|
-
module ClassMethods
|
184
|
-
def foo
|
185
|
-
"foo"
|
186
|
-
end
|
187
|
-
end
|
188
|
-
end
|
189
|
-
|
190
|
-
setup do
|
191
|
-
Tynn::Test.new
|
192
|
-
end
|
193
|
-
|
194
|
-
test "helpers" do |app|
|
195
|
-
Tynn.helpers(Helper)
|
196
|
-
|
197
|
-
Tynn.define do
|
198
|
-
get do
|
199
|
-
res.write(clean(" foo "))
|
200
|
-
end
|
201
|
-
end
|
202
|
-
|
203
|
-
app.get("/")
|
204
|
-
|
205
|
-
assert_equal "foo", app.res.body
|
206
|
-
assert_equal "foo", Tynn.foo
|
207
|
-
end
|
208
|
-
|
209
|
-
test "setup" do |app|
|
210
|
-
Tynn.helpers(Helper)
|
211
|
-
|
212
|
-
Tynn.define do
|
213
|
-
res.write(number)
|
214
|
-
end
|
215
|
-
|
216
|
-
app.get("/")
|
217
|
-
|
218
|
-
assert_equal "1", app.res.body
|
219
|
-
end
|
220
|
-
|
221
|
-
test "setup with arguments" do |app|
|
222
|
-
Tynn.helpers(Helper, 2)
|
223
|
-
|
224
|
-
Tynn.define do
|
225
|
-
res.write(number)
|
226
|
-
end
|
227
|
-
|
228
|
-
app.get("/")
|
229
|
-
|
230
|
-
assert_equal "2", app.res.body
|
231
|
-
end
|
232
|
-
end
|
data/tynn.gemspec
CHANGED
@@ -13,10 +13,11 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.files = `git ls-files`.split("\n")
|
14
14
|
|
15
15
|
s.add_dependency "rack", "~> 1.6"
|
16
|
-
s.add_dependency "seteable", "1.
|
17
|
-
s.add_dependency "syro", "~>
|
16
|
+
s.add_dependency "seteable", "1.1.0"
|
17
|
+
s.add_dependency "syro", "~> 1.0"
|
18
18
|
|
19
19
|
s.add_development_dependency "cutest", "1.2.2"
|
20
|
+
s.add_development_dependency "erubis", "~> 2.7"
|
20
21
|
s.add_development_dependency "hmote", "1.4.0"
|
21
22
|
s.add_development_dependency "rack-test", "0.6.3"
|
22
23
|
s.add_development_dependency "tilt", "~> 2.0"
|
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: 0.0.
|
4
|
+
version: 0.0.4
|
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-10-06 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: rack
|
@@ -30,28 +30,28 @@ dependencies:
|
|
30
30
|
requirements:
|
31
31
|
- - '='
|
32
32
|
- !ruby/object:Gem::Version
|
33
|
-
version: 1.
|
33
|
+
version: 1.1.0
|
34
34
|
type: :runtime
|
35
35
|
prerelease: false
|
36
36
|
version_requirements: !ruby/object:Gem::Requirement
|
37
37
|
requirements:
|
38
38
|
- - '='
|
39
39
|
- !ruby/object:Gem::Version
|
40
|
-
version: 1.
|
40
|
+
version: 1.1.0
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
42
|
name: syro
|
43
43
|
requirement: !ruby/object:Gem::Requirement
|
44
44
|
requirements:
|
45
45
|
- - "~>"
|
46
46
|
- !ruby/object:Gem::Version
|
47
|
-
version:
|
47
|
+
version: '1.0'
|
48
48
|
type: :runtime
|
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: '1.0'
|
55
55
|
- !ruby/object:Gem::Dependency
|
56
56
|
name: cutest
|
57
57
|
requirement: !ruby/object:Gem::Requirement
|
@@ -66,6 +66,20 @@ dependencies:
|
|
66
66
|
- - '='
|
67
67
|
- !ruby/object:Gem::Version
|
68
68
|
version: 1.2.2
|
69
|
+
- !ruby/object:Gem::Dependency
|
70
|
+
name: erubis
|
71
|
+
requirement: !ruby/object:Gem::Requirement
|
72
|
+
requirements:
|
73
|
+
- - "~>"
|
74
|
+
- !ruby/object:Gem::Version
|
75
|
+
version: '2.7'
|
76
|
+
type: :development
|
77
|
+
prerelease: false
|
78
|
+
version_requirements: !ruby/object:Gem::Requirement
|
79
|
+
requirements:
|
80
|
+
- - "~>"
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: '2.7'
|
69
83
|
- !ruby/object:Gem::Dependency
|
70
84
|
name: hmote
|
71
85
|
requirement: !ruby/object:Gem::Requirement
|
@@ -116,9 +130,16 @@ extensions: []
|
|
116
130
|
extra_rdoc_files: []
|
117
131
|
files:
|
118
132
|
- ".gems"
|
119
|
-
- ".gitignore"
|
120
133
|
- LICENSE
|
121
134
|
- README.md
|
135
|
+
- docs/bin/build
|
136
|
+
- docs/guides/security.md
|
137
|
+
- docs/index.md
|
138
|
+
- docs/layout.html
|
139
|
+
- docs/public/.gitignore
|
140
|
+
- docs/public/css/styles.css
|
141
|
+
- docs/public/guides/.gitignore
|
142
|
+
- docs/syro/syro.rb
|
122
143
|
- examples/composition.ru
|
123
144
|
- examples/hello.ru
|
124
145
|
- examples/protection.ru
|
@@ -134,10 +155,10 @@ files:
|
|
134
155
|
- lib/tynn/json_parser.rb
|
135
156
|
- lib/tynn/matchers.rb
|
136
157
|
- lib/tynn/not_found.rb
|
158
|
+
- lib/tynn/options.rb
|
137
159
|
- lib/tynn/protection.rb
|
138
160
|
- lib/tynn/render.rb
|
139
161
|
- lib/tynn/secure_headers.rb
|
140
|
-
- lib/tynn/send_file.rb
|
141
162
|
- lib/tynn/session.rb
|
142
163
|
- lib/tynn/ssl.rb
|
143
164
|
- lib/tynn/static.rb
|
@@ -154,10 +175,10 @@ files:
|
|
154
175
|
- test/json_test.rb
|
155
176
|
- test/matchers_test.rb
|
156
177
|
- test/not_found_test.rb
|
178
|
+
- test/options_test.rb
|
157
179
|
- test/protection_test.rb
|
158
180
|
- test/render_test.rb
|
159
181
|
- test/secure_headers_test.rb
|
160
|
-
- test/send_file_test.rb
|
161
182
|
- test/session_test.rb
|
162
183
|
- test/ssl_test.rb
|
163
184
|
- test/static_test.rb
|
data/.gitignore
DELETED
@@ -1 +0,0 @@
|
|
1
|
-
doc/
|
data/lib/tynn/send_file.rb
DELETED
data/test/send_file_test.rb
DELETED
@@ -1,31 +0,0 @@
|
|
1
|
-
require_relative "../lib/tynn/send_file"
|
2
|
-
|
3
|
-
test "file send" do
|
4
|
-
Tynn.helpers(Tynn::SendFile)
|
5
|
-
|
6
|
-
Tynn.define do
|
7
|
-
root do
|
8
|
-
send_file(__FILE__)
|
9
|
-
end
|
10
|
-
end
|
11
|
-
|
12
|
-
app = Tynn::Test.new
|
13
|
-
app.get("/")
|
14
|
-
|
15
|
-
assert_equal File.read(__FILE__), app.res.body
|
16
|
-
end
|
17
|
-
|
18
|
-
test "file not exists" do
|
19
|
-
Tynn.helpers(Tynn::SendFile)
|
20
|
-
|
21
|
-
Tynn.define do
|
22
|
-
root do
|
23
|
-
send_file("notexists")
|
24
|
-
end
|
25
|
-
end
|
26
|
-
|
27
|
-
app = Tynn::Test.new
|
28
|
-
app.get("/")
|
29
|
-
|
30
|
-
assert_equal 404, app.res.status
|
31
|
-
end
|