From c602ad503f2145584a9adbee63e53ca093a5e14d Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 17 Dec 2023 10:21:20 +0200 Subject: [PATCH 01/24] update readme --- README.md | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f10281..3f31c5c 100644 --- a/README.md +++ b/README.md @@ -66,4 +66,8 @@ var_dump( var_dump( \Yggverse\Net\Dig::isRecordValue('A', '127.0.0.1') ); -``` \ No newline at end of file +``` + +## Integrations + +* [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/net-api) From fc2b0822afe0dfa744e5ff375df051d91210195a Mon Sep 17 00:00:00 2001 From: ghost Date: Sun, 17 Dec 2023 11:45:25 +0200 Subject: [PATCH 02/24] update link --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 3f31c5c..3d93d2c 100644 --- a/README.md +++ b/README.md @@ -70,4 +70,4 @@ var_dump( ## Integrations -* [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/net-api) +* [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/web-api) From b2e0750d1eeadb16ceb0b8463ef68403fc24a1cd Mon Sep 17 00:00:00 2001 From: yggverse Date: Fri, 5 Apr 2024 09:52:50 +0300 Subject: [PATCH 03/24] init Address class --- README.md | 21 ++++++ src/Address.php | 168 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 189 insertions(+) create mode 100644 src/Address.php diff --git a/README.md b/README.md index 3d93d2c..5bce5aa 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,27 @@ var_dump( ); ``` +### Address + +Includes useful methods to work with network addresses + +``` +$address = new \Yggverse\Net\Address( + 'http://yo.ygg' +); + +var_dump( + $address->getScheme() // Just scheme substring +); + +var_dump( + $address->absolute( + './some/uri' + ) // return http://yo.ygg/some/uri +); +``` + ## Integrations * [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/web-api) +* [Yo! Search Crawler for different networks](https://github.com/YGGverse/Yo) diff --git a/src/Address.php b/src/Address.php new file mode 100644 index 0000000..065f9a4 --- /dev/null +++ b/src/Address.php @@ -0,0 +1,168 @@ +setScheme( + (string) $scheme + ); + } + + if ($user = parse_url($address, PHP_URL_USER)) + { + $this->setUser( + (string) $user + ); + } + + if ($pass = parse_url($address, PHP_URL_PASS)) + { + $this->setPath( + (string) $pass + ); + } + + if ($host = parse_url($address, PHP_URL_HOST)) + { + $this->setHost( + (string) $host + ); + } + + if ($port = parse_url($address, PHP_URL_PORT)) + { + $this->setPort( + (int) $port + ); + } + + if ($path = parse_url($address, PHP_URL_PATH)) + { + $this->setPath( + (string) $path + ); + } + + if ($query = parse_url($address, PHP_URL_QUERY)) + { + $this->setQuery( + (string) $query + ); + } + } + } + + public function isAbsolute(): bool + { + return ($this->_scheme && $this->_host); + } + + public function isRelative(): bool + { + return !$this->isAbsolute(); + } + + public function getScheme(): string + { + return $this->_scheme; + } + + public function setScheme(string $value): void + { + $this->_scheme = $value; + } + + public function getHost(): string + { + return $this->_host; + } + + public function setHost(string $value): void + { + $this->_host = $value; + } + + public function getUser(): string + { + return $this->_user; + } + + public function setUser(string $value): void + { + $this->_user = $value; + } + + public function getPass(): string + { + return $this->_pass; + } + + public function setPass(string $value): void + { + $this->_pass = $value; + } + + public function getPort(): int + { + return $this->_port; + } + + public function setPort(int $value): void + { + $this->_port = $value; + } + + public function getPath(): string + { + return $this->_path; + } + + public function setPath(string $value): void + { + $this->_path = $value; + + $this->_dirs = explode( + '/', + $value + ); + } + + public function getDirs(): array + { + return $this->_dirs; + } + + public function getQuery(): string + { + return $this->_query; + } + + public function setQuery(string $value): void + { + $this->_query = $value; + } + + public function absolute(string $address): string + { + // @TODO + } +} \ No newline at end of file From bbdc276db67fe3e475feb9e2d46b3a492d445dc6 Mon Sep 17 00:00:00 2001 From: yggverse Date: Fri, 5 Apr 2024 10:10:19 +0300 Subject: [PATCH 04/24] add cross-platform separator support --- src/Address.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/src/Address.php b/src/Address.php index 065f9a4..1e9b3ea 100644 --- a/src/Address.php +++ b/src/Address.php @@ -16,6 +16,8 @@ class Address private array $_dirs = []; + private string $_separator = '/'; + public function __construct(?string $address = null) { if ($address) @@ -138,12 +140,17 @@ class Address public function setPath(string $value): void { - $this->_path = $value; + if (false !== strpos($value, '\\')) + { + $this->_separator = '\\'; + } $this->_dirs = explode( - '/', + $this->_separator, $value ); + + $this->_path = $value; } public function getDirs(): array @@ -161,6 +168,11 @@ class Address $this->_query = $value; } + public function getSeparator(): string + { + return $this->_separator; + } + public function absolute(string $address): string { // @TODO From 3329a90819bd1d0662b2848d36bb8605fd4bc6fa Mon Sep 17 00:00:00 2001 From: yggverse Date: Fri, 5 Apr 2024 11:17:14 +0300 Subject: [PATCH 05/24] fix data types, add fragment support, draft absolute method --- README.md | 10 +++- src/Address.php | 153 +++++++++++++++++++++++++++++++++++++++++++----- 2 files changed, 145 insertions(+), 18 deletions(-) diff --git a/README.md b/README.md index 5bce5aa..348946e 100644 --- a/README.md +++ b/README.md @@ -78,12 +78,18 @@ $address = new \Yggverse\Net\Address( ); var_dump( - $address->getScheme() // Just scheme substring + $address->getScheme() // Scheme substring +); + +... + +$subject = new \Yggverse\Net\Address( + './some/uri' ); var_dump( $address->absolute( - './some/uri' + $subject ) // return http://yo.ygg/some/uri ); ``` diff --git a/src/Address.php b/src/Address.php index 1e9b3ea..4c1977e 100644 --- a/src/Address.php +++ b/src/Address.php @@ -13,6 +13,7 @@ class Address private ?int $_port = null; private ?string $_path = null; private ?string $_query = null; + private ?string $_fragment = null; private array $_dirs = []; @@ -70,6 +71,13 @@ class Address (string) $query ); } + + if ($fragment = parse_url($address, PHP_URL_FRAGMENT)) + { + $this->setFragment( + (string) $fragment + ); + } } } @@ -83,62 +91,62 @@ class Address return !$this->isAbsolute(); } - public function getScheme(): string + public function getScheme(): ?string { return $this->_scheme; } - public function setScheme(string $value): void + public function setScheme(?string $value): void { $this->_scheme = $value; } - public function getHost(): string + public function getHost(): ?string { return $this->_host; } - public function setHost(string $value): void + public function setHost(?string $value): void { $this->_host = $value; } - public function getUser(): string + public function getUser(): ?string { return $this->_user; } - public function setUser(string $value): void + public function setUser(?string $value): void { $this->_user = $value; } - public function getPass(): string + public function getPass(): ?string { return $this->_pass; } - public function setPass(string $value): void + public function setPass(?string $value): void { $this->_pass = $value; } - public function getPort(): int + public function getPort(): ?int { return $this->_port; } - public function setPort(int $value): void + public function setPort(?int $value): void { $this->_port = $value; } - public function getPath(): string + public function getPath(): ?string { return $this->_path; } - public function setPath(string $value): void + public function setPath(?string $value): void { if (false !== strpos($value, '\\')) { @@ -158,23 +166,136 @@ class Address return $this->_dirs; } - public function getQuery(): string + public function getQuery(): ?string { return $this->_query; } - public function setQuery(string $value): void + public function setQuery(?string $value): void { $this->_query = $value; } + public function getFragment(): ?string + { + return $this->_fragment; + } + + public function setFragment(?string $value): void + { + $this->_fragment = $value; + } + public function getSeparator(): string { return $this->_separator; } - public function absolute(string $address): string + public function get(): string { - // @TODO + $address = ''; + + if ($scheme = $this->getScheme()) + { + $address .= sprintf( + '%s://', + $scheme + ); + } + + if ($user = $this->getUser()) + { + if ($pass = $this->getPass()) + { + $address .= sprintf( + '%s:%s@', + $user, + pass + ); + } + + else + { + $address .= sprintf( + '%s@', + $user + ); + } + } + + if ($host = $this->getHost()) + { + $address .= $host; + } + + if ($port = $this->getPort()) + { + $address .= sprintf( + ':%d', + $port + ); + } + + if ($path = $this->getPath()) + { + $address .= sprintf( + '%s%s', + $this->getSeparator(), + trim( + $path, + $this->getSeparator() + ) + ); + } + + if ($query = $this->getQuery()) + { + $address .= sprintf( + '?%s', + $query + ); + } + + if ($fragment = $this->getFragment()) + { + $address .= sprintf( + '#%s', + $fragment + ); + } + + return $address; + } + + public function absolute( + \Yggverse\Net\Address $address + ): string + { + if ($address->isAbsolute()) + { + return $address->get(); + } + + $address->setScheme( + $this->getScheme() + ); + + $address->setUser( + $this->getUser() + ); + + $address->setPass( + $this->getPass() + ); + + $address->setHost( + $this->getHost() + ); + + $address->setPort( + $this->getPort() + ); + + return ''; // @TODO } } \ No newline at end of file From 92eb9b3ba20db3d228d4169275e3c920da95e6a4 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 6 Apr 2024 02:04:22 +0300 Subject: [PATCH 06/24] implement absolute address converter --- README.md | 87 ++++++++++++++++++++++++++---- src/Address.php | 137 ++++++++++++++++++++++++++++++++++++------------ 2 files changed, 179 insertions(+), 45 deletions(-) diff --git a/README.md b/README.md index 348946e..9956b8b 100644 --- a/README.md +++ b/README.md @@ -70,31 +70,96 @@ var_dump( ### Address -Includes useful methods to work with network addresses +Includes methods to work with network addresses. + +#### Base address methods + +Different operations with address parts: + +* `scheme` +* `user` +* `password` +* `host` +* `protocol` +* `path` +* `query` +* `fragment` + +#### Address conversion from relative to absolute format + +**Document root** ``` +$base = new \Yggverse\Net\Address( + 'http://yo.ygg/a1/b1/c1' +); + $address = new \Yggverse\Net\Address( - 'http://yo.ygg' + '/a2' ); var_dump( - $address->getScheme() // Scheme substring + $address->getAbsolute( + $base + ) // return http://yo.ygg/a2 +); +``` + +**Current folder** + +``` +$base = new \Yggverse\Net\Address( + 'http://yo.ygg/a1/b1/c1' ); -... - -$subject = new \Yggverse\Net\Address( - './some/uri' +$address = new \Yggverse\Net\Address( + 'c2' ); var_dump( - $address->absolute( - $subject - ) // return http://yo.ygg/some/uri + $address->getAbsolute( + $base + ) // return http://yo.ygg/a1/b1/c2 +); +``` + +**Ending slash** + +``` +$base = new \Yggverse\Net\Address( + 'http://yo.ygg/a1/b1/c1/' +); + +$address = new \Yggverse\Net\Address( + '../../b2/c2' +); + +var_dump( + $address->getAbsolute( + $base + ) // return http://yo.ygg/a1/b2/c2 +); +``` + +**All options** + +``` +$base = new \Yggverse\Net\Address( + 'http://user:password@yo.ygg/a1/b1/c1?attribute=value#anchor' +); + +$address = new \Yggverse\Net\Address( + '../../a2/b2?attribute2=value2#anchor2' +); + +var_dump( + $address->getAbsolute( + $base + ) // return http://user:password@yo.ygg/a2/b2?attribute2=value2#anchor2 ); ``` ## Integrations * [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/web-api) -* [Yo! Search Crawler for different networks](https://github.com/YGGverse/Yo) +* [Yo! Crawler for different networks](https://github.com/YGGverse/Yo) diff --git a/src/Address.php b/src/Address.php index 4c1977e..f7567f2 100644 --- a/src/Address.php +++ b/src/Address.php @@ -15,10 +15,10 @@ class Address private ?string $_query = null; private ?string $_fragment = null; - private array $_dirs = []; - private string $_separator = '/'; + private array $_segments = []; + public function __construct(?string $address = null) { if ($address) @@ -39,7 +39,7 @@ class Address if ($pass = parse_url($address, PHP_URL_PASS)) { - $this->setPath( + $this->setPass( (string) $pass ); } @@ -150,10 +150,12 @@ class Address { if (false !== strpos($value, '\\')) { - $this->_separator = '\\'; + $this->setSeparator( + '\\' + ); } - $this->_dirs = explode( + $this->_segments = explode( $this->_separator, $value ); @@ -161,9 +163,9 @@ class Address $this->_path = $value; } - public function getDirs(): array + public function getSegments(): array { - return $this->_dirs; + return $this->_segments; } public function getQuery(): ?string @@ -191,6 +193,11 @@ class Address return $this->_separator; } + public function setSeparator(?string $value): void + { + $this->_separator = $value; + } + public function get(): string { $address = ''; @@ -198,8 +205,10 @@ class Address if ($scheme = $this->getScheme()) { $address .= sprintf( - '%s://', - $scheme + '%s:%s%s', + $scheme, + $this->getSeparator(), + $this->getSeparator() ); } @@ -210,7 +219,7 @@ class Address $address .= sprintf( '%s:%s@', $user, - pass + $pass ); } @@ -238,14 +247,7 @@ class Address if ($path = $this->getPath()) { - $address .= sprintf( - '%s%s', - $this->getSeparator(), - trim( - $path, - $this->getSeparator() - ) - ); + $address .= $path; } if ($query = $this->getQuery()) @@ -267,35 +269,102 @@ class Address return $address; } - public function absolute( - \Yggverse\Net\Address $address - ): string + public function getAbsolute( + \Yggverse\Net\Address $base + ): ?string { - if ($address->isAbsolute()) + if ($this->isAbsolute()) { - return $address->get(); + return $this->get(); } - $address->setScheme( - $this->getScheme() + if ($base->isRelative()) + { + return null; + } + + $this->setScheme( + $base->getScheme() ); - $address->setUser( - $this->getUser() + $this->setUser( + $base->getUser() ); - $address->setPass( - $this->getPass() + $this->setPass( + $base->getPass() ); - $address->setHost( - $this->getHost() + $this->setHost( + $base->getHost() ); - $address->setPort( - $this->getPort() + $this->setPort( + $base->getPort() ); - return ''; // @TODO + $this->setSeparator( + $base->getSeparator() + ); + + if (str_starts_with((string) $this->getPath(), $this->getSeparator())) + { + return $this->get(); + } + + if ($path = $this->getPath()) + { + $prefix = array_reverse( + $base->getSegments() + ); + + array_shift( + $prefix + ); + + $navigate = true; + + $postfix = []; + + foreach ($this->getSegments() as $index => $segment) + { + if ($segment == '.') + { + continue; + } + + if ($navigate && $segment == '..') + { + if (empty($prefix[$index])) + { + return null; + } + + unset( + $prefix[$index] + ); + + continue; + } + + $navigate = false; + + $postfix[] = $segment; + } + + $this->setPath( + implode( + $this->getSeparator(), + array_merge( + array_reverse( + $prefix + ), + $postfix + ) + ) + ); + } + + return $this->get(); } } \ No newline at end of file From 16f90cb23bb4ea2dd5114bee719d5bf4c4a20083 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 6 Apr 2024 02:33:09 +0300 Subject: [PATCH 07/24] fix missed path slash --- src/Address.php | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/Address.php b/src/Address.php index f7567f2..f8b7e71 100644 --- a/src/Address.php +++ b/src/Address.php @@ -247,6 +247,11 @@ class Address if ($path = $this->getPath()) { + if (!str_starts_with($path, $this->getSeparator())) + { + $address .= $this->getSeparator(); + } + $address .= $path; } From a57028f6099b09e1136835c3b2aa1f45f83688bb Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 6 Apr 2024 10:30:22 +0300 Subject: [PATCH 08/24] add custom provider support --- README.md | 2 +- src/Dig.php | 41 ++++++++++++++++++++++++++++++++++------- 2 files changed, 35 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index 9956b8b..bd6e012 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ var_dump( ``` var_dump( - \Yggverse\Net\Dig::records('yo.index', ['A', 'AAAA']) + \Yggverse\Net\Dig::records('yo.index', ['A', 'AAAA'], &$result = [], &$error = [], $provider = null) ); ``` diff --git a/src/Dig.php b/src/Dig.php index 7323f0c..c7d221d 100644 --- a/src/Dig.php +++ b/src/Dig.php @@ -17,32 +17,59 @@ class Dig ]; } + public static function isProvider(mixed $value): bool + { + return + ( + is_string($value) && + false !== filter_var($value, FILTER_VALIDATE_IP) + ); + } + public static function isHostName(mixed $value, array $find = ['_'], array $replace = []): bool { - return is_string($value) && false !== filter_var(str_replace($find, $replace, $value), FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME); + return ( + is_string($value) && + false !== filter_var(str_replace($find, $replace, $value), FILTER_VALIDATE_DOMAIN, FILTER_FLAG_HOSTNAME) + ); } public static function isRecord(mixed $value): bool { - return is_string($value) && isset(self::_records()[$value]); + return + ( + is_string($value) && + isset(self::_records()[$value]) + ); } public static function isRecordValue(mixed $record, mixed $value): bool { - return is_string($record) && - is_string($value) && - isset(self::_records()[$record]) && self::_records()[$record]($value); + return + ( + is_string($record) && + is_string($value) && + isset(self::_records()[$record]) && self::_records()[$record]($value) + ); } - public static function records(string $hostname, array $records, array &$result = [], array &$error = []): array + public static function records(string $hostname, array $records, array &$result = [], array &$error = [], ?string $provider = null): array { + if (self::isProvider($provider)) + { + $provider = sprintf( + '@%s', + $provider + ); + } + if (self::isHostName($hostname)) { foreach ($records as $record) { if (self::isRecord($record)) { - if ($values = exec(sprintf('dig %s %s +short', $record, $hostname))) + if ($values = exec(sprintf('dig %s %s %s +short', (string) $provider, (string) $record, (string) $hostname))) { foreach (explode(PHP_EOL, $values) as $value) { From 1e5b42d407f3e784b952cb43c4ca36b4852f1081 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sat, 6 Apr 2024 11:35:40 +0300 Subject: [PATCH 09/24] add timeout attribute --- README.md | 2 +- src/Dig.php | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index bd6e012..d22fa2a 100644 --- a/README.md +++ b/README.md @@ -40,7 +40,7 @@ var_dump( ``` var_dump( - \Yggverse\Net\Dig::records('yo.index', ['A', 'AAAA'], &$result = [], &$error = [], $provider = null) + \Yggverse\Net\Dig::records('yo.index', ['A', 'AAAA'], &$result = [], &$error = [], $provider = null, $timeout = 5) ); ``` diff --git a/src/Dig.php b/src/Dig.php index c7d221d..e8f5ae9 100644 --- a/src/Dig.php +++ b/src/Dig.php @@ -53,7 +53,7 @@ class Dig ); } - public static function records(string $hostname, array $records, array &$result = [], array &$error = [], ?string $provider = null): array + public static function records(string $hostname, array $records, array &$result = [], array &$error = [], ?string $provider = null, int $timeout = 5): array { if (self::isProvider($provider)) { @@ -69,7 +69,7 @@ class Dig { if (self::isRecord($record)) { - if ($values = exec(sprintf('dig %s %s %s +short', (string) $provider, (string) $record, (string) $hostname))) + if ($values = exec(sprintf('dig %s %s %s +short +time=%d', (string) $provider, $record, $hostname, $timeout))) { foreach (explode(PHP_EOL, $values) as $value) { From 96cd4163be7951de6b114c72f869e5fd631d7348 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 00:58:48 +0300 Subject: [PATCH 10/24] implement resolve feature --- README.md | 31 ++++++++ src/Resolve.php | 185 ++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 216 insertions(+) create mode 100644 src/Resolve.php diff --git a/README.md b/README.md index d22fa2a..1e54a7c 100644 --- a/README.md +++ b/README.md @@ -68,6 +68,37 @@ var_dump( ); ``` +### Resolve + +``` +$resolve = new \Yggverse\Net\Resolve( + [ + 'A', + 'AAAA' + ], + [ + '1.1.1.1', + '8.8.8.8' + ], + // .. +); + +$resolved = $resolve->address( + 'https://en.wikipedia.org/wiki/Domain_Name_System' +); + +if ($resolved) +{ + var_dump( + $resolved->get() // https://185.15.59.224/wiki/Domain_Name_System + ); + + var_dump( + $resolved->getHost() // 185.15.59.224 + ); +} +``` + ### Address Includes methods to work with network addresses. diff --git a/src/Resolve.php b/src/Resolve.php new file mode 100644 index 0000000..be90e33 --- /dev/null +++ b/src/Resolve.php @@ -0,0 +1,185 @@ +setRecords( + $records + ); + } + + if ($providers) + { + $this->setProviders( + $providers + ); + } + + if ($timeout) + { + $this->setTimeout( + $timeout + ); + } + + $this->setShuffle( + $shuffle + ); + } + + public function getRecords(): array + { + return $this->_records; + } + + public function setRecords(array $records): void + { + foreach ($records as $record) + { + $this->addRecord( + $record + ); + } + } + + public function addRecord(string $record): void + { + $this->_records[] = $record; + + $this->_records = array_unique( + $this->_records + ); + } + + public function getProviders(): array + { + return $this->_providers; + } + + public function setProviders(array $providers): void + { + foreach ($providers as $provider) + { + $this->addProvider( + $provider + ); + } + } + + public function addProvider(string $provider): void + { + $this->_providers[] = $provider; + + $this->_providers = array_unique( + $this->_providers + ); + } + + public function setTimeout( + int $timeout + ): void + { + $this->_timeout = $timeout; + } + + public function getTimeout(): int + { + return $this->_timeout; + } + + public function setShuffle( + bool $shuffle + ): void + { + $this->_shuffle = $shuffle; + } + + public function isShuffle(): bool + { + return $this->_shuffle; + } + + public function address( + string $url, + array &$result = [], + array &$error = [] + ): ?\Yggverse\Net\Address + { + $address = new \Yggverse\Net\Address( + $url + ); + + foreach ($this->_providers as $provider) + { + foreach ( + \Yggverse\Net\Dig::records( + $address->getHost(), + $this->_records, + $result, + $error, + $provider, + $this->_timeout + ) as $record => $data + ) { + + if ($this->_shuffle) + { + shuffle( + $data + ); + } + + foreach ($data as $host) + { + if (false !== filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) + { + $resolved->setHost( + sprintf( + '[%s]', + $host + ) + ); + } + + else + { + $address->setHost( + $host + ); + } + + return $address; + } + } + } + + return null; + } +} \ No newline at end of file From 38f33eb584af74cf7e7f1ce7f92ad783bdc52be8 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 02:19:54 +0300 Subject: [PATCH 11/24] update address method api (outside address init) --- src/Resolve.php | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/src/Resolve.php b/src/Resolve.php index be90e33..b8d1747 100644 --- a/src/Resolve.php +++ b/src/Resolve.php @@ -127,15 +127,11 @@ class Resolve } public function address( - string $url, + \Yggverse\Net\Address $address, array &$result = [], array &$error = [] ): ?\Yggverse\Net\Address { - $address = new \Yggverse\Net\Address( - $url - ); - foreach ($this->_providers as $provider) { foreach ( From d3bea00b02d17342189d88e44b637289d2e7d754 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 02:20:23 +0300 Subject: [PATCH 12/24] implement url string resolve method --- src/Resolve.php | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/src/Resolve.php b/src/Resolve.php index b8d1747..1dd6492 100644 --- a/src/Resolve.php +++ b/src/Resolve.php @@ -126,6 +126,29 @@ class Resolve return $this->_shuffle; } + public function url( + string $url, + array &$result = [], + array &$error = [], + ?\Yggverse\Net\Address &$resolved = null + ): ?string + { + $resolved = $this->address( + new \Yggverse\Net\Address( + $url + ), + $result, + $error + ); + + if ($resolved) + { + return $resolved->get(); + } + + return null; + } + public function address( \Yggverse\Net\Address $address, array &$result = [], From 18ec72362ecf16df7b0a78a431ba896b2473bf58 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 02:27:57 +0300 Subject: [PATCH 13/24] update readme --- README.md | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1e54a7c..d08367b 100644 --- a/README.md +++ b/README.md @@ -70,6 +70,8 @@ var_dump( ### Resolve +#### Init resolver + ``` $resolve = new \Yggverse\Net\Resolve( [ @@ -82,9 +84,31 @@ $resolve = new \Yggverse\Net\Resolve( ], // .. ); +``` -$resolved = $resolve->address( +#### Get resolved URL string + +``` +$resolved = $resolve->url( 'https://en.wikipedia.org/wiki/Domain_Name_System' + // next arguments contain debug variables and new address object +); + +if ($resolved) +{ + var_dump( + $resolved // https://185.15.59.224/wiki/Domain_Name_System + ); +} +``` + +#### Resolve Address object + +``` +$resolved = $resolve->address( + new \Yggverse\Net\Address( + 'https://en.wikipedia.org/wiki/Domain_Name_System' + ) ); if ($resolved) From f6a3b1bbfa9f0b6f38616f64ab3b21be74253e51 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 02:44:41 +0300 Subject: [PATCH 14/24] use build in ip6 validator --- src/Resolve.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resolve.php b/src/Resolve.php index 1dd6492..933fa68 100644 --- a/src/Resolve.php +++ b/src/Resolve.php @@ -177,7 +177,7 @@ class Resolve foreach ($data as $host) { - if (false !== filter_var($host, FILTER_VALIDATE_IP, FILTER_FLAG_IPV6)) + if (\Yggverse\Net\Valid::ip6($host)) { $resolved->setHost( sprintf( From b37f28ce4f76ea3773bfe47f3b8020e3294234d9 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 02:45:35 +0300 Subject: [PATCH 15/24] implement validation class --- src/Valid.php | 40 ++++++++++++++++++++++++++++++++++++++++ 1 file changed, 40 insertions(+) create mode 100644 src/Valid.php diff --git a/src/Valid.php b/src/Valid.php new file mode 100644 index 0000000..3d80ecc --- /dev/null +++ b/src/Valid.php @@ -0,0 +1,40 @@ + Date: Sun, 7 Apr 2024 03:47:36 +0300 Subject: [PATCH 16/24] fix variable name --- src/Resolve.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Resolve.php b/src/Resolve.php index 933fa68..16f6d7e 100644 --- a/src/Resolve.php +++ b/src/Resolve.php @@ -179,7 +179,7 @@ class Resolve { if (\Yggverse\Net\Valid::ip6($host)) { - $resolved->setHost( + $address->setHost( sprintf( '[%s]', $host From 5e17d402451b0744fe8a73816e0b441a14846763 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 21:00:17 +0300 Subject: [PATCH 17/24] update readme --- README.md | 28 ++++++++++++++-------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/README.md b/README.md index d08367b..102f5b6 100644 --- a/README.md +++ b/README.md @@ -12,7 +12,7 @@ Network Library for PHP with native Yggdrasil support #### Check socket is open -``` +``` php var_dump( \Yggverse\Net\Socket::isOpen('yo.index', 80) ); @@ -20,7 +20,7 @@ var_dump( #### Check host valid -``` +``` php var_dump( \Yggverse\Net\Socket::isHost('yo.index') ); @@ -28,7 +28,7 @@ var_dump( #### Check port valid -``` +``` php var_dump( \Yggverse\Net\Socket::isPort(80) ); @@ -38,7 +38,7 @@ var_dump( #### Resolve records -``` +``` php var_dump( \Yggverse\Net\Dig::records('yo.index', ['A', 'AAAA'], &$result = [], &$error = [], $provider = null, $timeout = 5) ); @@ -46,7 +46,7 @@ var_dump( #### Check hostname valid -``` +``` php var_dump( \Yggverse\Net\Dig::isHostName('yo.index') ); @@ -54,7 +54,7 @@ var_dump( #### Check record valid -``` +``` php var_dump( \Yggverse\Net\Dig::isRecord('A') ); @@ -62,7 +62,7 @@ var_dump( #### Check record value valid -``` +``` php var_dump( \Yggverse\Net\Dig::isRecordValue('A', '127.0.0.1') ); @@ -72,7 +72,7 @@ var_dump( #### Init resolver -``` +``` php $resolve = new \Yggverse\Net\Resolve( [ 'A', @@ -88,7 +88,7 @@ $resolve = new \Yggverse\Net\Resolve( #### Get resolved URL string -``` +``` php $resolved = $resolve->url( 'https://en.wikipedia.org/wiki/Domain_Name_System' // next arguments contain debug variables and new address object @@ -104,7 +104,7 @@ if ($resolved) #### Resolve Address object -``` +``` php $resolved = $resolve->address( new \Yggverse\Net\Address( 'https://en.wikipedia.org/wiki/Domain_Name_System' @@ -144,7 +144,7 @@ Different operations with address parts: **Document root** -``` +``` php $base = new \Yggverse\Net\Address( 'http://yo.ygg/a1/b1/c1' ); @@ -162,7 +162,7 @@ var_dump( **Current folder** -``` +``` php $base = new \Yggverse\Net\Address( 'http://yo.ygg/a1/b1/c1' ); @@ -180,7 +180,7 @@ var_dump( **Ending slash** -``` +``` php $base = new \Yggverse\Net\Address( 'http://yo.ygg/a1/b1/c1/' ); @@ -198,7 +198,7 @@ var_dump( **All options** -``` +``` php $base = new \Yggverse\Net\Address( 'http://user:password@yo.ygg/a1/b1/c1?attribute=value#anchor' ); From 7c918ff99c19c3a6227b92f6c1a801d8394dd5c4 Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 7 Apr 2024 21:08:28 +0300 Subject: [PATCH 18/24] update readme --- README.md | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/README.md b/README.md index 102f5b6..9419e8c 100644 --- a/README.md +++ b/README.md @@ -214,6 +214,17 @@ var_dump( ); ``` +### Valid + +Network entities validation + +**Supported methods** + +* `Valid::ip` +* `Valid::ip4` +* `Valid::ip6` +* `Valid::domainHostName` + ## Integrations * [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/web-api) From 4f369bac4555a8afd6a98bb22b01b584b713dfbb Mon Sep 17 00:00:00 2001 From: yggverse Date: Tue, 9 Apr 2024 10:32:46 +0300 Subject: [PATCH 19/24] add integration --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index 9419e8c..a5da276 100644 --- a/README.md +++ b/README.md @@ -229,3 +229,4 @@ Network entities validation * [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/web-api) * [Yo! Crawler for different networks](https://github.com/YGGverse/Yo) +* [Yoda - PHP-GTK browser for Gemini Protocol](https://github.com/YGGverse/Yoda) From 0acff609f4feabdb52f65a15fcc668aad37369fa Mon Sep 17 00:00:00 2001 From: yggverse Date: Tue, 16 Apr 2024 18:44:00 +0300 Subject: [PATCH 20/24] implement custom Address::get attributes --- src/Address.php | 47 ++++++++++++++++++++++++++++------------------- 1 file changed, 28 insertions(+), 19 deletions(-) diff --git a/src/Address.php b/src/Address.php index f8b7e71..7ed5232 100644 --- a/src/Address.php +++ b/src/Address.php @@ -198,28 +198,37 @@ class Address $this->_separator = $value; } - public function get(): string + public function get( + bool $scheme = true, + bool $user = true, + bool $pass = true, + bool $host = true, + bool $port = true, + bool $path = true, + bool $query = true, + bool $fragment = true, + ): string { $address = ''; - if ($scheme = $this->getScheme()) + if ($scheme && $this->getScheme()) { $address .= sprintf( '%s:%s%s', - $scheme, + $this->getScheme(), $this->getSeparator(), $this->getSeparator() ); } - if ($user = $this->getUser()) + if ($user && $this->getUser()) { - if ($pass = $this->getPass()) + if ($pass && $this->getPass()) { $address .= sprintf( '%s:%s@', - $user, - $pass + $this->getUser(), + $this->getPass() ); } @@ -227,47 +236,47 @@ class Address { $address .= sprintf( '%s@', - $user + $this->getUser() ); } } - if ($host = $this->getHost()) + if ($host && $this->getHost()) { - $address .= $host; + $address .= $this->getHost(); } - if ($port = $this->getPort()) + if ($port && $this->getPort()) { $address .= sprintf( ':%d', - $port + $this->getPort() ); } - if ($path = $this->getPath()) + if ($path && $this->getPath()) { - if (!str_starts_with($path, $this->getSeparator())) + if (!str_starts_with($this->getPath(), $this->getSeparator())) { $address .= $this->getSeparator(); } - $address .= $path; + $address .= $this->getPath(); } - if ($query = $this->getQuery()) + if ($query && $this->getQuery()) { $address .= sprintf( '?%s', - $query + $this->getQuery() ); } - if ($fragment = $this->getFragment()) + if ($fragment && $this->getFragment()) { $address .= sprintf( '#%s', - $fragment + $this->getFragment() ); } From 0079e2a755789cc6e9c85b235644be2cc417b15c Mon Sep 17 00:00:00 2001 From: yggverse Date: Sun, 23 Jun 2024 00:17:31 +0300 Subject: [PATCH 21/24] replace getAbsolute with toAbsolute --- src/Address.php | 29 ++++++++++++++++++++++------- 1 file changed, 22 insertions(+), 7 deletions(-) diff --git a/src/Address.php b/src/Address.php index 7ed5232..d82756a 100644 --- a/src/Address.php +++ b/src/Address.php @@ -283,18 +283,18 @@ class Address return $address; } - public function getAbsolute( + public function toAbsolute( \Yggverse\Net\Address $base - ): ?string + ): bool { if ($this->isAbsolute()) { - return $this->get(); + return true; } if ($base->isRelative()) { - return null; + return false; } $this->setScheme( @@ -323,7 +323,7 @@ class Address if (str_starts_with((string) $this->getPath(), $this->getSeparator())) { - return $this->get(); + return true; } if ($path = $this->getPath()) @@ -351,7 +351,7 @@ class Address { if (empty($prefix[$index])) { - return null; + return false; } unset( @@ -377,8 +377,23 @@ class Address ) ) ); + + return true; } - return $this->get(); + return false; + } + + // @TODO deprecated, legacy needs only + public function getAbsolute( + \Yggverse\Net\Address $base + ): ?string + { + if ($this->toAbsolute($base)) + { + return $this->get(); + } + + return null; } } \ No newline at end of file From 9524c8fdec7443d8e27d47316787f1e84a7453d5 Mon Sep 17 00:00:00 2001 From: yggverse Date: Mon, 24 Jun 2024 23:04:50 +0300 Subject: [PATCH 22/24] add new project integration --- README.md | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index a5da276..6703ebb 100644 --- a/README.md +++ b/README.md @@ -227,6 +227,7 @@ Network entities validation ## Integrations -* [Network API with native Yggdrasil/IPv6 support](https://github.com/YGGverse/web-api) -* [Yo! Crawler for different networks](https://github.com/YGGverse/Yo) -* [Yoda - PHP-GTK browser for Gemini Protocol](https://github.com/YGGverse/Yoda) +* [web-api](https://github.com/YGGverse/web-api) - Network API with native Yggdrasil/IPv6 support +* [Yo!](https://github.com/YGGverse/Yo) - Crawler and search engine for different networks +* [Yoda](https://github.com/YGGverse/Yoda) - Experimental PHP-GTK browser for Gemini protocol +* [gemini-dl](https://github.com/YGGverse/gemini-dl) - CLI downloader for Gemini protocol From b28658d0414431d8b1265c5a12cdd70c4990f0c3 Mon Sep 17 00:00:00 2001 From: yggverse Date: Tue, 25 Jun 2024 00:10:36 +0300 Subject: [PATCH 23/24] update readme --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 6703ebb..34b9e0c 100644 --- a/README.md +++ b/README.md @@ -227,7 +227,7 @@ Network entities validation ## Integrations +* [gemini-dl](https://github.com/YGGverse/gemini-dl) - CLI batch downloader for Gemini protocol * [web-api](https://github.com/YGGverse/web-api) - Network API with native Yggdrasil/IPv6 support * [Yo!](https://github.com/YGGverse/Yo) - Crawler and search engine for different networks * [Yoda](https://github.com/YGGverse/Yoda) - Experimental PHP-GTK browser for Gemini protocol -* [gemini-dl](https://github.com/YGGverse/gemini-dl) - CLI downloader for Gemini protocol From 5ae447bcf0c0915aa9e1cb3ea45bc2b4aa78ddc9 Mon Sep 17 00:00:00 2001 From: yggverse Date: Thu, 11 Jul 2024 10:10:13 +0300 Subject: [PATCH 24/24] fix absolute address detection --- src/Address.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/Address.php b/src/Address.php index d82756a..41d19c6 100644 --- a/src/Address.php +++ b/src/Address.php @@ -83,7 +83,9 @@ class Address public function isAbsolute(): bool { - return ($this->_scheme && $this->_host); + return boolval( + $this->_scheme || $this->_host + ); } public function isRelative(): bool