Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
a11571ce
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
体验新版 GitCode,发现更多精彩内容 >>
提交
a11571ce
编写于
9月 07, 2015
作者:
J
Jeremy Daer (Kemper)
浏览文件
操作
浏览文件
下载
差异文件
Merge pull request #21520 from jeremy/friendlier-force-ssl
Make `config.force_ssl` less dangerous to try and easier to disable
上级
81dd3872
f6749224
变更
3
显示空白变更内容
内联
并排
Showing
3 changed file
with
252 addition
and
200 deletion
+252
-200
actionpack/CHANGELOG.md
actionpack/CHANGELOG.md
+27
-0
actionpack/lib/action_dispatch/middleware/ssl.rb
actionpack/lib/action_dispatch/middleware/ssl.rb
+92
-36
actionpack/test/dispatch/ssl_test.rb
actionpack/test/dispatch/ssl_test.rb
+133
-164
未找到文件。
actionpack/CHANGELOG.md
浏览文件 @
a11571ce
*
Make it easier to opt in to
`config.force_ssl`
and
`config.ssl_options`
by
making them less dangerous to try and easier to disable.
SSL redirect:
* Move `:host` and `:port` options within `redirect: { … }`. Deprecate.
* Introduce `:status` and `:body` to customize the redirect response.
The 301 permanent default makes it difficult to test the redirect and
back out of it since browsers remember the 301. Test with a 302 or 307
instead, then switch to 301 once you're confident that all is well.
HTTP Strict Transport Security (HSTS):
* Shorter max-age. Shorten the default max-age from 1 year to 180 days,
the low end for https://www.ssllabs.com/ssltest/ grading and greater
than the 18-week minimum to qualify for browser preload lists.
* Disabling HSTS. Setting `hsts: false` now sets `hsts { expires: 0 }`
instead of omitting the header. Omitting does nothing to disable HSTS
since browsers hang on to your previous settings until they expire.
Sending `{ hsts: { expires: 0 }}` flushes out old browser settings and
actually disables HSTS:
http://tools.ietf.org/html/rfc6797#section-6.1.1
* HSTS Preload. Introduce `preload: true` to set the `preload` flag,
indicating that your site may be included in browser preload lists,
including Chrome, Firefox, Safari, IE11, and Edge. Submit your site:
https://hstspreload.appspot.com
*Jeremy Daer*
*
Update
`ActionController::TestSession#fetch`
to behave more like
*
Update
`ActionController::TestSession#fetch`
to behave more like
`ActionDispatch::Request::Session#fetch`
when using non-string keys.
`ActionDispatch::Request::Session#fetch`
when using non-string keys.
...
...
actionpack/lib/action_dispatch/middleware/ssl.rb
浏览文件 @
a11571ce
module
ActionDispatch
module
ActionDispatch
# This middleware is added to the stack when `config.force_ssl = true`.
# It does three jobs to enforce secure HTTP requests:
#
# 1. TLS redirect. http:// requests are permanently redirected to https://
# with the same URL host, path, etc. Pass `:host` and/or `:port` to
# modify the destination URL. This is always enabled.
#
# 2. Secure cookies. Sets the `secure` flag on cookies to tell browsers they
# mustn't be sent along with http:// requests. This is always enabled.
#
# 3. HTTP Strict Transport Security (HSTS). Tells the browser to remember
# this site as TLS-only and automatically redirect non-TLS requests.
# Enabled by default. Pass `hsts: false` to disable.
#
# Configure HSTS with `hsts: { … }`:
# * `expires`: How long, in seconds, these settings will stick. Defaults to
# `18.weeks`, the minimum required to qualify for browser preload lists.
# * `subdomains`: Set to `true` to tell the browser to apply these settings
# to all subdomains. This protects your cookies from interception by a
# vulnerable site on a subdomain. Defaults to `false`.
# * `preload`: Advertise that this site may be included in browsers'
# preloaded HSTS lists. HSTS protects your site on every visit *except the
# first visit* since it hasn't seen your HSTS header yet. To close this
# gap, browser vendors include a baked-in list of HSTS-enabled sites.
# Go to https://hstspreload.appspot.com to submit your site for inclusion.
#
# Disabling HSTS: To turn off HSTS, omitting the header is not enough.
# Browsers will remember the original HSTS directive until it expires.
# Instead, use the header to tell browsers to expire HSTS immediately.
# Setting `hsts: false` is a shortcut for `hsts: { expires: 0 }`.
class
SSL
class
SSL
YEAR
=
31536000
# Default to 180 days, the low end for https://www.ssllabs.com/ssltest/
# and greater than the 18-week requirement for browser preload lists.
HSTS_EXPIRES_IN
=
15552000
def
self
.
default_hsts_options
def
self
.
default_hsts_options
{
:expires
=>
YEAR
,
:subdomains
=>
false
}
{
expires:
HSTS_EXPIRES_IN
,
subdomains:
false
,
preload:
false
}
end
end
def
initialize
(
app
,
options
=
{}
)
def
initialize
(
app
,
redirect:
{},
hsts:
{},
**
options
)
@app
=
app
@app
=
app
@hsts
=
options
.
fetch
(
:hsts
,
{})
if
options
[
:host
]
||
options
[
:port
]
@hsts
=
{}
if
@hsts
==
true
ActiveSupport
::
Deprecation
.
warn
<<-
end_warning
.
strip_heredoc
@hsts
=
self
.
class
.
default_hsts_options
.
merge
(
@hsts
)
if
@hsts
The `:host` and `:port` options are moving within `:redirect`:
`config.ssl_options = { redirect: { host: …, port: … }}`.
end_warning
@redirect
=
options
.
slice
(
:host
,
:port
)
else
@redirect
=
redirect
end
@host
=
options
[
:host
]
@hsts_header
=
build_hsts_header
(
normalize_hsts_options
(
hsts
))
@port
=
options
[
:port
]
end
end
def
call
(
env
)
def
call
(
env
)
request
=
Request
.
new
(
env
)
request
=
Request
.
new
env
if
request
.
ssl?
if
request
.
ssl?
status
,
headers
,
body
=
@app
.
call
(
env
)
@app
.
call
(
env
).
tap
do
|
status
,
headers
,
body
|
headers
.
reverse_merge!
(
hsts_headers
)
set_hsts_header!
headers
flag_cookies_as_secure!
(
headers
)
flag_cookies_as_secure!
headers
[
status
,
headers
,
body
]
end
else
else
redirect_to_https
(
request
)
redirect_to_https
request
end
end
end
end
private
private
def
redirect_to_https
(
request
)
def
set_hsts_header!
(
headers
)
host
=
@host
||
request
.
host
headers
[
'Strict-Transport-Security'
.
freeze
]
||=
@hsts_header
port
=
@port
||
request
.
port
location
=
"https://
#{
host
}
"
location
<<
":
#{
port
}
"
if
port
!=
80
location
<<
request
.
fullpath
headers
=
{
'Content-Type'
=>
'text/html'
,
'Location'
=>
location
}
[
301
,
headers
,
[]]
end
end
# http://tools.ietf.org/html/draft-hodges-strict-transport-sec-02
def
normalize_hsts_options
(
options
)
def
hsts_headers
case
options
if
@hsts
# Explicitly disabling HSTS clears the existing setting from browsers
value
=
"max-age=
#{
@hsts
[
:expires
].
to_i
}
"
# by setting expiry to 0.
value
+=
"; includeSubDomains"
if
@hsts
[
:subdomains
]
when
false
{
'Strict-Transport-Security'
=>
value
}
self
.
class
.
default_hsts_options
.
merge
(
expires:
0
)
# Default to enabled, with default options.
when
nil
,
true
self
.
class
.
default_hsts_options
else
else
{}
self
.
class
.
default_hsts_options
.
merge
(
options
)
end
end
end
end
# http://tools.ietf.org/html/rfc6797#section-6.1
def
build_hsts_header
(
hsts
)
value
=
"max-age=
#{
hsts
[
:expires
].
to_i
}
"
value
<<
"; includeSubDomains"
if
hsts
[
:subdomains
]
value
<<
"; preload"
if
hsts
[
:preload
]
value
end
def
flag_cookies_as_secure!
(
headers
)
def
flag_cookies_as_secure!
(
headers
)
if
cookies
=
headers
[
'Set-Cookie'
]
if
cookies
=
headers
[
'Set-Cookie'
.
freeze
]
cookies
=
cookies
.
split
(
"
\n
"
)
cookies
=
cookies
.
split
(
"
\n
"
.
freeze
)
headers
[
'Set-Cookie'
]
=
cookies
.
map
{
|
cookie
|
headers
[
'Set-Cookie'
.
freeze
]
=
cookies
.
map
{
|
cookie
|
if
cookie
!~
/;\s*secure\s*(;|$)/i
if
cookie
!~
/;\s*secure\s*(;|$)/i
"
#{
cookie
}
; secure"
"
#{
cookie
}
; secure"
else
else
cookie
cookie
end
end
}.
join
(
"
\n
"
)
}.
join
(
"
\n
"
.
freeze
)
end
end
def
redirect_to_https
(
request
)
[
@redirect
.
fetch
(
:status
,
301
),
{
'Content-Type'
=>
'text/html'
,
'Location'
=>
https_location_for
(
request
)
},
@redirect
.
fetch
(
:body
,
[])
]
end
end
def
https_location_for
(
request
)
host
=
@redirect
[
:host
]
||
request
.
host
port
=
@redirect
[
:port
]
||
request
.
port
location
=
"https://
#{
host
}
"
location
<<
":
#{
port
}
"
if
port
!=
80
&&
port
!=
443
location
<<
request
.
fullpath
location
end
end
end
end
end
end
actionpack/test/dispatch/ssl_test.rb
浏览文件 @
a11571ce
require
'abstract_unit'
require
'abstract_unit'
class
SSLTest
<
ActionDispatch
::
IntegrationTest
class
SSLTest
<
ActionDispatch
::
IntegrationTest
def
default_app
HEADERS
=
Rack
::
Utils
::
HeaderHash
.
new
'Content-Type'
=>
'text/html'
lambda
{
|
env
|
headers
=
{
'Content-Type'
=>
"text/html"
}
attr_accessor
:app
headers
[
'Set-Cookie'
]
=
"id=1; path=/
\n
token=abc; path=/; secure; HttpOnly"
[
200
,
headers
,
[
"OK"
]]
def
build_app
(
headers:
{},
ssl_options:
{})
headers
=
HEADERS
.
merge
(
headers
)
ActionDispatch
::
SSL
.
new
lambda
{
|
env
|
[
200
,
headers
,
[]]
},
ssl_options
end
end
class
RedirectSSLTest
<
SSLTest
def
assert_not_redirected
(
url
,
headers:
{})
self
.
app
=
build_app
get
url
,
headers:
headers
assert_response
:ok
end
def
assert_redirected
(
host:
nil
,
port:
nil
,
status:
301
,
body:
[],
deprecated_host:
nil
,
deprecated_port:
nil
,
from:
'http://a/b?c=d'
,
to:
from
.
sub
(
'http'
,
'https'
))
self
.
app
=
build_app
ssl_options:
{
redirect:
{
host:
host
,
port:
port
,
status:
status
,
body:
body
},
host:
deprecated_host
,
port:
deprecated_port
}
}
get
from
assert_response
status
assert_redirected_to
to
assert_equal
body
.
join
,
@response
.
body
end
end
def
app
test
'https is not redirected'
do
@app
||=
ActionDispatch
::
SSL
.
new
(
default_app
)
assert_not_redirected
'https://example.org'
end
end
attr_writer
:app
def
test_allows_https_url
test
'proxied https is not redirected'
do
get
"https://example.org/path?key=value"
assert_not_redirected
'http://example.org'
,
headers:
{
'HTTP_X_FORWARDED_PROTO'
=>
'https'
}
assert_response
:success
end
end
def
test_allows_https_proxy_header_url
test
'http is redirected to https'
do
get
"http://example.org/"
,
headers:
{
'HTTP_X_FORWARDED_PROTO'
=>
"https"
}
assert_redirected
assert_response
:success
end
end
def
test_redirects_http_to_https
test
'redirect with non-301 status'
do
get
"http://example.org/path?key=value"
assert_redirected
status:
307
assert_response
:redirect
assert_equal
"https://example.org/path?key=value"
,
response
.
headers
[
'Location'
]
end
end
def
test_hsts_header_by_default
test
'redirect with custom body'
do
get
"https://example.org/"
assert_redirected
body:
[
'foo'
]
assert_equal
"max-age=31536000"
,
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_no_hsts_with_insecure_connection
test
'redirect to specific host'
do
get
"http://example.org/"
assert_redirected
host:
'ssl'
,
to:
'https://ssl/b?c=d'
assert_not
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_hsts_header
test
'redirect to default port'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:hsts
=>
true
)
assert_redirected
port:
443
get
"https://example.org/"
assert_equal
"max-age=31536000"
,
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_disable_hsts_header
test
'redirect to non-default port'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:hsts
=>
false
)
assert_redirected
port:
8443
,
to:
'https://a:8443/b?c=d'
get
"https://example.org/"
assert_not
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_hsts_expires
test
'redirect to different host and non-default port'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:hsts
=>
{
:expires
=>
500
})
assert_redirected
host:
'ssl'
,
port:
8443
,
to:
'https://ssl:8443/b?c=d'
get
"https://example.org/"
assert_equal
"max-age=500"
,
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_hsts_expires_with_duration
test
'redirect to different host including port'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:hsts
=>
{
:expires
=>
1
.
year
})
assert_redirected
host:
'ssl:443'
,
to:
'https://ssl:443/b?c=d'
get
"https://example.org/"
assert_equal
"max-age=31557600"
,
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_hsts_include_subdomains
test
':host is deprecated, moved within redirect: { host: … }'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:hsts
=>
{
:subdomains
=>
true
})
assert_deprecated
do
get
"https://example.org/"
assert_redirected
deprecated_host:
'foo'
,
to:
'https://foo/b?c=d'
assert_equal
"max-age=31536000; includeSubDomains"
,
end
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_flag_cookies_as_secure
test
':port is deprecated, moved within redirect: { port: … }'
do
get
"https://example.org/"
assert_deprecated
do
assert_equal
[
"id=1; path=/; secure"
,
"token=abc; path=/; secure; HttpOnly"
],
assert_redirected
deprecated_port:
1
,
to:
'https://a:1/b?c=d'
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
end
end
end
end
def
test_flag_cookies_as_secure_at_end_of_line
class
StrictTransportSecurityTest
<
SSLTest
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
EXPECTED
=
'max-age=15552000'
headers
=
{
'Content-Type'
=>
"text/html"
,
'Set-Cookie'
=>
"problem=def; path=/; HttpOnly; secure"
}
[
200
,
headers
,
[
"OK"
]]
})
get
"https://example.org/"
def
assert_hsts
(
expected
,
url:
'https://example.org'
,
hsts:
{},
headers:
{})
assert_equal
[
"problem=def; path=/; HttpOnly; secure"
],
self
.
app
=
build_app
ssl_options:
{
hsts:
hsts
},
headers:
headers
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
get
url
assert_equal
expected
,
response
.
headers
[
'Strict-Transport-Security'
]
end
end
def
test_flag_cookies_as_secure_with_more_spaces_before
test
'enabled by default'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
assert_hsts
EXPECTED
headers
=
{
end
'Content-Type'
=>
"text/html"
,
'Set-Cookie'
=>
"problem=def; path=/; HttpOnly; secure"
}
[
200
,
headers
,
[
"OK"
]]
})
get
"https://example.org/"
test
'not sent with http:// responses'
do
assert_equal
[
"problem=def; path=/; HttpOnly; secure"
],
assert_hsts
nil
,
url:
'http://example.org'
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
end
end
def
test_flag_cookies_as_secure_with_more_spaces_after
test
'defers to app-provided header'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
assert_hsts
'app-provided'
,
headers:
{
'Strict-Transport-Security'
=>
'app-provided'
}
headers
=
{
end
'Content-Type'
=>
"text/html"
,
'Set-Cookie'
=>
"problem=def; path=/; secure; HttpOnly"
}
[
200
,
headers
,
[
"OK"
]]
})
get
"https://example.org/"
test
'hsts: true enables default settings'
do
assert_equal
[
"problem=def; path=/; secure; HttpOnly"
],
assert_hsts
EXPECTED
,
hsts:
true
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
end
end
test
'hsts: false sets max-age to zero, clearing browser HSTS settings'
do
assert_hsts
'max-age=0'
,
hsts:
false
end
def
test_flag_cookies_as_secure_with_has_not_spaces_before
test
':expires sets max-age'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
assert_hsts
'max-age=500'
,
hsts:
{
expires:
500
}
headers
=
{
end
'Content-Type'
=>
"text/html"
,
'Set-Cookie'
=>
"problem=def; path=/;secure; HttpOnly"
}
[
200
,
headers
,
[
"OK"
]]
})
get
"https://example.org/"
test
':expires supports AS::Duration arguments'
do
assert_equal
[
"problem=def; path=/;secure; HttpOnly"
],
assert_hsts
'max-age=31557600'
,
hsts:
{
expires:
1
.
year
}
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
end
end
def
test_flag_cookies_as_secure_with_has_not_spaces_after
test
'include subdomains'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
assert_hsts
"
#{
EXPECTED
}
; includeSubDomains"
,
hsts:
{
subdomains:
true
}
headers
=
{
end
'Content-Type'
=>
"text/html"
,
'Set-Cookie'
=>
"problem=def; path=/; secure;HttpOnly"
}
[
200
,
headers
,
[
"OK"
]]
})
get
"https://example.org/"
test
'exclude subdomains'
do
assert_equal
[
"problem=def; path=/; secure;HttpOnly"
],
assert_hsts
EXPECTED
,
hsts:
{
subdomains:
false
}
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
end
end
def
test_flag_cookies_as_secure_with_ignore_case
test
'opt in to browser preload lists'
do
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
assert_hsts
"
#{
EXPECTED
}
; preload"
,
hsts:
{
preload:
true
}
headers
=
{
end
'Content-Type'
=>
"text/html"
,
'Set-Cookie'
=>
"problem=def; path=/; Secure; HttpOnly"
}
[
200
,
headers
,
[
"OK"
]]
})
get
"https://example.org/"
test
'opt out of browser preload lists'
do
assert_equal
[
"problem=def; path=/; Secure; HttpOnly"
],
assert_hsts
EXPECTED
,
hsts:
{
preload:
false
}
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
end
end
end
def
test_no_cookies
class
SecureCookiesTest
<
SSLTest
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
DEFAULT
=
%(id=1; path=/\ntoken=abc; path=/; secure; HttpOnly)
[
200
,
{
'Content-Type'
=>
"text/html"
},
[
"OK"
]]
})
def
get
(
**
options
)
get
"https://example.org/"
self
.
app
=
build_app
(
**
options
)
assert
!
response
.
headers
[
'Set-Cookie'
]
super
'https://example.org'
end
def
assert_cookies
(
*
expected
)
assert_equal
expected
,
response
.
headers
[
'Set-Cookie'
].
split
(
"
\n
"
)
end
end
def
test_redirect_to_host
def
test_flag_cookies_as_secure
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:host
=>
"ssl.example.org"
)
get
headers:
{
'Set-Cookie'
=>
DEFAULT
}
get
"http://example.org/path?key=value"
assert_cookies
'id=1; path=/; secure'
,
'token=abc; path=/; secure; HttpOnly'
assert_equal
"https://ssl.example.org/path?key=value"
,
end
response
.
headers
[
'Location'
]
def
test_flag_cookies_as_secure_at_end_of_line
get
headers:
{
'Set-Cookie'
=>
'problem=def; path=/; HttpOnly; secure'
}
assert_cookies
'problem=def; path=/; HttpOnly; secure'
end
def
test_flag_cookies_as_secure_with_more_spaces_before
get
headers:
{
'Set-Cookie'
=>
'problem=def; path=/; HttpOnly; secure'
}
assert_cookies
'problem=def; path=/; HttpOnly; secure'
end
end
def
test_redirect_to_port
def
test_flag_cookies_as_secure_with_more_spaces_after
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:port
=>
8443
)
get
headers:
{
'Set-Cookie'
=>
'problem=def; path=/; secure; HttpOnly'
}
get
"http://example.org/path?key=value"
assert_cookies
'problem=def; path=/; secure; HttpOnly'
assert_equal
"https://example.org:8443/path?key=value"
,
response
.
headers
[
'Location'
]
end
end
def
test_redirect_to_host_and_port
def
test_flag_cookies_as_secure_with_has_not_spaces_before
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:host
=>
"ssl.example.org"
,
:port
=>
8443
)
get
headers:
{
'Set-Cookie'
=>
'problem=def; path=/;secure; HttpOnly'
}
get
"http://example.org/path?key=value"
assert_cookies
'problem=def; path=/;secure; HttpOnly'
assert_equal
"https://ssl.example.org:8443/path?key=value"
,
response
.
headers
[
'Location'
]
end
end
def
test_redirect_to_host_with_port
def
test_flag_cookies_as_secure_with_has_not_spaces_after
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:host
=>
"ssl.example.org:443"
)
get
headers:
{
'Set-Cookie'
=>
'problem=def; path=/; secure;HttpOnly'
}
get
"http://example.org/path?key=value"
assert_cookies
'problem=def; path=/; secure;HttpOnly'
assert_equal
"https://ssl.example.org:443/path?key=value"
,
response
.
headers
[
'Location'
]
end
end
def
test_redirect_to_secure_host_when_on_subdomain
def
test_flag_cookies_as_secure_with_ignore_case
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:host
=>
"ssl.example.org"
)
get
headers:
{
'Set-Cookie'
=>
'problem=def; path=/; Secure; HttpOnly'
}
get
"http://ssl.example.org/path?key=value"
assert_cookies
'problem=def; path=/; Secure; HttpOnly'
assert_equal
"https://ssl.example.org/path?key=value"
,
response
.
headers
[
'Location'
]
end
end
def
test_redirect_to_secure_subdomain_when_on_deep_subdomain
def
test_no_cookies
self
.
app
=
ActionDispatch
::
SSL
.
new
(
default_app
,
:host
=>
"example.co.uk"
)
get
get
"http://double.rainbow.what.does.it.mean.example.co.uk/path?key=value"
assert_nil
response
.
headers
[
'Set-Cookie'
]
assert_equal
"https://example.co.uk/path?key=value"
,
response
.
headers
[
'Location'
]
end
end
def
test_keeps_original_headers_behavior
def
test_keeps_original_headers_behavior
headers
=
Rack
::
Utils
::
HeaderHash
.
new
(
get
headers:
{
'Connection'
=>
%w[close]
}
"Content-Type"
=>
"text/html"
,
assert_equal
'close'
,
response
.
headers
[
'Connection'
]
"Connection"
=>
[
"close"
]
)
self
.
app
=
ActionDispatch
::
SSL
.
new
(
lambda
{
|
env
|
[
200
,
headers
,
[
"OK"
]]
})
get
"https://example.org/"
assert_equal
"close"
,
response
.
headers
[
"Connection"
]
end
end
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录