diff options
author | Samuel Williams <samuel.williams@oriontransfer.co.nz> | 2022-04-12 02:04:32 +1200 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-04-11 07:04:32 -0700 |
commit | 0493142d9a472249383c72d6d7e1195b3ca38df0 (patch) | |
tree | 97ca6d67868be30bfbc34499662075547d06a1d9 | |
parent | c0bf85f5ed49eb952619ed2705c3b49e5310d237 (diff) | |
download | rack-0493142d9a472249383c72d6d7e1195b3ca38df0.tar.gz |
Add documentation to key `Rack::Utils` cookie methods. (#1850)
-rw-r--r-- | lib/rack/utils.rb | 102 |
1 files changed, 90 insertions, 12 deletions
diff --git a/lib/rack/utils.rb b/lib/rack/utils.rb index ee1f93a5..7f402d93 100644 --- a/lib/rack/utils.rb +++ b/lib/rack/utils.rb @@ -219,17 +219,20 @@ module Rack (encoding_candidates & available_encodings)[0] end - def parse_cookies(env) - parse_cookies_header env[HTTP_COOKIE] - end + # :call-seq: + # parse_cookies_header(value) -> hash + # + # Parse cookies from the provided header +value+ according to RFC6265. The + # syntax for cookie headers only supports semicolons. Returns a map of + # cookie +key+ to cookie +value+. + # + # parse_cookies_header('myname=myvalue; max-age=0') + # # => {"myname"=>"myvalue", "max-age"=>"0"} + # + def parse_cookies_header(value) + return {} unless value - def parse_cookies_header(header) - # According to RFC 6265: - # The syntax for cookie headers only supports semicolons - # User Agent -> Server == - # Cookie: SID=31d4d96e407aad42; lang=en-US - return {} unless header - header.split(/[;] */n).each_with_object({}) do |cookie, cookies| + value.split(/[;] */n).each_with_object({}) do |cookie, cookies| next if cookie.empty? key, value = cookie.split('=', 2) cookies[key] = (unescape(value) rescue value) unless cookies.key?(key) @@ -251,6 +254,42 @@ module Rack end end + # :call-seq: + # parse_cookies(env) -> hash + # + # Parse cookies from the provided request environment using + # parse_cookies_header. Returns a map of cookie +key+ to cookie +value+. + # + # parse_cookies({'HTTP_COOKIE' => 'myname=myvalue'}) + # # => {'myname' => 'myvalue'} + # + def parse_cookies(env) + parse_cookies_header env[HTTP_COOKIE] + end + + # :call-seq: + # set_cookie_header(key, value) -> encoded string + # + # Generate an encoded string using the provided +key+ and +value+ suitable + # for the +set-cookie+ header according to RFC6265. The +value+ may be an + # instance of either +String+ or +Hash+. + # + # If the cookie +value+ is an instance of +Hash+, it considers the following + # cookie attribute keys: +domain+, +max_age+, +expires+ (must be instance + # of +Time+), +secure+, +http_only+, +same_site+ and +value+. For more + # details about the interpretation of these fields, consult + # [RFC6265 Section 5.2](https://datatracker.ietf.org/doc/html/rfc6265#section-5.2). + # + # An extra cookie attribute +escape_key+ can be provided to control whether + # or not the cookie key is URL encoded. If explicitly set to +false+, the + # cookie key name will not be url encoded (escaped). The default is +true+. + # + # set_cookie_header("myname", "myvalue") + # # => "myname=myvalue" + # + # set_cookie_header("myname", {value: "myvalue", max_age: 10}) + # # => "myname=myvalue; max-age=10" + # def set_cookie_header(key, value) case value when Hash @@ -278,12 +317,21 @@ module Rack else key = escape(key) end + value = [value] unless Array === value return "#{key}=#{value.map { |v| escape v }.join('&')}#{domain}" \ "#{path}#{max_age}#{expires}#{secure}#{httponly}#{same_site}" end + # :call-seq: + # set_cookie_header!(headers, key, value) -> header value + # + # Append a cookie in the specified headers with the given cookie +key+ and + # +value+ using set_cookie_header. + # + # If the headers already contains a +set-cookie+ key, it will be converted + # to an +Array+ if not already, and appended to. def set_cookie_header!(headers, key, value) if header = headers[SET_COOKIE] if header.is_a?(Array) @@ -296,8 +344,20 @@ module Rack end end - # Adds a cookie that will *remove* a cookie from the client. Hence the - # strange method name. + # :call-seq: + # delete_set_cookie_header(key, value = {}) -> encoded string + # + # Generate an encoded string based on the given +key+ and +value+ using + # set_cookie_header for the purpose of causing the specified cookie to be + # deleted. The +value+ may be an instance of +Hash+ and can include + # attributes as outlined by set_cookie_header. The encoded cookie will have + # a +max_age+ of 0 seconds, an +expires+ date in the past and an empty + # +value+. When used with the +set-cookie+ header, it will cause the client + # to *remove* any matching cookie. + # + # delete_set_cookie_header("myname") + # # => "myname=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT" + # def delete_set_cookie_header(key, value = {}) set_cookie_header(key, { value: '', path: nil, domain: nil, @@ -324,6 +384,24 @@ module Rack delete_set_cookie_header!(header, key, value) end + # :call-seq: + # delete_set_cookie_header!(header, key, value = {}) -> header value + # + # Set an expired cookie in the specified headers with the given cookie + # +key+ and +value+ using delete_set_cookie_header. This causes + # the client to immediately delete the specified cookie. + # + # delete_set_cookie_header!(nil, "mycookie") + # # => "mycookie=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT" + # + # If the header is non-nil, it will be modified in place. + # + # header = [] + # delete_set_cookie_header!(header, "mycookie") + # # => ["mycookie=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT"] + # header + # # => ["mycookie=; max-age=0; expires=Thu, 01 Jan 1970 00:00:00 GMT"] + # def delete_set_cookie_header!(header, key, value = {}) if header header = Array(header) |