Skip to content

Commit c5a5197

Browse files
committed
Improve CurlHttpClient
1 parent d5ff1a4 commit c5a5197

File tree

3 files changed

+71
-33
lines changed

3 files changed

+71
-33
lines changed

README.md

Lines changed: 28 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -47,10 +47,10 @@ Documentation
4747
### Domain name resolution
4848

4949

50-
In order to resolve a domain name we must:
50+
In order to resolve a domain name one we must:
5151

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

5555
Conversion is done using the `Pdp\Converter` class.
5656

@@ -67,7 +67,7 @@ final class Converter
6767

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

70-
Once the PSL has been converted we can feed its data to a `Pdp\Rules` object which is responsable for resolving a given domain name against the PSL rules.
70+
Once the PSL has been converted we can feed its data to a `Pdp\Rules` object which is responsable for resolving a given domain name against its rules.
7171

7272
~~~php
7373
<?php
@@ -87,7 +87,7 @@ final class Rules
8787

8888
The `Rules` constructor expects the result of the PSL conversion by the `Pdp\Converter` class.
8989

90-
Domain name resolution is done using the `Rules::resolve` method which returns a `Pdp\Domain` object. The method expects
90+
Domain name resolution is done using the `Rules::resolve`. The method expects
9191

9292
- a valid domain name as a string
9393
- a string to optionnally specify which section of the PSL you want to validate the given domain against. The possible values are:
@@ -97,6 +97,9 @@ Domain name resolution is done using the `Rules::resolve` method which returns a
9797

9898
By default, the `$type` argument equals `Rules::ALL_DOMAINS`. If an unrecognized section is submitted otherwise, a `Pdp\Exception` exception will be thrown.
9999

100+
101+
`Rules::resolve` returns a `Domain` object.
102+
100103
~~~php
101104
<?php
102105

@@ -112,7 +115,22 @@ final class Domain implements JsonSerializable
112115
}
113116
~~~
114117

115-
The `Domain` getters method always return normalized value according to the domain status against the PSL rules.
118+
The `Domain` getter methods returns:
119+
120+
- the submitted domain name using `Domain::getDomain`
121+
- the public suffix part normalized according to the domain using `Domain::getPublicSuffix`
122+
- the registrable domain part using `Domain::getRegistrableDomain`
123+
- the subdomain part usung `Domain::getSubDomain`.
124+
125+
If the domain name of some of its part are seriously malformed or unrecognized, the getter methods will return `null`.
126+
127+
**The Domain name public status status depends on the PSL section used to resolve them:**
128+
129+
- `Domain::isICANN` returns `true` if the domain name resolution is done against a PSL which includes the ICANN DOMAINS section and its public suffix is found in it;
130+
- `Domain::isPrivate` returns `true` if the domain name resolution is done against a PSL which includes the PRIVATE DOMAINS section and its public suffix is found in it;
131+
- `Domain::isKnown` returns `true` if the public suffix is found in the selected PSL
132+
133+
**THIS EXAMPLE ILLUSTRATE HOW EACH OBJECT IS USED BUT SHOULD BE AVOID IN A PRODUCTIVE ENVIRONMENT**
116134

117135
~~~php
118136
<?php
@@ -144,7 +162,7 @@ echo json_encode($domain, JSON_PRETTY_PRINT);
144162
// "isPrivate": false
145163
// }
146164

147-
//let's resolve the same domain against the PRIVATE DOMAIN SECTION
165+
//The same domain will yield a different result using the PRIVATE DOMAIN SECTION only
148166

149167
$domain = $rules->resolve('www.ulb.ac.be', Rules::PRIVATE_DOMAINS);
150168
echo json_encode($domain, JSON_PRETTY_PRINT);
@@ -160,15 +178,15 @@ echo json_encode($domain, JSON_PRETTY_PRINT);
160178
// }
161179
~~~
162180

163-
**Warning: While the above example works it is highly discouraged to use the library in a productive application this way, without a caching mechanism to load the PSL.**
181+
**WARNING:**
164182

165-
**Warning: `Domain::isKnown`, `Domain::isICANN` status depends on the PSL rules used. For the same domain, depending on the rules used a domain public suffix status may be known or not, may be ICANN or not.**
183+
**Yous should never user the library this way in a productive application, without at least a caching mechanism to load the PSL.**
166184

167-
**Warning: 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.**
185+
**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.**
168186

169187
### Public Suffix List Maintenance
170188

171-
**Directly fetching the PSL without caching the result is not recommend**. For that reason, the library comes bundle with a `Pdp\Manager` class. This class is a service which enables resolving domain name without the constant network overhead of continously downloading the PSL. The class retrieves, converts and caches the PSL as well as creates the corresponding `Pdp\Rules` object on demand. It uses internally a `Pdp\Converter` object to convert the fetched PSL into its `array` representation when required.
189+
Since **directly fetching the PSL without caching the result is not recommend**, the library comes bundle with a `Pdp\Manager` class. This class is a service which enables resolving domain name without the constant network overhead of continously downloading the PSL. The class retrieves, converts and caches the PSL as well as creates the corresponding `Pdp\Rules` object on demand. It internally uses a `Pdp\Converter` object to convert the fetched PSL into its `array` representation when required.
172190

173191
~~~php
174192
<?php

src/CurlHttpClient.php

Lines changed: 34 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,8 @@
1111

1212
namespace Pdp;
1313

14+
use InvalidArgumentException;
15+
1416
/**
1517
* Simple cURL Http client
1618
*
@@ -26,17 +28,43 @@
2628
final class CurlHttpClient implements HttpClient
2729
{
2830
/**
29-
* {@inheritdoc}
31+
* Additionnal cURL options
32+
*
33+
* @var array
3034
*/
31-
public function getContent(string $url): string
35+
private $options;
36+
37+
/**
38+
* new instance
39+
*
40+
* @param array $options additional cURL options
41+
*/
42+
public function __construct(array $options = [])
3243
{
33-
$curl = curl_init();
34-
curl_setopt_array($curl, [
44+
$this->options = $options + [
3545
CURLOPT_FAILONERROR => true,
3646
CURLOPT_FOLLOWLOCATION => true,
3747
CURLOPT_RETURNTRANSFER => true,
38-
CURLOPT_URL => $url,
39-
]);
48+
CURLOPT_HTTPGET => true,
49+
];
50+
51+
$curl = curl_init();
52+
$res = @curl_setopt_array($curl, $this->options);
53+
curl_close($curl);
54+
if (!$res) {
55+
throw new InvalidArgumentException('Please verify your curl additionnal options');
56+
}
57+
}
58+
59+
/**
60+
* {@inheritdoc}
61+
*/
62+
public function getContent(string $url): string
63+
{
64+
$options = $this->options;
65+
$options[CURLOPT_URL] = $url;
66+
$curl = curl_init();
67+
curl_setopt_array($curl, $options);
4068
$content = curl_exec($curl);
4169
$code = curl_errno($curl);
4270
$message = curl_error($curl);

tests/CurlHttpClientTest.php

Lines changed: 9 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -4,37 +4,29 @@
44

55
namespace pdp\tests;
66

7+
use InvalidArgumentException;
78
use Pdp\CurlHttpClient;
89
use Pdp\HttpClientException;
910
use PHPUnit\Framework\TestCase;
1011

1112
class CurlHttpClientTest extends TestCase
1213
{
13-
/**
14-
* @var HttpClient
15-
*/
16-
protected $adapter;
17-
18-
protected function setUp()
19-
{
20-
$this->adapter = new CurlHttpClient();
21-
}
22-
23-
protected function tearDown()
24-
{
25-
$this->adapter = null;
26-
}
27-
2814
public function testGetContent()
2915
{
30-
$content = $this->adapter->getContent('https://www.google.com');
16+
$content = (new CurlHttpClient())->getContent('https://www.google.com');
3117
$this->assertNotNull($content);
3218
$this->assertContains('google', $content);
3319
}
3420

3521
public function testThrowsException()
3622
{
3723
$this->expectException(HttpClientException::class);
38-
$this->adapter->getContent('https://qsfsdfqdf.dfsf');
24+
(new CurlHttpClient())->getContent('https://qsfsdfqdf.dfsf');
25+
}
26+
27+
public function testConstructorThrowsException()
28+
{
29+
$this->expectException(InvalidArgumentException::class);
30+
new CurlHttpClient(['foo' => 'bar']);
3931
}
4032
}

0 commit comments

Comments
 (0)