diff --git a/examples/cookies-hmac/cookie.ru b/examples/cookies-hmac/cookie.ru new file mode 100644 index 0000000..96e3706 --- /dev/null +++ b/examples/cookies-hmac/cookie.ru @@ -0,0 +1,27 @@ +# frozen_string_literal: true + +$LOAD_PATH.unshift("#{File.dirname(__FILE__)}/lib") +require 'securerandom' +require 'landline' +require 'landline/util/cookie' +require 'irb' + +KEY = SecureRandom.base64(64).freeze + +app = Landline::Server.new do + get "/set-cookie" do + cookie "test", (rand * 500).floor.to_s, { hmac: KEY } + header "content-type", "text/plain" + "Cookie set! Visit /get-cookie to view it" + end + get "/get-cookie" do + header "content-type", "text/plain" + if request.cookies.dig('test', 0)&.verify(KEY) + "Cookie is valid and generated by server" + else + "Cookie either doesn't exist or is forged" + end + end +end + +run app diff --git a/examples/cookies-hmac/lib b/examples/cookies-hmac/lib new file mode 120000 index 0000000..58677dd --- /dev/null +++ b/examples/cookies-hmac/lib @@ -0,0 +1 @@ +../../lib \ No newline at end of file diff --git a/examples/cookies-hmac/readme.txt b/examples/cookies-hmac/readme.txt new file mode 100644 index 0000000..a8501aa --- /dev/null +++ b/examples/cookies-hmac/readme.txt @@ -0,0 +1,3 @@ +shows basic usage of unsigned cookies + +please note that this does not sign cookies. diff --git a/lib/landline/response.rb b/lib/landline/response.rb index f1718b4..212d99c 100644 --- a/lib/landline/response.rb +++ b/lib/landline/response.rb @@ -26,7 +26,7 @@ module Landline def finalize @cookies.each do |_, cookie_array| cookie_array.each do |cookie| - add_header("set-cookie", cookie.to_s) + add_header("set-cookie", cookie.finalize) end end [@status, @headers, @body] diff --git a/lib/landline/util/cookie.rb b/lib/landline/util/cookie.rb index 70467b4..e83ef3e 100644 --- a/lib/landline/util/cookie.rb +++ b/lib/landline/util/cookie.rb @@ -44,7 +44,7 @@ module Landline # Convert cookie to "Set-Cookie: " string representation. # @return [String] - def to_s + def finalize sign(@hmac, algorithm: @algorithm, sep: @sep) if @hmac ParserCommon.make_value( "#{key.to_s.strip}=#{value.to_s.strip}", @@ -62,7 +62,8 @@ module Landline # Convert cookie to "Cookie: " string representation (no params) # @return [String] - def to_short + def finalize_short + sign(@hmac, algorithm: @algorithm, sep: @sep) if @hmac "#{key.to_s.strip}=#{value.to_s.strip}" end @@ -103,6 +104,8 @@ module Landline # @return [Hash{String => Cookie}] def self.from_cookie_string(data) hash = {} + return hash if data.nil? + data.split(";").map do |cookiestr| key, value = cookiestr.match(/([^=]+)=?(.*)/).to_a[1..].map(&:strip) cookie = Cookie.new(key, value)