ixtlan-core 0.5.0 → 0.6.0
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/ixtlan/core/cache_headers.rb +9 -8
- data/lib/ixtlan/core/extra_headers.rb +11 -6
- data/lib/ixtlan/core/railtie.rb +5 -2
- data/lib/ixtlan/core/x_content_type_headers.rb +30 -0
- data/lib/ixtlan/core/x_frame_headers.rb +10 -7
- data/lib/ixtlan/core/x_xss_protection_headers.rb +32 -0
- data/spec/cache_headers_spec.rb +51 -0
- data/spec/controller.rb +78 -0
- data/spec/x_headers_spec.rb +74 -0
- metadata +31 -13
@@ -9,7 +9,7 @@ module Ixtlan
|
|
9
9
|
# Pragma: no-cache
|
10
10
|
# Cache-control: no-cache, must-revalidate
|
11
11
|
def no_caching(no_store = true)
|
12
|
-
if
|
12
|
+
if cacheable_response?
|
13
13
|
response.headers["Date"] = timestamp
|
14
14
|
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 GMT"
|
15
15
|
response.headers["Pragma"] = "no-cache"
|
@@ -21,7 +21,7 @@ module Ixtlan
|
|
21
21
|
# Expires: Fri, 01 Jan 1990 00:00:00 GMT
|
22
22
|
# Cache-control: private, max-age=<1dayInSeconds>
|
23
23
|
def only_browser_can_cache(no_store = false, max_age_in_seconds = 0)
|
24
|
-
if
|
24
|
+
if cacheable_response?
|
25
25
|
response.headers["Date"] = timestamp
|
26
26
|
response.headers["Expires"] = "Fri, 01 Jan 1990 00:00:00 UTC"
|
27
27
|
response.headers["Cache-Control"] = "private, max-age=#{max_age_in_seconds}" + (", no-store" if no_store).to_s
|
@@ -32,7 +32,7 @@ module Ixtlan
|
|
32
32
|
# Expires: <ServerCurrentDate + 1month>
|
33
33
|
# Cache-control: public, max-age=<1month>
|
34
34
|
def allow_browser_and_proxy_to_cache(no_store = false, max_age_in_seconds = 0)
|
35
|
-
if
|
35
|
+
if cacheable_response?
|
36
36
|
now = Time.now
|
37
37
|
response.headers["Date"] = timestamp(now)
|
38
38
|
response.headers["Expires"] = timestamp(now + max_age_in_seconds)
|
@@ -40,9 +40,9 @@ module Ixtlan
|
|
40
40
|
end
|
41
41
|
end
|
42
42
|
|
43
|
-
def cache_headers
|
44
|
-
if
|
45
|
-
mode
|
43
|
+
def cache_headers(mode = nil)
|
44
|
+
if respond_to?(:current_user) && send(:current_user)
|
45
|
+
mode ||= self.class.instance_variable_get(:@_cache_headers)
|
46
46
|
case mode
|
47
47
|
when :private
|
48
48
|
no_caching(self.class.instance_variable_get(:@no_store))
|
@@ -50,6 +50,7 @@ module Ixtlan
|
|
50
50
|
only_browser_can_cache(self.class.instance_variable_get(:@no_store))
|
51
51
|
when :public
|
52
52
|
allow_browser_and_proxy_to_cache(self.class.instance_variable_get(:@no_store))
|
53
|
+
when :off
|
53
54
|
else
|
54
55
|
send mode if mode
|
55
56
|
end
|
@@ -60,7 +61,7 @@ module Ixtlan
|
|
60
61
|
base.class_eval do
|
61
62
|
def self.cache_headers(mode = nil, no_store = true)
|
62
63
|
if(mode)
|
63
|
-
@
|
64
|
+
@_cache_headers = mode.to_sym
|
64
65
|
end
|
65
66
|
@no_store = no_store
|
66
67
|
end
|
@@ -68,7 +69,7 @@ module Ixtlan
|
|
68
69
|
end
|
69
70
|
|
70
71
|
private
|
71
|
-
def
|
72
|
+
def cacheable_response?
|
72
73
|
request.method.to_s.downcase == "get" &&
|
73
74
|
[200, 203, 206, 300, 301].member?(response.status)
|
74
75
|
end
|
@@ -6,22 +6,27 @@ module Ixtlan
|
|
6
6
|
base.class_eval do
|
7
7
|
alias :render_old :render
|
8
8
|
def render(*args, &block)
|
9
|
-
|
10
|
-
x_frame_headers
|
9
|
+
_extra_header(*args)
|
11
10
|
render_old(*args, &block)
|
12
11
|
end
|
13
12
|
alias :send_file_old :send_file
|
14
13
|
def send_file(*args)
|
15
|
-
|
16
|
-
x_frame_headers
|
14
|
+
_extra_header(*args)
|
17
15
|
send_file_old(*args)
|
18
16
|
end
|
19
17
|
alias :send_data_old :send_data
|
20
18
|
def send_data(*args)
|
21
|
-
|
22
|
-
x_frame_headers
|
19
|
+
_extra_header(*args)
|
23
20
|
send_file_old(*args)
|
24
21
|
end
|
22
|
+
private
|
23
|
+
def _extra_header(*args)
|
24
|
+
opt = (args[0].is_a?(Hash) ? args[0] : args[1]) || {}
|
25
|
+
cache_headers(opt[:cache_headers])
|
26
|
+
x_frame_headers(opt[:x_frame_headers])
|
27
|
+
x_content_type_headers(opt[:x_content_type_headers])
|
28
|
+
x_xss_protection_headers(opt[:x_xss_protection_headers])
|
29
|
+
end
|
25
30
|
end
|
26
31
|
end
|
27
32
|
end
|
data/lib/ixtlan/core/railtie.rb
CHANGED
@@ -1,6 +1,8 @@
|
|
1
1
|
require 'ixtlan/core/extra_headers'
|
2
2
|
require 'ixtlan/core/cache_headers'
|
3
3
|
require 'ixtlan/core/x_frame_headers'
|
4
|
+
require 'ixtlan/core/x_content_type_headers'
|
5
|
+
require 'ixtlan/core/x_xss_protection_headers'
|
4
6
|
require 'ixtlan/core/optimistic_active_record'
|
5
7
|
require 'ixtlan/core/optimistic_data_mapper'
|
6
8
|
require 'ixtlan/core/configuration_rack'
|
@@ -40,9 +42,8 @@ module Ixtlan
|
|
40
42
|
|
41
43
|
config.before_configuration do |app|
|
42
44
|
app.config.class.class_eval do
|
43
|
-
attr_accessor :x_frame_headers
|
45
|
+
attr_accessor :x_frame_headers, :x_content_type_headers, :x_xss_protection_headers
|
44
46
|
end
|
45
|
-
app.config.x_frame_headers = :deny
|
46
47
|
end
|
47
48
|
|
48
49
|
config.before_initialize do |app|
|
@@ -55,6 +56,8 @@ module Ixtlan
|
|
55
56
|
end
|
56
57
|
::ActionController::Base.send(:include, Ixtlan::Core::ExtraHeaders)
|
57
58
|
::ActionController::Base.send(:include, Ixtlan::Core::XFrameHeaders)
|
59
|
+
::ActionController::Base.send(:include, Ixtlan::Core::XContentTypeHeaders)
|
60
|
+
::ActionController::Base.send(:include, Ixtlan::Core::XXssProtectionHeaders)
|
58
61
|
::ActionController::Base.send(:include, Ixtlan::Core::CacheHeaders)
|
59
62
|
|
60
63
|
app.config.middleware.use Ixtlan::Core::ConfigurationRack
|
@@ -0,0 +1,30 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Core
|
3
|
+
module XContentTypeHeaders
|
4
|
+
|
5
|
+
protected
|
6
|
+
|
7
|
+
def x_content_type_headers(mode = nil)
|
8
|
+
case mode || self.class.instance_variable_get(:@_x_content_type_headers) || Rails.configuration.x_content_type_headers || :nosniff
|
9
|
+
when :nosniff
|
10
|
+
response.headers["X-Content-Type-Options"] = "nosniff"
|
11
|
+
when :off
|
12
|
+
else
|
13
|
+
warn "allowed values for x_content_type_headers are :nosniff, :off"
|
14
|
+
end
|
15
|
+
end
|
16
|
+
|
17
|
+
def self.included(base)
|
18
|
+
base.class_eval do
|
19
|
+
def self.x_content_type_headers(mode)
|
20
|
+
if(mode)
|
21
|
+
@_x_content_type_headers = mode.to_sym
|
22
|
+
else
|
23
|
+
@_x_content_type_headers = nil
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
@@ -4,22 +4,25 @@ module Ixtlan
|
|
4
4
|
|
5
5
|
protected
|
6
6
|
|
7
|
-
def x_frame_headers
|
8
|
-
case self.class.instance_variable_get(:@
|
7
|
+
def x_frame_headers(mode = nil)
|
8
|
+
case mode || self.class.instance_variable_get(:@_x_frame_headers) || Rails.configuration.x_frame_headers || :deny
|
9
9
|
when :deny
|
10
|
-
response.headers["X-
|
10
|
+
response.headers["X-Frame-Options"] = "DENY"
|
11
11
|
when :sameorigin
|
12
|
-
response.headers["X-
|
12
|
+
response.headers["X-Frame-Options"] = "SAMEORIGIN"
|
13
|
+
when :off
|
14
|
+
else
|
15
|
+
warn "allowed values for x_frame_headers are :deny, :sameorigin, :off"
|
13
16
|
end
|
14
17
|
end
|
15
|
-
|
18
|
+
|
16
19
|
def self.included(base)
|
17
20
|
base.class_eval do
|
18
21
|
def self.x_frame_headers(mode)
|
19
22
|
if(mode)
|
20
|
-
@
|
23
|
+
@_x_frame_headers = mode.to_sym
|
21
24
|
else
|
22
|
-
@
|
25
|
+
@_x_frame_headers = nil
|
23
26
|
end
|
24
27
|
end
|
25
28
|
end
|
@@ -0,0 +1,32 @@
|
|
1
|
+
module Ixtlan
|
2
|
+
module Core
|
3
|
+
module XXssProtectionHeaders
|
4
|
+
|
5
|
+
protected
|
6
|
+
|
7
|
+
def x_xss_protection_headers(mode = nil)
|
8
|
+
case mode || self.class.instance_variable_get(:@_x_xss_protection_headers) || Rails.configuration.x_xss_protection_headers || :block
|
9
|
+
when :disabled
|
10
|
+
response.headers["X-XSS-Protection"] = "0"
|
11
|
+
when :block
|
12
|
+
response.headers["X-XSS-Protection"] = "1; mode=block"
|
13
|
+
when :off
|
14
|
+
else
|
15
|
+
warn "allowed values for x_xss_protection_headers are :nocheck, :block, :off"
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
def self.included(base)
|
20
|
+
base.class_eval do
|
21
|
+
def self.x_xss_protection_headers(mode)
|
22
|
+
if(mode)
|
23
|
+
@_x_xss_protection_headers = mode.to_sym
|
24
|
+
else
|
25
|
+
@_x_xss_protection_headers = nil
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'controller'
|
2
|
+
|
3
|
+
|
4
|
+
class MyControllerWithUser < ControllerWithUser
|
5
|
+
cache_headers :private
|
6
|
+
end
|
7
|
+
|
8
|
+
[:render, :send_file, :send_data].each do |method|
|
9
|
+
describe "cache-headers using controller method #{method}" do
|
10
|
+
context "with simple controller" do
|
11
|
+
subject { ControllerWithUser.new(Object.new) }
|
12
|
+
|
13
|
+
it 'should use default' do
|
14
|
+
subject.send method, :inline => "asd"
|
15
|
+
subject.response.headers.should == {"X-Frame-Options"=>"DENY", "X-Content-Type-Options"=>"nosniff", "X-XSS-Protection"=>"1; mode=block"}
|
16
|
+
end
|
17
|
+
it 'should use given option' do
|
18
|
+
subject.send method, :inline => "asd", :cache_headers => :protected
|
19
|
+
subject.response.headers.delete("Date").should_not be_nil
|
20
|
+
subject.response.headers.delete("Expires").should_not be_nil
|
21
|
+
subject.response.headers.should == {"Cache-Control"=>"private, max-age=0", "X-Frame-Options"=>"DENY", "X-Content-Type-Options"=>"nosniff", "X-XSS-Protection"=>"1; mode=block"}
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
context "with controller with header configuration" do
|
26
|
+
subject { MyControllerWithUser.new(Object.new) }
|
27
|
+
|
28
|
+
it 'should use configuration' do
|
29
|
+
subject.send method, :inline => "asd"
|
30
|
+
subject.response.headers.delete("Date").should_not be_nil
|
31
|
+
subject.response.headers.delete("Expires").should_not be_nil
|
32
|
+
subject.response.headers.should == {"Pragma"=>"no-cache", "Cache-Control"=>"no-cache, must-revalidate, no-store", "X-Frame-Options"=>"DENY", "X-Content-Type-Options"=>"nosniff", "X-XSS-Protection"=>"1; mode=block"}
|
33
|
+
end
|
34
|
+
it 'should use given option' do
|
35
|
+
subject.send method, :inline => "asd", :cache_headers => :public
|
36
|
+
subject.response.headers.delete("Date").should_not be_nil
|
37
|
+
subject.response.headers.delete("Expires").should_not be_nil
|
38
|
+
subject.response.headers.should == {"Cache-Control"=>"public, max-age=0, no-store", "X-Frame-Options"=>"DENY", "X-Content-Type-Options"=>"nosniff", "X-XSS-Protection"=>"1; mode=block"}
|
39
|
+
end
|
40
|
+
end
|
41
|
+
|
42
|
+
context "with simple controller without user" do
|
43
|
+
subject { MyControllerWithUser.new }
|
44
|
+
|
45
|
+
it 'should use default' do
|
46
|
+
subject.send method, :inline => "asd"
|
47
|
+
subject.response.headers.should == {"X-Frame-Options"=>"DENY", "X-Content-Type-Options"=>"nosniff", "X-XSS-Protection"=>"1; mode=block"}
|
48
|
+
end
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
data/spec/controller.rb
ADDED
@@ -0,0 +1,78 @@
|
|
1
|
+
require 'ixtlan/core/extra_headers'
|
2
|
+
require 'ixtlan/core/cache_headers'
|
3
|
+
require 'ixtlan/core/x_frame_headers'
|
4
|
+
require 'ixtlan/core/x_content_type_headers'
|
5
|
+
require 'ixtlan/core/x_xss_protection_headers'
|
6
|
+
|
7
|
+
class Controller
|
8
|
+
|
9
|
+
def render(*args, &block)
|
10
|
+
@render = args if args.size > 0
|
11
|
+
@render
|
12
|
+
end
|
13
|
+
def send_file(*args, &block)
|
14
|
+
@send_file = args if args.size > 0
|
15
|
+
@send_file
|
16
|
+
end
|
17
|
+
def send_data(*args, &block)
|
18
|
+
@send_data = args if args.size > 0
|
19
|
+
@send_data
|
20
|
+
end
|
21
|
+
|
22
|
+
include Ixtlan::Core::ExtraHeaders
|
23
|
+
include Ixtlan::Core::XFrameHeaders
|
24
|
+
include Ixtlan::Core::XContentTypeHeaders
|
25
|
+
include Ixtlan::Core::XXssProtectionHeaders
|
26
|
+
include Ixtlan::Core::CacheHeaders
|
27
|
+
|
28
|
+
def response
|
29
|
+
unless @response
|
30
|
+
@response = Object.new
|
31
|
+
|
32
|
+
def @response.headers
|
33
|
+
@headers ||= {}
|
34
|
+
end
|
35
|
+
def @response.status(st = nil)
|
36
|
+
@status = st if st
|
37
|
+
@status
|
38
|
+
end
|
39
|
+
end
|
40
|
+
@response
|
41
|
+
end
|
42
|
+
|
43
|
+
def request
|
44
|
+
unless @request
|
45
|
+
@request = Object.new
|
46
|
+
def @request.method(m = nil)
|
47
|
+
@method = m if m
|
48
|
+
@method
|
49
|
+
end
|
50
|
+
end
|
51
|
+
@request
|
52
|
+
end
|
53
|
+
|
54
|
+
end
|
55
|
+
|
56
|
+
class ControllerWithUser < Controller
|
57
|
+
|
58
|
+
def initialize(user = nil, status = 200, method = :get)
|
59
|
+
@user = user
|
60
|
+
request.method method
|
61
|
+
response.status status
|
62
|
+
end
|
63
|
+
def current_user
|
64
|
+
@user
|
65
|
+
end
|
66
|
+
|
67
|
+
end
|
68
|
+
|
69
|
+
class Rails
|
70
|
+
|
71
|
+
class Config
|
72
|
+
attr_accessor :x_content_type_headers, :x_frame_headers , :x_xss_protection_headers, :cache_headers
|
73
|
+
end
|
74
|
+
|
75
|
+
def self.configuration
|
76
|
+
@config ||= Config.new
|
77
|
+
end
|
78
|
+
end
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require 'controller'
|
2
|
+
|
3
|
+
shared_examples 'a X-Headers' do
|
4
|
+
|
5
|
+
it 'should be able to switch off' do
|
6
|
+
subject.send method, :inline => "asd", :x_frame_headers => :off, :x_content_type_headers => :off, :x_xss_protection_headers => :off
|
7
|
+
subject.response.headers.should == {}
|
8
|
+
end
|
9
|
+
|
10
|
+
end
|
11
|
+
|
12
|
+
class MyController < Controller
|
13
|
+
x_frame_headers :sameorigin
|
14
|
+
x_content_type_headers :off
|
15
|
+
x_xss_protection_headers :disabled
|
16
|
+
end
|
17
|
+
|
18
|
+
[:render, :send_file, :send_data].each do |method|
|
19
|
+
describe "x-headers using controller method #{method}" do
|
20
|
+
context "with simple controller" do
|
21
|
+
before do
|
22
|
+
Rails.configuration.x_frame_headers = nil
|
23
|
+
Rails.configuration.x_content_type_headers = nil
|
24
|
+
Rails.configuration.x_xss_protection_headers = nil
|
25
|
+
end
|
26
|
+
subject { Controller.new }
|
27
|
+
|
28
|
+
it 'should use default' do
|
29
|
+
subject.send method, :inline => "asd"
|
30
|
+
subject.response.headers.should == {"X-Frame-Options"=>"DENY", "X-Content-Type-Options"=>"nosniff", "X-XSS-Protection"=>"1; mode=block"}
|
31
|
+
end
|
32
|
+
|
33
|
+
it_behaves_like "a X-Headers" do
|
34
|
+
let(:method) { method }
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
context "with controller with header configuration" do
|
39
|
+
before do
|
40
|
+
Rails.configuration.x_frame_headers = nil
|
41
|
+
Rails.configuration.x_content_type_headers = nil
|
42
|
+
Rails.configuration.x_xss_protection_headers = nil
|
43
|
+
end
|
44
|
+
subject { MyController.new }
|
45
|
+
|
46
|
+
it 'should use configuration' do
|
47
|
+
subject.send method, :inline => "asd"
|
48
|
+
subject.response.headers.should == {"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"0"}
|
49
|
+
end
|
50
|
+
|
51
|
+
it_behaves_like "a X-Headers" do
|
52
|
+
let(:method) { method }
|
53
|
+
end
|
54
|
+
end
|
55
|
+
|
56
|
+
context "with simple controller with rails configuration" do
|
57
|
+
before do
|
58
|
+
Rails.configuration.x_frame_headers = :sameorigin
|
59
|
+
Rails.configuration.x_content_type_headers = :off
|
60
|
+
Rails.configuration.x_xss_protection_headers = :disabled
|
61
|
+
end
|
62
|
+
subject { Controller.new }
|
63
|
+
|
64
|
+
it 'should use configuration' do
|
65
|
+
subject.send method, :inline => "asd"
|
66
|
+
subject.response.headers.should == {"X-Frame-Options"=>"SAMEORIGIN", "X-XSS-Protection"=>"0"}
|
67
|
+
end
|
68
|
+
|
69
|
+
it_behaves_like "a X-Headers" do
|
70
|
+
let(:method) { method }
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
metadata
CHANGED
@@ -2,7 +2,7 @@
|
|
2
2
|
name: ixtlan-core
|
3
3
|
version: !ruby/object:Gem::Version
|
4
4
|
prerelease:
|
5
|
-
version: 0.
|
5
|
+
version: 0.6.0
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
8
8
|
- mkristian
|
@@ -10,7 +10,7 @@ autorequire:
|
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
12
|
|
13
|
-
date: 2011-
|
13
|
+
date: 2011-09-05 00:00:00 +05:30
|
14
14
|
default_executable:
|
15
15
|
dependencies:
|
16
16
|
- !ruby/object:Gem::Dependency
|
@@ -28,50 +28,61 @@ dependencies:
|
|
28
28
|
type: :runtime
|
29
29
|
version_requirements: *id001
|
30
30
|
- !ruby/object:Gem::Dependency
|
31
|
-
name:
|
31
|
+
name: ixtlan-generators
|
32
32
|
prerelease: false
|
33
33
|
requirement: &id002 !ruby/object:Gem::Requirement
|
34
34
|
none: false
|
35
35
|
requirements:
|
36
36
|
- - "="
|
37
37
|
- !ruby/object:Gem::Version
|
38
|
-
version:
|
38
|
+
version: 0.1.0
|
39
39
|
type: :development
|
40
40
|
version_requirements: *id002
|
41
41
|
- !ruby/object:Gem::Dependency
|
42
|
-
name:
|
42
|
+
name: rails
|
43
43
|
prerelease: false
|
44
44
|
requirement: &id003 !ruby/object:Gem::Requirement
|
45
45
|
none: false
|
46
46
|
requirements:
|
47
47
|
- - "="
|
48
48
|
- !ruby/object:Gem::Version
|
49
|
-
version:
|
49
|
+
version: 3.0.9
|
50
50
|
type: :development
|
51
51
|
version_requirements: *id003
|
52
52
|
- !ruby/object:Gem::Dependency
|
53
|
-
name:
|
53
|
+
name: rspec
|
54
54
|
prerelease: false
|
55
55
|
requirement: &id004 !ruby/object:Gem::Requirement
|
56
56
|
none: false
|
57
57
|
requirements:
|
58
58
|
- - "="
|
59
59
|
- !ruby/object:Gem::Version
|
60
|
-
version:
|
60
|
+
version: 2.6.0
|
61
61
|
type: :development
|
62
62
|
version_requirements: *id004
|
63
63
|
- !ruby/object:Gem::Dependency
|
64
|
-
name:
|
64
|
+
name: cucumber
|
65
65
|
prerelease: false
|
66
66
|
requirement: &id005 !ruby/object:Gem::Requirement
|
67
67
|
none: false
|
68
68
|
requirements:
|
69
69
|
- - "="
|
70
70
|
- !ruby/object:Gem::Version
|
71
|
-
version: 0.
|
71
|
+
version: 0.9.4
|
72
72
|
type: :development
|
73
73
|
version_requirements: *id005
|
74
|
-
|
74
|
+
- !ruby/object:Gem::Dependency
|
75
|
+
name: ruby-maven
|
76
|
+
prerelease: false
|
77
|
+
requirement: &id006 !ruby/object:Gem::Requirement
|
78
|
+
none: false
|
79
|
+
requirements:
|
80
|
+
- - "="
|
81
|
+
- !ruby/object:Gem::Version
|
82
|
+
version: 0.8.3.0.3.0.28.3
|
83
|
+
type: :development
|
84
|
+
version_requirements: *id006
|
85
|
+
description: cache header control, dynamic configuration, and optimistic find on model via updated_at timestamp
|
75
86
|
email:
|
76
87
|
- m.kristian@web.de
|
77
88
|
executables: []
|
@@ -115,10 +126,15 @@ files:
|
|
115
126
|
- lib/ixtlan/core/configuration_rack.rb
|
116
127
|
- lib/ixtlan/core/optimistic_active_record.rb
|
117
128
|
- lib/ixtlan/core/extra_headers.rb
|
129
|
+
- lib/ixtlan/core/x_content_type_headers.rb
|
118
130
|
- lib/ixtlan/core/cache_headers.rb
|
131
|
+
- lib/ixtlan/core/x_xss_protection_headers.rb
|
119
132
|
- lib/ixtlan/core/railtie.rb
|
120
133
|
- lib/ixtlan/core/configuration_manager.rb
|
121
134
|
- lib/ixtlan/core/controllers/configuration_controller.rb
|
135
|
+
- spec/controller.rb
|
136
|
+
- spec/cache_headers_spec.rb
|
137
|
+
- spec/x_headers_spec.rb
|
122
138
|
- spec/configuration_manager_spec.rb
|
123
139
|
has_rdoc: true
|
124
140
|
homepage: http://github.com/mkristian/ixtlan-core
|
@@ -127,7 +143,7 @@ licenses:
|
|
127
143
|
post_install_message:
|
128
144
|
rdoc_options:
|
129
145
|
- --main
|
130
|
-
- README.
|
146
|
+
- README.md
|
131
147
|
require_paths:
|
132
148
|
- lib
|
133
149
|
required_ruby_version: !ruby/object:Gem::Requirement
|
@@ -148,6 +164,8 @@ rubyforge_project:
|
|
148
164
|
rubygems_version: 1.5.1
|
149
165
|
signing_key:
|
150
166
|
specification_version: 3
|
151
|
-
summary: cache header control, dynamic configuration, and
|
167
|
+
summary: cache header control, dynamic configuration, and optimistic find on model via updated_at timestamp
|
152
168
|
test_files:
|
169
|
+
- spec/cache_headers_spec.rb
|
170
|
+
- spec/x_headers_spec.rb
|
153
171
|
- spec/configuration_manager_spec.rb
|