Conversation
spec/std/http/cookie_spec.cr
Outdated
| delta.should be > 9.seconds | ||
| delta.should be < 11.seconds | ||
| delta = cookie.max_age | ||
| delta.should eq 10.seconds |
There was a problem hiding this comment.
you could skip delta intermediary variable altogether since there's one call only.
spec/std/http/cookie_spec.cr
Outdated
| delta.should be > 0.seconds | ||
| delta.should be < 1.seconds | ||
| delta = cookie.max_age | ||
| delta.should eq 0.seconds |
src/http/cookie.cr
Outdated
| end | ||
|
|
||
| # Returns the `Time` at which this cookie will expire, or `nil` if it will not expire. | ||
| # Uses *max-age* and *expires* values to ccalculate the time. |
spec/std/http/cookie_spec.cr
Outdated
|
|
||
| describe "expiration_time" do | ||
| it "by max-age=0" do | ||
| c = parse_set_cookie("bla=1; max-age=0") |
spec/std/http/cookie_spec.cr
Outdated
| end | ||
|
|
||
| it "by old date" do | ||
| c = parse_set_cookie("bla=1; expires=Thu, 01 Jan 1970 00:00:00 -0000") |
src/http/cookie.cr
Outdated
| # Returns the `Time` at which this cookie will expire, or `nil` if it will not expire. | ||
| # Uses *max-age* and *expires* values to calculate the time. | ||
| def expiration_time | ||
| ma = @max_age |
src/http/cookie.cr
Outdated
| # Uses *max-age* and *expires* values to calculate the time. | ||
| def expiration_time | ||
| ma = @max_age | ||
| ex = @expires |
src/http/cookie.cr
Outdated
| def expired? | ||
| if e = expires | ||
| e < Time.now | ||
| ma = @max_age |
src/http/cookie.cr
Outdated
| if e = expires | ||
| e < Time.now | ||
| ma = @max_age | ||
| ex = @expires |
| parse_time(match["expires"]?) | ||
| end | ||
| expires = parse_time(match["expires"]?) | ||
| max_age = match["max_age"]? ? match["max_age"].to_i.seconds : nil |
There was a problem hiding this comment.
max_age = match["max_age"]?.try(&.to_i.seconds)There was a problem hiding this comment.
This suggestion seems better than the current code.
spec/std/http/cookie_spec.cr
Outdated
| describe "expiration_time" do | ||
| it "by max-age=0" do | ||
| cookie = parse_set_cookie("bla=1; max-age=0") | ||
| (cookie.expiration_time.not_nil! <= (Time.now + 1.seconds)).should eq true |
There was a problem hiding this comment.
eq true should be written as be_true in all specs.
And the tested value is probably better understandable as Time.now - cookie.expiration_time <= 1.seconds
spec/std/http/cookie_spec.cr
Outdated
| end | ||
|
|
||
| it "not expired" do | ||
| (parse_set_cookie("bla=1; max-age=1").expiration_time.not_nil! > Time.now).should eq true |
There was a problem hiding this comment.
Please use a cookie variable like in the other examples. This makes it better readable.
The same goes for the following specs.
spec/std/http/cookie_spec.cr
Outdated
| cookie.expiration_time.should eq Time.new(1970, 1, 1, 0, 0, 0) | ||
| end | ||
|
|
||
| it "not expired" do |
There was a problem hiding this comment.
It would be great to add more detail to the spec name, e.g. with max-age
spec/std/http/cookie_spec.cr
Outdated
| (parse_set_cookie("bla=1; max-age=1").expiration_time.not_nil! > Time.now).should eq true | ||
| end | ||
|
|
||
| it "not expired" do |
There was a problem hiding this comment.
It would be great to add more detail to the spec name, e.g. with expires
spec/std/http/cookie_spec.cr
Outdated
| (parse_set_cookie("bla=1; expires=Thu, 01 Jan 2020 00:00:00 -0000").expiration_time.not_nil! >= Time.new(2020, 1, 1, 0, 0, 0)).should eq true | ||
| end | ||
|
|
||
| it "not expired" do |
There was a problem hiding this comment.
It would be great to add more detail to the spec name, e.g. without expiration
spec/std/http/cookie_spec.cr
Outdated
| end | ||
|
|
||
| it "not expired" do | ||
| parse_set_cookie("bla=1").expiration_time.should eq nil |
src/http/cookie.cr
Outdated
| property secure : Bool | ||
| property http_only : Bool | ||
| property extension : String? | ||
| property creation_time : Time |
There was a problem hiding this comment.
I don't think it makes sense to have creation_time writable, and I'm not sure if it should even be readable externally.
To have a customizeable time reference, I would rather add an optional argument to expiration_time and expired?. It could be called current_time or time_reference. That would be a better API, because you don't need to change the Cookie's internal data to check its expiration at a certain point of time.
There was a problem hiding this comment.
I think I set this up as you described, though I'm happy to rewrite. I added tests for using reference_time in specs as well, though the spec naming may be too verbose.
There was a problem hiding this comment.
Looks good!
However on a second thought, it would probably make sense to have creation_time readable just to be transparent about it. And I'd also suggest to add creation_time as an optional named parameter to initialize. This allows for time-independent testing as well as (re-)creating a Cookie instance which was retrieved at a different point in time, maybe for serialization.
I think it makes generally sense to allow all references to Time.new to be replaced with an optional parameter. So maybe even expired? should get a second, optional named parameter...
src/http/cookie.cr
Outdated
| # Returns the `Time` at which this cookie will expire, or `nil` if it will not expire. | ||
| # Uses *max-age* and *expires* values to calculate the time. | ||
| def expiration_time | ||
| max_age = @max_age |
There was a problem hiding this comment.
I'd suggest to move the variable assignment into the condition.
The elsif branch is unnecessary because @expires is either nil or Time and this is what this method returns.
if max_age = @max_age
creation_time + max_age
else
@expires
end
src/http/cookie.cr
Outdated
| def expired? | ||
| if e = expires | ||
| e < Time.now | ||
| max_age = @max_age |
There was a problem hiding this comment.
This method has duplicated code from expiration_time and should use that method instead. This way it becomes very simple:
@max_age == 0.seconds || expiration_time.try &.<(Time.now) || false
src/http/cookie.cr
Outdated
| elsif expires | ||
| expires | ||
| # By default, this function uses the creation time of this cookie as the offset for max-age, if max-age is set. | ||
| # To use a different offset, provide a `Time` object to *time_Reference*. |
There was a problem hiding this comment.
Just a small typo: time_reference
spec/std/http/cookie_spec.cr
Outdated
| describe "expiration_time" do | ||
| it "sets expiration_time to be current when max-age=0" do | ||
| cookie = parse_set_cookie("bla=1; max-age=0") | ||
| (Time.now - cookie.expiration_time.not_nil! <= 1.seconds).should be_true |
There was a problem hiding this comment.
This could even be written (Time.now - cookie.expiration_time.not_nil!).should be.<= 1.seconds
I just learned about this ;)
spec/std/http/cookie_spec.cr
Outdated
| describe "expiration_time" do | ||
| it "sets expiration_time to be current when max-age=0" do | ||
| cookie = parse_set_cookie("bla=1; max-age=0") | ||
| (Time.now - cookie.expiration_time.not_nil!).should be.<= 1.seconds |
There was a problem hiding this comment.
I'm really sorry that I my suggestion was a bit inprecise. 😢 I don't know why I assumed the period to be necessary...
be <= 1.seconds works as well and reads much better.
There was a problem hiding this comment.
Will fix. No problem; I could have looked through more docs myself.
|
Great work! Unfortunately, I was misleading you about the proper syntax for comparison expectations. Sorry about that :/ |
| header << "; domain=#{domain}" if domain | ||
| header << "; path=#{path}" if path | ||
| header << "; expires=#{HTTP.rfc1123_date(expires)}" if expires | ||
| header << "; max-age=#{max_age.total_seconds}" if max_age |
There was a problem hiding this comment.
I think + is preferred in string concatenation.
before:
header << "; max-age=#{max_age.total_seconds}" if max_ageafter:
header << "; max-age=" + max_age.total_seconds if max_ageThere was a problem hiding this comment.
Seems like the rest of the headers are in the other style so this is not a change is not necessary with this PR.
There was a problem hiding this comment.
No, + is discouraged. Maybe << would be slightly faster, but interpolation is totally fine.
There was a problem hiding this comment.
In that case this is good.
|
@bmmcginty what is the status on this PR? I am just curious it looks pretty good to me. |
74f9181 to
e2e9b28
Compare
src/http/cookie.cr
Outdated
| end | ||
|
|
||
| def expired?(time_reference = @creation_time) | ||
| @max_age == 0.seconds || expiration_time(time_reference).try &.<(Time.now) || false |
There was a problem hiding this comment.
Why || false?
I'd prefer
time = expiration_time(time_reference)
@max_age == 0.seconds || (time && time < Time.now)There was a problem hiding this comment.
@max_age == 0.seconds || (time = expiration_time(time_reference) && time < Time.now)Avoids calculation of expiration_time if the first condition is already true.
src/http/cookie.cr
Outdated
| header << "; expires=#{HTTP.rfc1123_date(expires)}" if expires | ||
| header << "; max-age=#{max_age.total_seconds}" if max_age | ||
| header << "; expires=#{HTTP.format_time(expires)}" if expires | ||
| xheader << "; max-age=#{max_age.total_seconds}" if max_age |
|
Typo. Should be corrected by the latest push.
…On Fri, Jun 15, 2018 at 07:27:07AM -0700, Sijawusz Pur Rahnama wrote:
***@***.***** commented on this pull request.
----
In
[src/http/cookie.cr](http://go.bmcginty.us/213788)
:
> @@ -35,8 +35,8 @@ module HTTP
header << "#{URI.escape @name}=#{URI.escape value}"
header << "; domain=#{domain}" if domain
header << "; path=#{path}" if path
- header << "; expires=#{HTTP.rfc1123_date(expires)}" if expires
- header << "; max-age=#{max_age.total_seconds}" if max_age
+ header << "; expires=#{HTTP.format_time(expires)}" if expires
+ xheader << "; max-age=#{max_age.total_seconds}" if max_age
xheader
?
—
You are receiving this because you were mentioned.
Reply to this email directly,
[view it on GitHub](http://go.bmcginty.us/213787)
, or
[mute the thread](http://go.bmcginty.us/213789)
.![]
|
| end | ||
| end | ||
|
|
||
| # returns the expiration status of this cookie as a `Bool` given a creation time |
There was a problem hiding this comment.
Returns true if this cookie is expired.
Uses max-age and expires values to calculate the time.
By default, this function uses the creation time of this cookie as the offset for max-age, if max-age is set.
To use a different offset, provide aTimeobject to time_reference.
fc8c27e to
354bc8c
Compare
|
I'd like to say this has been rebased to match the master branch. At this point, though, I haven't a clue. |
|
It seems like you lost the specs and some code in |
|
@bmmcginty ac6a53e could be a recovery starting point. |
354bc8c to
aae5f30
Compare
|
Closed in favour of #7925 |
As mentioned in #5033, this PR adds consistent handling for the expires parameter for cookies. It changes #expires to #expiration_time and allows #expires to act as a property for the expires parameter. It also adds #max_age to allow access to the max-age parameter. Finally, documentation has been added for #expiration_time.