-
Notifications
You must be signed in to change notification settings - Fork 29
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Fix bug in handling of invalid if-modified-since/last-modified values #23
Fix bug in handling of invalid if-modified-since/last-modified values #23
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Wow, thanks! What a goof :) The PR should just be tweaked a bit to handle the fact that a very popular library, datejs, overwrites Date.parse
and actually returns just a falsy-value instead of NaN
on a date parse failure. This causes isNaN
to have the opposite value of what it should, which could lead to 304 responses when that was not appropriate.
I'm only aware of this because a while back a release of a related library started using isNaN
checks on the result of Date.parse
and it turns into a Whole Thing(TM) and so I modified many libraries, like this one, to still function correctly as long as the result of Date.parse
was any falsy value.
This new logic will cause those users to start getting unconditional 304 responses in normal usage. For example if a the last modified and modified since are both empty, you would expect this to be isNaN(NaN) || isNaN(NaN) || NaN > NaN
which results in true
, but under datejs, that line is actually isNaN(null) || isNaN(null) || null > null
which results in false
:(
Oh, ok. Didn't know about the var lastModifiedTimestamp = Date.parse(resHeaders['last-modified'])
var modifiedSinceTimestamp = Date.parse(modifiedSince)
var modifiedStale = !lastModifiedTimestamp || isNaN(lastModifiedTimestamp) ||
!modifiedSinceTimestamp || isNaN(modifiedSinceTimestamp) ||
!lastModifiedTimestamp > modifiedSinceTimestamp Or two "short" short circuits? var lastModifiedTimestamp = Date.parse(resHeaders['last-modified']) || NaN
var modifiedSinceTimestamp = Date.parse(modifiedSince) || NaN
var modifiedStale = isNaN(lastModifiedTimestamp) || isNaN(modifiedSinceTimestamp) ||
lastModifiedTimestamp > modifiedSinceTimestamp |
Neither of them seem to work correctly for the one date / time in which Date.parse returns 0 (unix epoch). |
Hey @dougwilson, |
test/fresh.js
Outdated
}) | ||
}) | ||
|
||
describe('with earliest possible If-Modified-Since date', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure if this makes sense, because you can use earlier dates / times, so not sure why this is the "earliest possible".
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah you're right. I'll change that to something like 'with unix epoch in If-Modified-Since', ok?
}) | ||
}) | ||
|
||
describe('when Date.parse was monkey patched', function () { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If this is going to actually have a test, just test with what we really care about specifically: the datejs patching.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Mhh ok. I haven't had a look at datejs yet, but do you suggest adding it as a devDependency or rather make the mock more similar to the datejs patching? Or are these tests a bad idea in general?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A devDep is just fine, as they are available during the testing. If you want to just not have any tests, that's OK too, but if you wanted to make some patching tests, I'd say to either (a) directly use datejs in them or (b) make the mocking patches actually function like the datejs does (which afaik these are different from what datejs returns).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I was not able to use datejs without polluting global objects, but I updated the mock to return the same result as datejs for the strings in the tests. If you don't like this I would rather remove the tests again.
Hi @dougwilson |
Hey @dougwilson |
Hi @benurb I'm really sorry I let this fall though, truly sorry. I just got it merged in now. |
Hi @dougwilson
thanks for this very useful lib, but unfortunately I found two little bugs.
I split up the changes in two commits so it's easier for you the reproduce the behavior. With only the test changes applied you can see that one test is actually failing and with both commits applied all tests should be green again 👍
Best regards,
Ben