tzispa 0.6.1 → 0.7.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/CHANGELOG.md +12 -0
- data/lib/tzispa/api/handler.rb +54 -23
- data/lib/tzispa/app.rb +60 -68
- data/lib/tzispa/cli.rb +42 -3
- data/lib/tzispa/commands/api.rb +55 -0
- data/lib/tzispa/commands/app.rb +83 -0
- data/lib/tzispa/commands/cli/generate.rb +60 -0
- data/lib/tzispa/commands/command.rb +28 -0
- data/lib/tzispa/commands/console.rb +62 -0
- data/lib/tzispa/commands/helpers/i18n.rb +67 -0
- data/lib/tzispa/commands/helpers/project.rb +69 -0
- data/lib/tzispa/commands/helpers/repository.rb +46 -0
- data/lib/tzispa/commands/project.rb +104 -0
- data/lib/tzispa/commands/repository.rb +66 -0
- data/lib/tzispa/commands/rig.rb +28 -0
- data/lib/tzispa/commands/server.rb +26 -0
- data/lib/tzispa/config/{appconfig.rb → app_config.rb} +12 -32
- data/lib/tzispa/config/base.rb +7 -5
- data/lib/tzispa/config/db_config.rb +67 -0
- data/lib/tzispa/config/yaml.rb +9 -10
- data/lib/tzispa/context.rb +3 -2
- data/lib/tzispa/controller/api.rb +66 -60
- data/lib/tzispa/controller/auth_layout.rb +4 -28
- data/lib/tzispa/controller/base.rb +61 -24
- data/lib/tzispa/controller/exceptions.rb +3 -4
- data/lib/tzispa/controller/http_error.rb +0 -3
- data/lib/tzispa/controller/layout.rb +4 -4
- data/lib/tzispa/domain.rb +27 -23
- data/lib/tzispa/env.rb +34 -0
- data/lib/tzispa/environment.rb +231 -0
- data/lib/tzispa/http/context.rb +65 -80
- data/lib/tzispa/http/request.rb +29 -17
- data/lib/tzispa/http/response.rb +45 -12
- data/lib/tzispa/route_set.rb +100 -0
- data/lib/tzispa/server.rb +61 -0
- data/lib/tzispa/tzisparc.rb +80 -0
- data/lib/tzispa/version.rb +1 -1
- data/lib/tzispa.rb +3 -1
- data/tzispa.gemspec +12 -6
- metadata +68 -17
- data/lib/tzispa/command/api.rb +0 -24
- data/lib/tzispa/command/app.rb +0 -95
- data/lib/tzispa/command/cli/generate.rb +0 -51
- data/lib/tzispa/command/project.rb +0 -258
- data/lib/tzispa/command/rig.rb +0 -26
- data/lib/tzispa/controller/signed_api.rb +0 -13
- data/lib/tzispa/http/session_flash_bag.rb +0 -62
- data/lib/tzispa/middleware.rb +0 -48
- data/lib/tzispa/routes.rb +0 -69
@@ -0,0 +1,231 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
require 'thread'
|
4
|
+
require 'pathname'
|
5
|
+
require 'singleton'
|
6
|
+
require 'tzispa/env'
|
7
|
+
require 'tzispa/tzisparc'
|
8
|
+
require 'tzispa/utils/hash'
|
9
|
+
|
10
|
+
module Tzispa
|
11
|
+
|
12
|
+
class Environment
|
13
|
+
include Singleton
|
14
|
+
using Tzispa::Utils::TzHash
|
15
|
+
|
16
|
+
LOCK = Mutex.new
|
17
|
+
|
18
|
+
RACK_ENV = 'RACK_ENV'
|
19
|
+
|
20
|
+
TZISPA_ENV = 'TZISPA_ENV'
|
21
|
+
|
22
|
+
DEVELOPMENT_ENV = 'development'
|
23
|
+
|
24
|
+
DEFAULT_ENV = 'development'
|
25
|
+
|
26
|
+
PRODUCTION_ENV = 'deployment'
|
27
|
+
|
28
|
+
RACK_ENV_DEPLOYMENT = 'deployment'
|
29
|
+
|
30
|
+
DEFAULT_DOTENV_ENV = '.env.%s'
|
31
|
+
|
32
|
+
DEFAULT_CONFIG = 'config'
|
33
|
+
|
34
|
+
TZISPA_HOST = 'TZISPA_HOST'
|
35
|
+
|
36
|
+
TZISPA_SSL = 'TZISPA_SSL'
|
37
|
+
|
38
|
+
TZISPA_SERVER_HOST = 'TZISPA_SERVER_HOST'
|
39
|
+
|
40
|
+
DEFAULT_HOST = 'localhost'
|
41
|
+
|
42
|
+
TZISPA_PORT = 'TZISPA_PORT'
|
43
|
+
|
44
|
+
TZISPA_SERVER_PORT = 'TZISPA_SERVER_PORT'
|
45
|
+
|
46
|
+
DEFAULT_PORT = 9412
|
47
|
+
|
48
|
+
DEFAULT_RACKUP = 'tzispa.ru'
|
49
|
+
|
50
|
+
DEFAULT_ENVIRONMENT_CONFIG = 'environment'
|
51
|
+
|
52
|
+
DEFAULT_DOMAINS_PATH = 'apps'
|
53
|
+
|
54
|
+
DOMAINS = 'domains'
|
55
|
+
|
56
|
+
DOMAINS_PATH = 'apps/%s'
|
57
|
+
|
58
|
+
APPLICATION = 'application'
|
59
|
+
|
60
|
+
APPLICATION_PATH = 'app'
|
61
|
+
|
62
|
+
# rubocop:disable Style/ClassVars
|
63
|
+
@@opts = {}
|
64
|
+
|
65
|
+
def initialize
|
66
|
+
@env = Tzispa::Env.new(env: @@opts.delete(:env) || ENV)
|
67
|
+
@options = Tzispa::Tzisparc.new(root).options
|
68
|
+
@options.merge! @@opts.clone.symbolize!
|
69
|
+
LOCK.synchronize { set_env_vars! }
|
70
|
+
end
|
71
|
+
|
72
|
+
def self.opts=(hash)
|
73
|
+
@@opts = hash.to_h.dup
|
74
|
+
end
|
75
|
+
|
76
|
+
def self.[](key)
|
77
|
+
instance[key]
|
78
|
+
end
|
79
|
+
|
80
|
+
def self.development?
|
81
|
+
instance.development?
|
82
|
+
end
|
83
|
+
|
84
|
+
def [](key)
|
85
|
+
@env[key]
|
86
|
+
end
|
87
|
+
|
88
|
+
def environment
|
89
|
+
@environment ||= env[TZISPA_ENV] || rack_env || DEFAULT_ENV
|
90
|
+
end
|
91
|
+
|
92
|
+
def development?
|
93
|
+
environment == DEVELOPMENT_ENV
|
94
|
+
end
|
95
|
+
|
96
|
+
def code_reloading?
|
97
|
+
development?
|
98
|
+
end
|
99
|
+
|
100
|
+
def environment?(*names)
|
101
|
+
names.map(&:to_s).include?(environment)
|
102
|
+
end
|
103
|
+
|
104
|
+
def bundler_groups
|
105
|
+
[:default, environment.to_sym]
|
106
|
+
end
|
107
|
+
|
108
|
+
def project_name
|
109
|
+
@options.fetch(:project)
|
110
|
+
end
|
111
|
+
|
112
|
+
def architecture
|
113
|
+
@options.fetch(:architecture) do
|
114
|
+
puts "Tzispa architecture unknown: see `.tzisparc'"
|
115
|
+
exit 1
|
116
|
+
end
|
117
|
+
end
|
118
|
+
|
119
|
+
def root
|
120
|
+
@root ||= Pathname.new(Dir.pwd)
|
121
|
+
end
|
122
|
+
|
123
|
+
def apps_path
|
124
|
+
@options.fetch(:path) do
|
125
|
+
case architecture
|
126
|
+
when DOMAINS
|
127
|
+
DOMAINS_PATH
|
128
|
+
when APPLICATION
|
129
|
+
APPLICATION_PATH
|
130
|
+
end
|
131
|
+
end
|
132
|
+
end
|
133
|
+
|
134
|
+
def config
|
135
|
+
@config ||= root.join(@options.fetch(:config) { DEFAULT_CONFIG })
|
136
|
+
end
|
137
|
+
|
138
|
+
def host
|
139
|
+
@host ||= @options.fetch(:host) do
|
140
|
+
env[TZISPA_HOST] || DEFAULT_HOST
|
141
|
+
end
|
142
|
+
end
|
143
|
+
|
144
|
+
def server_host
|
145
|
+
@server_host ||= @options.fetch(:server_host) do
|
146
|
+
env[TZISPA_SERVER_HOST] || host
|
147
|
+
end
|
148
|
+
end
|
149
|
+
|
150
|
+
def port
|
151
|
+
@port ||= @options.fetch(:port) do
|
152
|
+
env[TZISPA_PORT] || DEFAULT_PORT
|
153
|
+
end.to_i
|
154
|
+
end
|
155
|
+
|
156
|
+
def server_port
|
157
|
+
@server_port ||= @options.fetch(:server_port) do
|
158
|
+
env[TZISPA_SERVER_PORT] || port
|
159
|
+
end.to_i
|
160
|
+
end
|
161
|
+
|
162
|
+
def uri_port
|
163
|
+
if ssl?
|
164
|
+
":#{port}" unless port == 443
|
165
|
+
else
|
166
|
+
":#{port}" unless port == 80
|
167
|
+
end
|
168
|
+
end
|
169
|
+
|
170
|
+
def domains_path
|
171
|
+
@domains_path ||= @options.fetch(:domains_path) do
|
172
|
+
env[DOMAINS_PATH] || DEFAULT_DOMAINS_PATH
|
173
|
+
end
|
174
|
+
end
|
175
|
+
|
176
|
+
def default_port?
|
177
|
+
port == DEFAULT_PORT
|
178
|
+
end
|
179
|
+
|
180
|
+
def ssl?
|
181
|
+
env[TZISPA_SSL] == 'yes'
|
182
|
+
end
|
183
|
+
|
184
|
+
def rackup
|
185
|
+
root.join(@options.fetch(:rackup) { DEFAULT_RACKUP })
|
186
|
+
end
|
187
|
+
|
188
|
+
def daemonize?
|
189
|
+
@options.key?(:daemonize) && @options.fetch(:daemonize)
|
190
|
+
end
|
191
|
+
|
192
|
+
def to_options
|
193
|
+
@options.to_h.merge(
|
194
|
+
environment: environment,
|
195
|
+
apps_path: apps_path,
|
196
|
+
rackup: rackup,
|
197
|
+
host: server_host,
|
198
|
+
port: server_port
|
199
|
+
)
|
200
|
+
end
|
201
|
+
|
202
|
+
private
|
203
|
+
|
204
|
+
attr_reader :env
|
205
|
+
|
206
|
+
def set_env_vars!
|
207
|
+
set_application_env_vars!
|
208
|
+
set_tzispa_env_vars!
|
209
|
+
end
|
210
|
+
|
211
|
+
def set_tzispa_env_vars!
|
212
|
+
env[TZISPA_ENV] = env[RACK_ENV] = environment
|
213
|
+
env[TZISPA_HOST] = host
|
214
|
+
env[TZISPA_PORT] = port.to_s
|
215
|
+
end
|
216
|
+
|
217
|
+
def set_application_env_vars!
|
218
|
+
dotenv = root.join(DEFAULT_DOTENV_ENV % environment)
|
219
|
+
env.load!(dotenv) if dotenv.exist?
|
220
|
+
end
|
221
|
+
|
222
|
+
def rack_env
|
223
|
+
case env[RACK_ENV]
|
224
|
+
when RACK_ENV_DEPLOYMENT
|
225
|
+
PRODUCTION_ENV
|
226
|
+
else
|
227
|
+
env[RACK_ENV]
|
228
|
+
end
|
229
|
+
end
|
230
|
+
end
|
231
|
+
end
|
data/lib/tzispa/http/context.rb
CHANGED
@@ -1,10 +1,11 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
1
3
|
require 'forwardable'
|
2
|
-
require 'securerandom'
|
3
4
|
require 'tzispa/context'
|
4
5
|
require 'tzispa/http/response'
|
5
6
|
require 'tzispa/http/request'
|
6
|
-
require 'tzispa/http/session_flash_bag'
|
7
7
|
require 'tzispa/helpers/response'
|
8
|
+
require 'tzispa/helpers/session'
|
8
9
|
require 'tzispa/helpers/security'
|
9
10
|
|
10
11
|
module Tzispa
|
@@ -15,118 +16,111 @@ module Tzispa
|
|
15
16
|
|
16
17
|
include Tzispa::Helpers::Response
|
17
18
|
include Tzispa::Helpers::Security
|
19
|
+
include Tzispa::Helpers::Session
|
18
20
|
|
19
21
|
attr_reader :request, :response
|
20
22
|
def_delegators :@request, :session
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
24
|
+
def initialize(app, env)
|
25
|
+
super(app, env)
|
26
|
+
@request = Request.new(env)
|
27
|
+
@response = Response.new
|
28
|
+
init_session
|
29
|
+
end
|
27
30
|
|
28
|
-
def
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
31
|
+
def request_method
|
32
|
+
if request.request_method == 'POST' && request['_method']
|
33
|
+
env[Request::REQUEST_METHOD] = request['_method']
|
34
|
+
request['_method']
|
35
|
+
else
|
36
|
+
request.request_method
|
37
|
+
end
|
33
38
|
end
|
34
39
|
|
35
40
|
def router_params
|
36
|
-
env['router.params'] ||
|
41
|
+
env['router.params'] || {}
|
37
42
|
end
|
38
43
|
|
39
44
|
def layout
|
40
45
|
router_params&.fetch(:layout, nil)
|
41
46
|
end
|
42
47
|
|
43
|
-
def
|
44
|
-
|
45
|
-
end
|
46
|
-
|
47
|
-
def last_access
|
48
|
-
session[SESSION_LAST_ACCESS]
|
49
|
-
end
|
50
|
-
|
51
|
-
def flash
|
52
|
-
@flash ||= SessionFlashBag.new(session, GLOBAL_MESSAGE_FLASH)
|
53
|
-
end
|
54
|
-
|
55
|
-
def session?
|
56
|
-
(not session[SESSION_ID].nil?) and (session[SESSION_ID] == session.id)
|
57
|
-
end
|
58
|
-
|
59
|
-
def logged?
|
60
|
-
session? and (not session[SESSION_AUTH_USER].nil?)
|
61
|
-
end
|
62
|
-
|
63
|
-
def login=(user)
|
64
|
-
session[SESSION_AUTH_USER] = user unless user.nil?
|
65
|
-
end
|
66
|
-
|
67
|
-
def login
|
68
|
-
session[SESSION_AUTH_USER]
|
48
|
+
def login_redirect
|
49
|
+
redirect(layout_path(config.login_layout.to_sym), true, response) if login_redirect?
|
69
50
|
end
|
70
51
|
|
71
|
-
def
|
72
|
-
|
52
|
+
def login_redirect?
|
53
|
+
!logged? && (layout != config.login_layout)
|
73
54
|
end
|
74
55
|
|
75
|
-
def
|
76
|
-
|
77
|
-
response.body = str if str
|
78
|
-
}
|
56
|
+
def unauthorized_but_logged
|
57
|
+
not_authorized unless logged?
|
79
58
|
end
|
80
59
|
|
81
|
-
def path(path_id, params={})
|
60
|
+
def path(path_id, params = {})
|
82
61
|
app.routes.path path_id, params
|
83
62
|
end
|
84
63
|
|
85
|
-
def app_path(app_name, path_id, params={})
|
64
|
+
def app_path(app_name, path_id, params = {})
|
86
65
|
app[app_name].routes.path path_id, params
|
87
66
|
end
|
88
67
|
|
89
|
-
def
|
90
|
-
|
68
|
+
def canonical_root
|
69
|
+
@canonical_root ||= begin
|
70
|
+
http_proto = Tzispa::Environment.instance.ssl? ? 'https://' : 'http://'
|
71
|
+
http_host = Tzispa::Environment.instance.host
|
72
|
+
http_port = Tzispa::Environment.instance.uri_port
|
73
|
+
"#{http_proto}#{http_host}#{http_port}"
|
74
|
+
end
|
91
75
|
end
|
92
76
|
|
93
|
-
def
|
94
|
-
|
77
|
+
def canonical_url(path_id, params = {})
|
78
|
+
"#{canonical_root}#{path(path_id, params)}"
|
95
79
|
end
|
96
80
|
|
97
|
-
def
|
98
|
-
|
99
|
-
app.routes.path layout, normalize_format(params)
|
81
|
+
def app_canonical_url(app_name, path_id, params = {})
|
82
|
+
"#{canonical_root}#{app_path(app_name, path_id, params)}"
|
100
83
|
end
|
101
84
|
|
102
|
-
def
|
103
|
-
|
104
|
-
|
85
|
+
def layout_path(layout, params = {})
|
86
|
+
is_default = app.default_layout? layout
|
87
|
+
params = normalize_format(params.merge(layout: layout)) unless is_default
|
88
|
+
app.routes.path layout, params
|
105
89
|
end
|
106
90
|
|
107
|
-
def
|
108
|
-
app.
|
91
|
+
def app_layout_path(app_name, layout, params = {})
|
92
|
+
is_default = app[app_name].default_layout? == layout
|
93
|
+
params = normalize_format(params.merge(layout: layout)) unless is_default
|
94
|
+
app[app_name].routes.path layout, params
|
109
95
|
end
|
110
96
|
|
111
|
-
def
|
112
|
-
|
97
|
+
def layout_canonical_url(layout, params = {})
|
98
|
+
"#{canonical_root}#{layout_path(layout, params)}"
|
99
|
+
end
|
100
|
+
|
101
|
+
def app_layout_canonical_url(app_name, layout, params = {})
|
102
|
+
"#{canonical_root}#{app_layout_path(app_name, layout, params)}"
|
113
103
|
end
|
114
104
|
|
115
105
|
def api(handler, verb, predicate, sufix, app_name = nil)
|
116
|
-
|
117
|
-
|
106
|
+
if app_name
|
107
|
+
app_canonical_url app_name, :api, handler: handler, verb: verb,
|
108
|
+
predicate: predicate, sufix: sufix
|
118
109
|
else
|
119
|
-
|
110
|
+
canonical_url :api, handler: handler, verb: verb,
|
111
|
+
predicate: predicate, sufix: sufix
|
120
112
|
end
|
121
113
|
end
|
122
114
|
|
123
115
|
def sapi(handler, verb, predicate, sufix, app_name = nil)
|
124
|
-
|
125
|
-
sign = sign_array [handler, verb, predicate], app.config.salt
|
126
|
-
canonical_url :sapi, sign: sign, handler: handler, verb: verb, predicate: predicate, sufix: sufix
|
127
|
-
else
|
116
|
+
if app_name
|
128
117
|
sign = sign_array [handler, verb, predicate], app[:app_name].config.salt
|
129
|
-
app_canonical_url app_name, :sapi, sign: sign, handler: handler,
|
118
|
+
app_canonical_url app_name, :sapi, sign: sign, handler: handler,
|
119
|
+
verb: verb, predicate: predicate, sufix: sufix
|
120
|
+
else
|
121
|
+
sign = sign_array [handler, verb, predicate], app.config.salt
|
122
|
+
canonical_url :sapi, sign: sign, handler: handler,
|
123
|
+
verb: verb, predicate: predicate, sufix: sufix
|
130
124
|
end
|
131
125
|
end
|
132
126
|
|
@@ -136,19 +130,10 @@ module Tzispa
|
|
136
130
|
|
137
131
|
private
|
138
132
|
|
139
|
-
def generate_session_id
|
140
|
-
SecureRandom.uuid.tap { |uuid|
|
141
|
-
session.id = uuid
|
142
|
-
session[SESSION_ID] = uuid
|
143
|
-
}
|
144
|
-
end
|
145
|
-
|
146
133
|
def normalize_format(params)
|
147
|
-
params.tap { |pmm|
|
148
|
-
pmm[:format] = config.default_format unless pmm[:format]
|
149
|
-
}
|
134
|
+
params.tap { |pmm| pmm[:format] = config.default_format unless pmm[:format] }
|
150
135
|
end
|
151
|
-
|
152
136
|
end
|
137
|
+
|
153
138
|
end
|
154
139
|
end
|
data/lib/tzispa/http/request.rb
CHANGED
@@ -2,34 +2,46 @@
|
|
2
2
|
|
3
3
|
require 'rack'
|
4
4
|
|
5
|
-
|
6
5
|
module Tzispa
|
7
6
|
module Http
|
7
|
+
|
8
8
|
class Request < Rack::Request
|
9
|
+
ALLOWED_HTTP_VERSIONS = ['HTTP/1.1', 'HTTP/2.0'].freeze
|
10
|
+
|
11
|
+
HTTP_X_FORWARDED_HOST = 'HTTP_X_FORWARDED_HOST'
|
9
12
|
|
10
|
-
|
13
|
+
REQUEST_METHOD = Rack::REQUEST_METHOD
|
11
14
|
|
15
|
+
alias secure? ssl?
|
12
16
|
|
13
|
-
|
14
|
-
|
15
|
-
|
17
|
+
def forwarded?
|
18
|
+
env.include? HTTP_X_FORWARDED_HOST
|
19
|
+
end
|
16
20
|
|
17
|
-
|
18
|
-
|
19
|
-
|
21
|
+
def http_version
|
22
|
+
env['HTTP_VERSION']
|
23
|
+
end
|
20
24
|
|
21
|
-
|
22
|
-
|
23
|
-
|
25
|
+
def allowed_http_version?
|
26
|
+
ALLOWED_HTTP_VERSIONS.include? http_version
|
27
|
+
end
|
24
28
|
|
25
|
-
|
26
|
-
|
27
|
-
|
29
|
+
def safe?
|
30
|
+
get? || head? || options? || trace?
|
31
|
+
end
|
28
32
|
|
29
|
-
|
30
|
-
|
31
|
-
|
33
|
+
def idempotent?
|
34
|
+
safe? || put? || delete? || link? || unlink?
|
35
|
+
end
|
32
36
|
|
37
|
+
def link?
|
38
|
+
request_method == 'LINK'
|
39
|
+
end
|
40
|
+
|
41
|
+
def unlink?
|
42
|
+
request_method == 'UNLINK'
|
43
|
+
end
|
33
44
|
end
|
45
|
+
|
34
46
|
end
|
35
47
|
end
|
data/lib/tzispa/http/response.rb
CHANGED
@@ -6,8 +6,7 @@ module Tzispa
|
|
6
6
|
module Http
|
7
7
|
|
8
8
|
class Response < Rack::Response
|
9
|
-
|
10
|
-
DROP_BODY_RESPONSES = [204, 205, 304]
|
9
|
+
DROP_BODY_RESPONSES = [204, 205, 304].freeze
|
11
10
|
|
12
11
|
def initialize(*)
|
13
12
|
super
|
@@ -15,8 +14,8 @@ module Tzispa
|
|
15
14
|
end
|
16
15
|
|
17
16
|
def body=(value)
|
18
|
-
value = value.body while Rack::Response
|
19
|
-
@body = String
|
17
|
+
value = value.body while value.is_a?(Rack::Response)
|
18
|
+
@body = value.is_a?(String) ? [value.to_str] : value
|
20
19
|
end
|
21
20
|
|
22
21
|
def each
|
@@ -27,8 +26,8 @@ module Tzispa
|
|
27
26
|
result = body
|
28
27
|
|
29
28
|
if drop_content_info?
|
30
|
-
headers.delete
|
31
|
-
headers.delete
|
29
|
+
headers.delete 'Content-Length'
|
30
|
+
headers.delete 'Content-Type'
|
32
31
|
end
|
33
32
|
|
34
33
|
if drop_body?
|
@@ -39,27 +38,61 @@ module Tzispa
|
|
39
38
|
if calculate_content_length?
|
40
39
|
# if some other code has already set Content-Length, don't muck with it
|
41
40
|
# currently, this would be the static file-handler
|
42
|
-
headers[
|
41
|
+
headers['Content-Length'] = body.inject(0) { |l, p| l + p.bytesize }.to_s
|
43
42
|
end
|
44
|
-
|
45
|
-
headers['X-Powered-By'] = "#{Tzispa::FRAMEWORK_NAME} #{Tzispa::VERSION}"
|
43
|
+
custom_headers
|
46
44
|
[status.to_i, headers, result]
|
47
45
|
end
|
48
46
|
|
49
|
-
|
47
|
+
def custom_headers
|
48
|
+
headers['X-Frame-Options'] = 'SAMEORIGIN'
|
49
|
+
headers['X-Powered-By'] = "#{Tzispa::FRAMEWORK_NAME} #{Tzispa::VERSION}"
|
50
|
+
end
|
51
|
+
|
52
|
+
def cache_control
|
53
|
+
headers['Cache-control']
|
54
|
+
end
|
55
|
+
|
56
|
+
def cache_private
|
57
|
+
add_cache_control 'private'
|
58
|
+
end
|
59
|
+
|
60
|
+
def no_store
|
61
|
+
add_cache_control 'no-store'
|
62
|
+
end
|
63
|
+
|
64
|
+
def no_cache
|
65
|
+
add_cache_control 'no-cache'
|
66
|
+
end
|
67
|
+
|
68
|
+
def must_revalidate
|
69
|
+
add_cache_control 'must-revalidate'
|
70
|
+
end
|
71
|
+
|
72
|
+
def max_age(seconds)
|
73
|
+
add_cache_control "max-age=#{seconds}"
|
74
|
+
end
|
50
75
|
|
51
76
|
def calculate_content_length?
|
52
|
-
headers[
|
77
|
+
headers['Content-Type'] && !headers['Content-Length'] && body.is_a?(Array)
|
53
78
|
end
|
54
79
|
|
55
80
|
def drop_content_info?
|
56
|
-
status.to_i / 100 == 1
|
81
|
+
status.to_i / 100 == 1 || drop_body?
|
57
82
|
end
|
58
83
|
|
59
84
|
def drop_body?
|
60
85
|
DROP_BODY_RESPONSES.include?(status.to_i)
|
61
86
|
end
|
62
87
|
|
88
|
+
private
|
89
|
+
|
90
|
+
def add_cache_control(policy)
|
91
|
+
acache = (cache_control || String.new).split(',').map(&:strip)
|
92
|
+
acache << policy unless acache.include?(policy)
|
93
|
+
headers['Cache-control'] = acache.join(', ')
|
94
|
+
self
|
95
|
+
end
|
63
96
|
end
|
64
97
|
|
65
98
|
end
|