Skip to content
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

Closed
wants to merge 6 commits into from
Closed

Fix bug in handling of invalid if-modified-since/last-modified values #23

wants to merge 6 commits into from

Conversation

benurb
Copy link
Contributor

@benurb benurb commented Jul 19, 2017

Hi @dougwilson

thanks for this very useful lib, but unfortunately I found two little bugs.

  1. The tests for invalid values in if-modified-since/last-modified were broken and therefore covering up ...
  2. a actual bug in the handling of invalid values in if-modified-since headers.
    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

@benurb benurb changed the title Fix/invalid modified since handling Fix bug in handling of invalid if-modified-since/last-modified values Jul 19, 2017
Copy link
Contributor

@dougwilson dougwilson left a 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

:(

@dougwilson dougwilson added the pr label Jul 19, 2017
@benurb
Copy link
Contributor Author

benurb commented Jul 20, 2017

Oh, ok. Didn't know about the Date.parse problem. What solution do you prefer?
One "long" short circuit clause?

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

@dougwilson
Copy link
Contributor

Neither of them seem to work correctly for the one date / time in which Date.parse returns 0 (unix epoch).

@benurb
Copy link
Contributor Author

benurb commented Jul 21, 2017

Hey @dougwilson,
yep, you're right. I've change the code a bit and added tests for all the edge cases you mentioned.

test/fresh.js Outdated
})
})

describe('with earliest possible If-Modified-Since date', function () {
Copy link
Contributor

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".

Copy link
Contributor Author

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 () {
Copy link
Contributor

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.

Copy link
Contributor Author

@benurb benurb Jul 21, 2017

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?

Copy link
Contributor

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).

Copy link
Contributor Author

@benurb benurb Jul 24, 2017

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.

@benurb
Copy link
Contributor Author

benurb commented Jul 24, 2017

Hi @dougwilson
I addressed your comments. Let me know what you think 👍

@benurb
Copy link
Contributor Author

benurb commented Aug 3, 2017

Hey @dougwilson
any additional thoughs on this PR?

@dougwilson
Copy link
Contributor

Hi @benurb I'm really sorry I let this fall though, truly sorry. I just got it merged in now.

@dougwilson dougwilson self-assigned this Sep 12, 2017
@dougwilson dougwilson added the bug label Sep 12, 2017
dougwilson pushed a commit that referenced this pull request Sep 12, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants