ixtlan-core 0.5.0 → 0.6.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.
- 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
|