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

Optional cookie validation #68

Merged

Conversation

ajgarlag
Copy link
Contributor

@ajgarlag ajgarlag commented Dec 22, 2016

Q A
Bug fix? no
New feature? yes
BC breaks? no
Deprecations? no
Related tickets fixes #67
License MIT

What's in this PR?

This PR adds optional cookie validation

Example Usage

TBD

Checklist

  • Updated CHANGELOG.md to describe BC breaks / deprecations | new feature | bugfix
  • Documentation pull request created (if not simply a bugfix)

To Do

  • Discuss how to avoid current cookie constructor validation: additional flag parameter or using ReflectionClass::newInstanceWithoutConstructor

@ajgarlag ajgarlag force-pushed the create-cookies-without-validation branch 2 times, most recently from e656ae8 to d6e6ec8 Compare December 22, 2016 22:22
@ajgarlag
Copy link
Contributor Author

I've implemented it with an additional __construct parameter.

Maybe, we can rename createWithoutValidation to create and deprecate __construct making it private in 2.0

What do you think?

@@ -73,11 +81,16 @@ public function __construct(
$path = null,
$secure = false,
$httpOnly = false,
\DateTime $expires = null
\DateTime $expires = null,
$requireValidation = true
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't really like the idea of having optional validation. Have it or not IMO. So I would just deprecate the exception and bypass the validation manually.

$httpOnly = false,
\DateTime $expires = null
) {
return new self($name, $value, $maxAge, $domain, $path, $secure, $httpOnly, $expires, false);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would do some hacks here: pass null or the valid empty value to bypass the validation, then set the property directly. Since we are in the same class, we can set private properties.

*/
public function isValid()
{
if (null === $this->valid) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hm, not sure about this. This value should be cleared at least when the value or the max age is "modified", but even then I am not sure the performance gain worth risking inconsistency.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You are right, I'll remove this.

@@ -63,7 +63,7 @@
* @param bool $httpOnly
* @param \DateTime|null $expires Expires attribute is HTTP 1.0 only and should be avoided.
*
* @throws \InvalidArgumentException If name, value or max age is not valid.
* @throws \InvalidArgumentException If name, value or max age is not valid. Attributes validation during instantiation is deprecated since 1.5 and will be removed in 2.0.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should be "Attribute validation"

@@ -89,6 +94,24 @@ public function __construct(
$this->httpOnly = (bool) $httpOnly;
}

public static function createWithoutValidation(
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you please add phpdoc?

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should this be deprecated as well? That would be weird, but still...

}

/**
* @dataProvider invalidCharacterExamples
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure if we want to test the fact that validation actually works correctly here. Although I can't really see any tests for that. Nevertheless I think we only need to test two cases here: validation passes/validation fails. For that I am not sure if we need data provider. In fact using data providers in specification tests is kind of abusing BDD, these kind of tests should be done in separate unit tests.

@sagikazarmark
Copy link
Member

@php-http/owners can you add some input here?

Copy link
Member

@Nyholm Nyholm left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like the idea of a createWithoutValidation and isValid. I see from your issue why they are needed.

I do not think we should disable validation in the constructor though. Because normally when you are creating a Cookie you want to make sure it is a valid object. Currently dev-master makes sure you never have an invalid object with is a good thing and it should be the default behavior.

@sagikazarmark
Copy link
Member

I do not think we should disable validation in the constructor though

My only concern is that the current way is a little bit hacky. Also, maybe we could make this a configuration in CookieJar (whether to check cookie validation or not)

@sagikazarmark
Copy link
Member

This looks good to me. Is there anything else @Nyholm ?

@ajgarlag can you please rebase your branch?

@Nyholm
Copy link
Member

Nyholm commented Jan 14, 2017

Im happy with the current state of this PR. Thanks!

@ajgarlag ajgarlag force-pushed the create-cookies-without-validation branch from fb1ac8e to 5eeecd1 Compare January 18, 2017 07:52
@ajgarlag
Copy link
Contributor Author

Rebased. Sorry for the delay.

@sagikazarmark
Copy link
Member

sagikazarmark commented Jan 18, 2017

Does this require a follow up PR in the common-client repo to solve the original issue? Any last words @php-http/owners before merging?

@ajgarlag
Copy link
Contributor Author

I'll add a $requireValidCookies flag (true by default) to CookieJar and then, validate each cookie when is added to CookieJar. Then, in the common-client repo, I will always use createWithoutValidation to create the cookie object, although, I think this could be a BC in common-client.

@Nyholm
Copy link
Member

Nyholm commented Jan 19, 2017

I think this could be a BC in common-client

It has to be =)

I do not think the CookieJar should care about if the cookies are valid or not. The Jar is just a storage, it should be pretty stupid.

I agree with you that the CookiePlugin should always use createWithoutValidation. Depending on configuration of the CookiePlugin, we validate the cookies before we put them in the jar. That is BC.

👍 for merging this PR now.

@ajgarlag
Copy link
Contributor Author

I agree with you that the CookiePlugin should always use createWithoutValidation.

As this the method that should be used always by CookiePlugin, I proposed:

Maybe, we can rename createWithoutValidation to create and deprecate __construct making it private in 2.0

@Nyholm
Copy link
Member

Nyholm commented Jan 19, 2017

I know. But making the constructor private would be a BC break. And we are doing it just because "one class in a other library stopped using the constructor". That is wrong. Also if we created (though unlikely) a AlwaysValidCookiePlugin, that class would use the constructor.

@Nyholm
Copy link
Member

Nyholm commented Feb 12, 2017

Good to merge?

@Nyholm Nyholm mentioned this pull request Feb 12, 2017
@sagikazarmark
Copy link
Member

Sorry for the long wait, thanks for the contribution @ajgarlag

@sagikazarmark sagikazarmark merged commit 72d7e28 into php-http:master Feb 13, 2017
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Optional cookie validation
3 participants