Skip to content

Commit c2f686a

Browse files
authored
Implement "Followup improvements for ext/uri" RFC - URL building with base URL (#23526)
Add support for passing a non-null $baseUrl parameter for Uri\WhatWg\UrlBuilder::build(). RFC: https://wiki.php.net/rfc/uri_followup#uri_building
1 parent d2493f6 commit c2f686a

35 files changed

Lines changed: 911 additions & 35 deletions

‎ext/uri/php_uri.c‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1425,8 +1425,6 @@ PHP_METHOD(Uri_WhatWg_UrlBuilder, build)
14251425

14261426
lxb_url_t *base_url = NULL;
14271427
if (base_url_zv != NULL) {
1428-
zend_argument_error(NULL, 1, "is not supported yet, and therefore, null must be passed");
1429-
RETURN_THROWS();
14301428
base_url = Z_URI_OBJECT_P(base_url_zv)->uri;
14311429
}
14321430

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
--TEST--
2+
Test Uri\WhatWg\UrlBuilder::build() - success - replaces the base authority with encoded credentials
3+
--FILE--
4+
<?php
5+
6+
$base = new Uri\WhatWg\Url("https://old:secret@example.com:81/a?old#old");
7+
$builder = new Uri\WhatWg\UrlBuilder();
8+
$builder->setHost("example.net");
9+
$builder->setUsername("a@b");
10+
$builder->setPassword("c:d");
11+
$url = $builder->build($base);
12+
13+
var_dump($url->toAsciiString());
14+
var_dump($url->equals(new Uri\WhatWg\Url($url->toAsciiString())));
15+
var_dump($base->toAsciiString());
16+
17+
?>
18+
--EXPECT--
19+
string(32) "https://a%40b:c%3Ad@example.net/"
20+
bool(true)
21+
string(43) "https://old:secret@example.com:81/a?old#old"
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
--TEST--
2+
Test Uri\WhatWg\UrlBuilder::build() - error - empty reference with an opaque base
3+
--FILE--
4+
<?php
5+
6+
$base = new Uri\WhatWg\Url("foo:opaque?old#old");
7+
$builder = new Uri\WhatWg\UrlBuilder();
8+
9+
try {
10+
$builder->build($base);
11+
} catch (Throwable $e) {
12+
echo $e::class, ': ', $e->getMessage(), "\n";
13+
var_dump($e->errors[0]->type);
14+
}
15+
16+
?>
17+
--EXPECT--
18+
Uri\WhatWg\InvalidUrlException: The specified path is malformed (MissingSchemeNonRelativeUrl)
19+
enum(Uri\WhatWg\UrlValidationErrorType::MissingSchemeNonRelativeUrl)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Test Uri\WhatWg\UrlBuilder basic - error - with base URL containing opaque path
3+
--FILE--
4+
<?php
5+
6+
$builder = new Uri\WhatWg\UrlBuilder();
7+
$builder->setPath("/foo/bar/baz");
8+
9+
try {
10+
$builder->build(new Uri\WhatWg\Url("scheme:opaque-path"));
11+
} catch (Throwable $e) {
12+
echo $e::class, ': ', $e->getMessage(), "\n";
13+
}
14+
15+
?>
16+
--EXPECT--
17+
Uri\WhatWg\InvalidUrlException: The specified path is malformed (MissingSchemeNonRelativeUrl)
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
--TEST--
2+
Test Uri\WhatWg\UrlBuilder::build() - success - inherits the path and query but not the fragment
3+
--FILE--
4+
<?php
5+
6+
$base = new Uri\WhatWg\Url("https://example.com/a?old#old");
7+
$builder = new Uri\WhatWg\UrlBuilder();
8+
9+
$url = $builder->build($base);
10+
11+
var_dump($url->toAsciiString());
12+
var_dump($url->equals(new Uri\WhatWg\Url($url->toAsciiString())));
13+
14+
?>
15+
--EXPECT--
16+
string(25) "https://example.com/a?old"
17+
bool(true)

‎ext/uri/tests/whatwg/builder/basic_success_with_base.phpt‎

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
--TEST--
22
Test Uri\WhatWg\UrlBuilder basic - success - with base URL
3-
--XFAIL--
4-
Support for passing $baseUrl to Uri\WhatWg\UrlBuilder::build() is not implemented yet.
53
--FILE--
64
<?php
75

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
--TEST--
2+
Test Uri\WhatWg\UrlBuilder basic - success - with scheme relative URL
3+
--FILE--
4+
<?php
5+
6+
$builder = new Uri\WhatWg\UrlBuilder();
7+
$builder->setHost("example.net");
8+
$builder->setPath("/foo/bar/baz");
9+
$builder->setPort(124);
10+
$url = $builder->build(new Uri\WhatWg\Url("https://user:pass@example.com:123/foo/bar?query#hash"));
11+
12+
var_dump($url->toAsciiString());
13+
var_dump($url);
14+
var_dump($url->equals(new Uri\WhatWg\Url($url->toAsciiString())));
15+
16+
?>
17+
--EXPECTF--
18+
string(35) "https://example.net:124/foo/bar/baz"
19+
object(Uri\WhatWg\Url)#%d (%d) {
20+
["scheme"]=>
21+
string(5) "https"
22+
["username"]=>
23+
NULL
24+
["password"]=>
25+
NULL
26+
["host"]=>
27+
string(11) "example.net"
28+
["port"]=>
29+
int(124)
30+
["path"]=>
31+
string(12) "/foo/bar/baz"
32+
["query"]=>
33+
NULL
34+
["fragment"]=>
35+
NULL
36+
}
37+
bool(true)
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
--TEST--
2+
Test Uri\WhatWg\UrlBuilder::build() - error - preserves soft errors output with an opaque base URL
3+
--FILE--
4+
<?php
5+
6+
$builder = new Uri\WhatWg\UrlBuilder();
7+
$builder->setPath("/a\tb");
8+
$softErrors = ["previous error"];
9+
10+
try {
11+
$builder->build(new Uri\WhatWg\Url("foo:opaque"), $softErrors);
12+
} catch (Throwable $e) {
13+
echo $e::class, ': ', $e->getMessage(), "\n";
14+
foreach ($e->errors as $error) {
15+
var_dump($error->type);
16+
}
17+
}
18+
19+
var_dump($softErrors);
20+
21+
?>
22+
--EXPECT--
23+
Uri\WhatWg\InvalidUrlException: The specified path is malformed (MissingSchemeNonRelativeUrl)
24+
enum(Uri\WhatWg\UrlValidationErrorType::MissingSchemeNonRelativeUrl)
25+
enum(Uri\WhatWg\UrlValidationErrorType::InvalidUrlUnit)
26+
array(0) {
27+
}

ext/uri/tests/whatwg/builder/build_error_soft_errors_reset.phpt renamed to ext/uri/tests/whatwg/builder/build_error_soft_errors_reset_without_base.phpt

File renamed without changes.
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
--TEST--
2+
Test Uri\WhatWg\UrlBuilder::build() - error - soft errors assigned to a typed property with a base URL
3+
--FILE--
4+
<?php
5+
6+
class Foo {
7+
public string $errors = "unchanged";
8+
}
9+
10+
$foo = new Foo();
11+
$builder = new Uri\WhatWg\UrlBuilder();
12+
$builder->setFragment("a\tb");
13+
try {
14+
$builder->build(new Uri\WhatWg\Url("https://example.com/"), $foo->errors);
15+
} catch (Throwable $e) {
16+
echo $e::class, ': ', $e->getMessage(), "\n";
17+
}
18+
var_dump($foo->errors);
19+
20+
?>
21+
--EXPECT--
22+
TypeError: Cannot assign array to reference held by property Foo::$errors of type string
23+
string(9) "unchanged"

0 commit comments

Comments
 (0)