Page MenuHomeDevCentral

No OneTemporary

diff --git a/src/HTTP/Requests/WithURL.php b/src/HTTP/Requests/WithURL.php
index fae1a50..5c21db2 100644
--- a/src/HTTP/Requests/WithURL.php
+++ b/src/HTTP/Requests/WithURL.php
@@ -1,87 +1,102 @@
<?php
namespace Keruald\OmniTools\HTTP\Requests;
+use Keruald\OmniTools\HTTP\URL;
use Keruald\OmniTools\Strings\Multibyte\StringUtilities;
trait WithURL {
///
/// Main methods
///
public static function getServerURL () : string {
$scheme = self::getScheme();
$name = self::getServerName();
$port = self::getPort();
// If we forward for a proxy, trust the scheme instead of standard :80
$fixToHTTPS = $port === 80 && $scheme === "https";
if ($port === 443 || $fixToHTTPS) {
return "https://$name";
}
if ($port === 80) {
return "http://$name";
}
return "$scheme://$name:$port";
}
///
/// Helper methods
///
public static function getPort () : int {
return (int)($_SERVER['SERVER_PORT'] ?? 80);
}
public static function getServerName () : string {
return $_SERVER['SERVER_NAME'] ?? "localhost";
}
public static function getScheme () : string {
return $_SERVER['REQUEST_SCHEME']
?? $_SERVER['HTTP_X_FORWARDED_PROTO']
?? $_SERVER['HTTP_X_FORWARDED_PROTOCOL']
?? $_SERVER['HTTP_X_URL_SCHEME']
?? self::guessScheme();
}
private static function guessScheme () : string {
return self::isHTTPS() ? "https" : "http";
}
public static function isHTTPS () : bool {
// Legacy headers have been documented at MDN:
// https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/X-Forwarded-Proto
$headers = self::getHTTPSHeadersTable();
foreach ($headers as $header => $value) {
if (isset($_SERVER[$header]) && $_SERVER[$header] === $value) {
return true;
}
}
if (isset($_SERVER['HTTP_FORWARDED'])) {
return StringUtilities::contains($_SERVER['HTTP_FORWARDED'], "proto=https");
}
return false;
}
private static function getHTTPSHeadersTable () : array {
return [
"HTTPS" => "on",
"REQUEST_SCHEME" => "https",
"SERVER_PORT" => "443",
"HTTP_X_FORWARDED_PROTO" => "https",
"HTTP_FRONT_END_HTTPS" => "on",
"HTTP_X_FORWARDED_PROTOCOL" => "https",
"HTTP_X_FORWARDED_SSL" => "on",
"HTTP_X_URL_SCHEME" => "https",
];
}
+ /**
+ * Create a URL object, using the current request server URL for protocol
+ * and domain name.
+ *
+ * @param string $query The query part of the URL [facultative]
+ * @param int $encodeMode Encoding to use for the query [facultative]
+ */
+ public static function createLocalURL (string $query = "",
+ int $encodeMode = URL::ENCODE_RFC3986_SLASH_EXCEPTED
+ ) : URL {
+ return (new URL(self::getServerURL()))
+ ->setQuery($query, $encodeMode);
+ }
+
}
diff --git a/tests/HTTP/Requests/RequestTest.php b/tests/HTTP/Requests/RequestTest.php
index 4cf958f..672f43f 100644
--- a/tests/HTTP/Requests/RequestTest.php
+++ b/tests/HTTP/Requests/RequestTest.php
@@ -1,137 +1,155 @@
<?php
declare(strict_types=1);
namespace Keruald\OmniTools\Tests\HTTP\Requests;
use Keruald\OmniTools\HTTP\Requests\Request;
use PHPUnit\Framework\TestCase;
class RequestTest extends TestCase {
///
/// Tests
///
/**
* @covers \Keruald\OmniTools\HTTP\Requests\Request::getRemoteAddress
* @backupGlobals enabled
*/
public function testGetRemoteAddress () : void {
$this->assertEmpty(Request::getRemoteAddress());
$_SERVER = [
'REMOTE_ADDR' => '10.0.0.2',
];
$this->assertEquals('10.0.0.2', Request::getRemoteAddress());
$_SERVER += [
'HTTP_X_FORWARDED_FOR' => '10.0.0.3',
'HTTP_CLIENT_IP' => '10.0.0.4',
];
$this->assertEquals(
'10.0.0.3', Request::getRemoteAddress(),
"HTTP_X_FORWARDED_FOR must be prioritized."
);
}
/**
* @covers \Keruald\OmniTools\HTTP\Requests\Request::getClientAddress
* @backupGlobals enabled
*/
public function testGetRemoteAddressWithSeveralAddresses () : void {
$_SERVER = [
'HTTP_X_FORWARDED_FOR' => '10.0.0.2 10.0.0.3',
];
$this->assertEquals('10.0.0.2', Request::getRemoteAddress(),
"HTTP_X_FORWARDED_FOR could contain more than one address, the client one is the first"
);
$_SERVER = [
'HTTP_X_FORWARDED_FOR' => '10.0.0.2, 10.0.0.3',
];
$this->assertEquals('10.0.0.2', Request::getRemoteAddress(),
"HTTP_X_FORWARDED_FOR could contain more than one address, the client one is the first"
);
}
/**
* @covers \Keruald\OmniTools\HTTP\Requests\Request::getAcceptedLanguages
* @backupGlobals enabled
*/
public function testGetAcceptedLanguages () : void {
$_SERVER = [
'HTTP_ACCEPT_LANGUAGE' => 'fr,en-US;q=0.7,en;q=0.3',
];
$this->assertEquals(
["fr", "en-US", "en"],
Request::getAcceptedLanguages()
);
}
/**
* @backupGlobals enabled
* @dataProvider provideServerURLs
*/
public function testGetServerURL (array $server, string $url) : void {
$_SERVER = $server;
$this->assertEquals($url, Request::getServerURL());
}
+ /**
+ * @backupGlobals enabled
+ * @dataProvider provideServerURLs
+ */
+ public function testCreateLocalURL (array $server, string $url) : void {
+ $_SERVER = $server;
+
+ $this->assertEquals(
+ $url . "/",
+ Request::createLocalURL()->__toString()
+ );
+
+ $this->assertEquals(
+ $url . "/foo",
+ Request::createLocalURL("foo")->__toString()
+ );
+ }
+
///
/// Data providers
///
public function provideServerURLs () : iterable {
yield [[], "http://localhost"];
yield [["UNRELATED" => "ANYTHING"], "http://localhost"];
yield [
[
"SERVER_PORT" => "80",
"SERVER_NAME" => "acme.tld",
],
"http://acme.tld"
];
yield [
[
"SERVER_PORT" => "443",
"SERVER_NAME" => "acme.tld",
],
"https://acme.tld"
];
yield [
[
"SERVER_PORT" => "80",
"SERVER_NAME" => "acme.tld",
"HTTP_X_FORWARDED_PROTO" => "https",
],
"https://acme.tld"
];
yield [
[
"SERVER_PORT" => "80",
"SERVER_NAME" => "acme.tld",
"HTTP_FORWARDED" => "for=192.0.2.43, for=\"[2001:db8:cafe::17]\", proto=https, by=203.0.113.43",
],
"https://acme.tld"
];
yield [
[
"SERVER_PORT" => "8443",
"SERVER_NAME" => "acme.tld",
"HTTPS" => "on",
],
"https://acme.tld:8443"
];
}
}

File Metadata

Mime Type
text/x-diff
Expires
Thu, Sep 18, 11:17 (13 h, 42 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2990627
Default Alt Text
(7 KB)

Event Timeline