Skip to content

Commit

Permalink
Merge pull request #215 from jeremykendall/develop
Browse files Browse the repository at this point in the history
Prepare 5.2 release
  • Loading branch information
nyamsprod authored Feb 23, 2018
2 parents 2f2c542 + 758dfa2 commit fa7937a
Show file tree
Hide file tree
Showing 22 changed files with 776 additions and 240 deletions.
21 changes: 11 additions & 10 deletions .gitattributes
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
* text=auto

/.editorconfig export-ignore
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/.php_cs export-ignore
/.travis.yml export-ignore
/README.md export-ignore
/CHANGELOG.md export-ignore
/phpunit.xml.dist export-ignore
/tests export-ignore
/.editorconfig export-ignore
/.gitattributes export-ignore
/.github export-ignore
/.gitignore export-ignore
/.php_cs export-ignore
/.phpstan.src.neon export-ignore
/.phpstan.tests.neon export-ignore
/.travis.yml export-ignore
/README.md export-ignore
/phpunit.xml.dist export-ignore
/tests export-ignore
12 changes: 6 additions & 6 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,13 @@ sudo: false
matrix:
include:
- php: 7.0
env: COLLECT_COVERAGE=true VALIDATE_CODING_STYLE=true IGNORE_PLATFORMS=false
env: VALIDATE_CODING_STYLE=false RUN_PHPSTAN=false IGNORE_PLATFORMS=false
- php: 7.1
env: COLLECT_COVERAGE=true VALIDATE_CODING_STYLE=true IGNORE_PLATFORMS=false
env: VALIDATE_CODING_STYLE=false RUN_PHPSTAN=false IGNORE_PLATFORMS=false
- php: 7.2
env: COLLECT_COVERAGE=false VALIDATE_CODING_STYLE=false IGNORE_PLATFORMS=true
env: VALIDATE_CODING_STYLE=true RUN_PHPSTAN=true IGNORE_PLATFORMS=false
- php: nightly
env: COLLECT_COVERAGE=false VALIDATE_CODING_STYLE=false IGNORE_PLATFORMS=true
env: VALIDATE_CODING_STYLE=false RUN_PHPSTAN=false IGNORE_PLATFORMS=true
allow_failures:
- php: nightly
fast_finish: true
Expand All @@ -31,5 +31,5 @@ script:
- composer phpunit

after_script:
- if [ "$COLLECT_COVERAGE" == "true" ]; then wget https://scrutinizer-ci.com/ocular.phar && php ocular.phar code-coverage:upload --format=php-clover build/clover.xml; fi
- if [ "$VALIDATE_CODING_STYLE" == "true" ]; then composer phpcs; fi
- if [ "$VALIDATE_CODING_STYLE" == "true" ]; then composer phpcs; fi
- if [ "$RUN_PHPSTAN" == "true" ]; then composer phpstan; fi
28 changes: 27 additions & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,32 @@
# Changelog

All Notable changes to `PHP Domain Parser` will be documented in this file
All Notable changes to `PHP Domain Parser` **5.x** series will be documented in this file

## 5.2.0 - 2018-02-23

### Added

- `Pdp\Rules::getPublicSuffix` returns a `Pdp\PublicSuffix` value object
- `Pdp\Rules::__set_state` is implemented
- `Pdp\Domain::toUnicode` returns a `Pdp\Domain` with its value converted to its Unicode form
- `Pdp\Domain::toAscii` returns a `Pdp\Domain` with its value converted to its AScii form
- `Pdp\PublicSuffix::toUnicode` returns a `Pdp\PublicSuffix` with its value converted to its Unicode form
- `Pdp\PublicSuffix::toAscii` returns a `Pdp\PublicSuffix` with its value converted to its AScii form

### Fixed

- `Pdp\Domain::getDomain` returns the normalized form of the domain name
- `Pdp\PublicSuffix` is no longer internal.
- Normalizes IDN conversion using a internal `IDNConverterTrait`
- Internal code improved by requiring PHPStan for development

### Deprecated

- None

### Removed

- None

## 5.1.0 - 2017-12-18

Expand Down
130 changes: 83 additions & 47 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,6 @@ System Requirements
You need:

- **PHP >= 7.0** but the latest stable version of PHP is recommended
- the `mbstring` extension
- the `intl` extension

Dependencies
Expand All @@ -48,27 +47,7 @@ Documentation

### Domain name resolution

In order to resolve a domain name one we must:

- Convert the Public Suffix List (PSL) into a structure usable in PHP
- Resolve the domain name against the PSL rules

PSL Conversion is done using the `Pdp\Converter` class.

~~~php
<?php

namespace Pdp;

final class Converter
{
public function convert(string $content): array
}
~~~

The `Pdp\Converter::convert` method expects the raw content of a PSL and returns its `array` representation.

Once the PSL has been converted we can used the returned `array` to instantiate a `Pdp\Rules` object which is responsable for resolving a given domain name.
The `Pdp\Rules` object is responsible for domain name resolution.

~~~php
<?php
Expand All @@ -84,21 +63,26 @@ final class Rules
public static function createFromPath(string $path, $context = null): self
public static function createFromString(string $content): self
public function __construct(array $rules)
public function getPublicSuffix(string $domain = null, string $section = self::ALL_DOMAINS): PublicSuffix
public function resolve(string $domain = null, string $section = self::ALL_DOMAINS): Domain
}
~~~

Starting with version 5.1.0, the following named constructors arre added to ease `Rules` instantiation.
**NEW IN VERSION 5.2:**

- `Rules::createFromString` expects a string content which follows [the PSL format](https://publicsuffix.org/list/#list-format);
- `Rules::getPublicSuffix` returns a `PublicSuffix` object determined from the `Rules` object;

**NEW IN VERSION 5.1:**

- `Rules::createFromString` expects a string content which follows [the PSL format](https://publicsuffix.org/list/#list-format);
- `Rules::createFromPath` expects a valid path to a readable PSL. You can optionnally submit a context resource as defined in PHP's `fopen` function;

Both named constructors:

- uses internally a `Pdp\Converter` object to convert the raw content into a suitable array to instantiate a valid `Pdp\Rules`;
- do not have any cache functionnality;

#### Usage

Domain name resolution is done using the `Pdp\Rules::resolve` method which expects at most two parameters:

Expand All @@ -108,9 +92,7 @@ Domain name resolution is done using the `Pdp\Rules::resolve` method which expec
- `Rules::ICANN_DOMAINS`, to validate against the PSL ICANN DOMAINS section only.
- `Rules::PRIVATE_DOMAINS`, to validate against the PSL PRIVATE DOMAINS section only.

By default, the `$section` argument is equal to `Rules::ALL_DOMAINS`. If an unsupported section is submitted a `Pdp\Exception` exception will be thrown.

**WARNING: The `Pdp\Rules::resolve` does not validate the submitted host. You are require to use a host validator prior to using this library.**
By default, the `$section` argument is equal to `Rules::ALL_DOMAINS`. If an unsupported section is submitted a `Pdp\Exception` exception will be thrown.

The `Pdp\Rules::resolve` returns a `Pdp\Domain` object.

Expand All @@ -126,34 +108,29 @@ final class Domain implements JsonSerializable
public function isKnown(): bool;
public function isICANN(): bool;
public function isPrivate(): bool;
public function toUnicode(): self;
public function toAscii(): self;
}
~~~

The `Pdp\Domain` getter methods returns:

- the submitted domain name using `Pdp\Domain::getDomain`
- the public suffix part normalized according to the domain using `Pdp\Domain::getPublicSuffix`
- the registrable domain part using `Pdp\Domain::getRegistrableDomain`
- the subdomain part using `Pdp\Domain::getSubDomain`.

If the domain name or some of its part are seriously malformed or unrecognized, the getter methods will return `null`.
**NEW IN VERSION 5.2:**

**The Domain name status depends on the PSL section used to resolve it:**

- `Pdp\Domain::isKnown` returns `true` if the public suffix is found in the selected PSL;
- `Pdp\Domain::isICANN` returns `true` if the public suffix is found in a selected PSL which includes the ICANN DOMAINS section;
- `Pdp\Domain::isPrivate` returns `true` if the public suffix is found in a selected PSL which includes the PRIVATE DOMAINS section;
- `Domain::toUnicode` returns an instance with the domain converted to its unicode representation;
- `Domain::toAscii` returns an instance with the domain converted to its ascii representation;
- `Domain::getDomain` will lowercase the domain name to normalize its content;

**THIS EXAMPLE ILLUSTRATES HOW EACH OBJECT IS USED BUT SHOULD BE AVOID IN PRODUCTON**
**THIS EXAMPLE ILLUSTRATES HOW THE OBJECT WORK BUT SHOULD BE AVOIDED IN PRODUCTON**

~~~php
<?php

use Pdp\Rules;
use Pdp\Converter;

$rules = Rules::createFromPath('https://raw.githubusercontent.com/publicsuffix/list/master/public_suffix_list.dat');
$pdp_url = 'https://raw.githubusercontent.com/publicsuffix/list/master/public_suffix_list.dat';
$rules = Rules::createFromPath($pdp_url);

$domain = $rules->resolve('www.ulb.ac.be'); //using Rules::ALL_DOMAINS
$domain = $rules->resolve('www.Ulb.AC.be'); //using Rules::ALL_DOMAINS
$domain->getDomain(); //returns 'www.ulb.ac.be'
$domain->getPublicSuffix(); //returns 'ac.be'
$domain->getRegistrableDomain(); //returns 'ulb.ac.be'
Expand All @@ -175,7 +152,7 @@ echo json_encode($domain, JSON_PRETTY_PRINT);

//The same domain will yield a different result using the PSL PRIVATE DOMAIN SECTION only

$domain = $rules->resolve('www.ulb.ac.be', Rules::PRIVATE_DOMAINS);
$domain = $rules->resolve('www.Ulb.AC.be', Rules::PRIVATE_DOMAINS);
echo json_encode($domain, JSON_PRETTY_PRINT);
// returns
// {
Expand All @@ -189,11 +166,49 @@ echo json_encode($domain, JSON_PRETTY_PRINT);
// }
~~~

The `Pdp\Domain` getter methods returns:

- the submitted domain name using `Pdp\Domain::getDomain`
- the public suffix part normalized according to the domain using `Pdp\Domain::getPublicSuffix`
- the registrable domain part using `Pdp\Domain::getRegistrableDomain`
- the subdomain part using `Pdp\Domain::getSubDomain`.

If the domain name or some of its part are seriously malformed or unrecognized, the getter methods will return `null`.

**The Domain name status depends on the PSL section used to resolve it:**

- `Pdp\Domain::isKnown` returns `true` if the public suffix is found in the selected PSL;
- `Pdp\Domain::isICANN` returns `true` if the public suffix is found using a PSL which includes the ICANN DOMAINS section;
- `Pdp\Domain::isPrivate` returns `true` if the public suffix is found using a PSL which includes the PRIVATE DOMAINS section;

The `Rules::getPublicSuffix` method expects the same arguments as `Rules::resolve` but returns a `Pdp\PublicSuffix` object instead.

~~~php
<?php

final class PublicSuffix implements Countable, JsonSerializable
{
public function getContent(): ?string
public function isKnown(): bool;
public function isICANN(): bool;
public function isPrivate(): bool;
public function toUnicode(): self;
public function toAscii(): self;
}
~~~

While `Rules::resolve` will only throws an exception if the section value is invalid, the `Rules::getPublicSuffix` is more restrictive and will additionnally throw if:

- The domain name is invalid or seriously malformed
- The public suffix can not be normalized and converted using the domain encoding.

**WARNING:**

**The `Pdp\Rules::resolve` does not validate the submitted host. You are require to use a host validator prior to using this library.**

**You should never use the library this way in production, without, at least, a caching mechanism to reduce PSL downloads.**

**Some people use the PSL to determine what is a valid domain name and what isn't. This is dangerous, particularly in these days where new gTLDs are arriving at a rapid pace, if your software does not regularly receive PSL updates, it may erroneously think new gTLDs are not known. The DNS is the proper source for this information. If you must use it for this purpose, please do not bake static copies of the PSL into your software with no update mechanism.**
**Using the PSL to determine what is a valid domain name and what isn't is dangerous, particularly in these days where new gTLDs are arriving at a rapid pace. The DNS is the proper source for this information. If you must use this library for this purpose, please consider integrating a PSL update mechanism into your software.**

### Public Suffix List Maintenance

Expand Down Expand Up @@ -221,8 +236,9 @@ To work as intended, the `Pdp\Manager` constructor requires:

- a [PSR-16](http://www.php-fig.org/psr/psr-16/) Cache object to store the rules locally.

- a `Pdp\HttpClient` object to retrieve the PSL.
the `Pdp\HttpClient` is a simple interface which exposes the `HttpClient::getContent` method. This method expects a string URL representation has its sole argument and returns the body from the given URL resource as a string.
- a `Pdp\HttpClient` object to retrieve the PSL.

The `Pdp\HttpClient` is a simple interface which exposes the `HttpClient::getContent` method. This method expects a string URL representation has its sole argument and returns the body from the given URL resource as a string.
If an error occurs while retrieving such body a `HttpClientException` exception is thrown.

~~~php
Expand Down Expand Up @@ -411,6 +427,26 @@ Contributing

Contributions are welcome and will be fully credited. Please see [CONTRIBUTING](.github/CONTRIBUTING.md) for details.

Testing
-------

`pdp-domain-parser` has:

- a [PHPUnit](https://phpunit.de) test suite
- a coding style compliance test suite using [PHP CS Fixer](http://cs.sensiolabs.org/).
- a code analysis compliance test suite using [PHPStan](https://github.com/phpstan/phpstan).

To run the tests, run the following command from the project folder.

``` bash
$ composer test
```

Security
-------

If you discover any security related issues, please email [email protected] instead of using the issue tracker.

Credits
-------

Expand Down
24 changes: 19 additions & 5 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,9 +39,13 @@
"psr/simple-cache": "^1"
},
"require-dev": {
"phpunit/phpunit": "^6.3",
"composer/composer": "^1.6",
"friendsofphp/php-cs-fixer": "^2.7",
"mikey179/vfsStream": "^1.6",
"friendsofphp/php-cs-fixer": "^2.7"
"phpstan/phpstan": "^0.9.2",
"phpstan/phpstan-phpunit": "^0.9.4",
"phpstan/phpstan-strict-rules": "^0.9.0",
"phpunit/phpunit": "^6.3"
},
"suggest": {
"psr/simple-cache-implementation": "To enable using other cache providers",
Expand All @@ -59,11 +63,21 @@
}
},
"scripts": {
"phpcs": "php-cs-fixer fix -vv --diff --dry-run --allow-risky=yes",
"phpstan-src": "phpstan analyse -l 7 -c phpstan.src.neon src",
"phpstan-tests": "phpstan analyse -l 7 -c phpstan.tests.neon tests",
"phpstan": [
"@phpstan-src",
"@phpstan-tests"
],
"phpunit": "phpunit --coverage-text",
"post-install-cmd": "\\Pdp\\Installer::updateLocalCache",
"post-update-cmd": "\\Pdp\\Installer::updateLocalCache",
"test": "phpunit --coverage-text; php-cs-fixer fix -vv --diff --dry-run --allow-risky=yes",
"phpunit": "phpunit --coverage-text",
"phpcs": "php-cs-fixer fix -vv --diff --dry-run --allow-risky=yes"
"test": [
"@phpunit",
"@phpcs",
"@phpstan"
]
},
"extra": {
"branch-alias": {
Expand Down
1 change: 0 additions & 1 deletion data/pdp-PSL-FULL-5a3cc7f81795bb2e48e848af42d287b4.cache

This file was deleted.

1 change: 1 addition & 0 deletions data/pdp-PSL_FULL_5a3cc7f81795bb2e48e848af42d287b4.cache

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions phpstan.src.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon
parameters:
ignoreErrors:
- '#has invalid typehint type Psr\\SimpleCache\\DateInterval#'
reportUnmatchedIgnoredErrors: false
5 changes: 5 additions & 0 deletions phpstan.tests.neon
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
includes:
- vendor/phpstan/phpstan-strict-rules/rules.neon
- vendor/phpstan/phpstan-phpunit/extension.neon
- vendor/phpstan/phpstan-phpunit/rules.neon
- vendor/phpstan/phpstan-phpunit/strictRules.neon
7 changes: 6 additions & 1 deletion src/Converter.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,14 @@
* Public Suffix List Parser.
*
* This class convert the Public Suffix List into an associative, multidimensional array
*
* @author Jeremy Kendall <[email protected]>
* @author Ignace Nyamagana Butera <[email protected]>
*/
final class Converter
{
use IDNAConverterTrait;

/**
* Convert the Public Suffix List into
* an associative, multidimensional array
Expand Down Expand Up @@ -99,7 +104,7 @@ private function addRule(array $list, array $rule_parts): array
// "The domain and all rules must be canonicalized in the normal way
// for hostnames - lower-case, Punycode (RFC 3492)."

$part = idn_to_ascii($part, 0, INTL_IDNA_VARIANT_UTS46);
$part = $this->idnToAscii($part);
$isDomain = true;
if (0 === strpos($part, '!')) {
$part = substr($part, 1);
Expand Down
Loading

0 comments on commit fa7937a

Please sign in to comment.