Skip to content

Commit 56175df

Browse files
authored
Move Content Type header values to a separate class (#47)
This will make it easier to use those in projects where `SecurityTxt` as a name is already a thing, to avoid at least some conflicts. Better naming as a bonus: add "parameter" suffix to "charset" where it makes sense: "Charset" is just `utf-8`, while "charset parameter" is the whole string `charset=utf-8` as per RFC 9110.
2 parents 96fea4d + 71f7a16 commit 56175df

10 files changed

+50
-38
lines changed

README.md

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,12 @@ By default, values are validated when set, and an exception is thrown when they'
111111
- `AllowInvalidValues` (an exception will be thrown but the value will still be set)
112112
- `AllowInvalidValuesSilently` (an exception will not be thrown, and the value will be set)
113113

114-
You can use the following `SecurityTxt` constants to serve the file with correct HTTP content type:
115-
- `SecurityTxt::CONTENT_TYPE_HEADER`, the value to be sent as `Content-Type` header value (`text/plain; charset=utf-8`);
116-
- `SecurityTxt::CONTENT_TYPE`, the correct content type `text/plain`
117-
- `SecurityTxt::CHARSET`, the correct charset as `charset=utf-8`
114+
## Content type
115+
You can use the following `SecurityTxtContentType` constants to serve the file with correct HTTP content type:
116+
- `SecurityTxtContentType::MEDIA_TYPE`, the value to be sent as `Content-Type` header value (`text/plain; charset=utf-8`);
117+
- `SecurityTxtContentType::CONTENT_TYPE`, the correct content type `text/plain`
118+
- `SecurityTxtContentType::CHARSET`, the charset `utf-8`
119+
- `SecurityTxtContentType::CHARSET_PARAMETER`, the correct charset parameter name and value as `charset=utf-8`
118120

119121
## Example
120122
```php

src/Fetcher/SecurityTxtContentType.php renamed to src/Fetcher/SecurityTxtFetchHostContentType.php

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Spaze\SecurityTxt\Fetcher;
55

6-
final readonly class SecurityTxtContentType
6+
final readonly class SecurityTxtFetchHostContentType
77
{
88

99
/**
@@ -14,15 +14,15 @@
1414
/**
1515
* @var lowercase-string|null
1616
*/
17-
private ?string $lowercaseCharset;
17+
private ?string $lowercaseCharsetParameter;
1818

1919

2020
public function __construct(
2121
private string $contentType,
22-
private ?string $charset,
22+
private ?string $charsetParameter,
2323
) {
2424
$this->lowercaseContentType = strtolower(trim($this->contentType));
25-
$this->lowercaseCharset = $this->charset !== null ? strtolower(trim($this->charset)) : null;
25+
$this->lowercaseCharsetParameter = $this->charsetParameter !== null ? strtolower(trim($this->charsetParameter)) : null;
2626
}
2727

2828

@@ -32,9 +32,9 @@ public function getContentType(): string
3232
}
3333

3434

35-
public function getCharset(): ?string
35+
public function getCharsetParameter(): ?string
3636
{
37-
return $this->charset;
37+
return $this->charsetParameter;
3838
}
3939

4040

@@ -50,9 +50,9 @@ public function getLowercaseContentType(): string
5050
/**
5151
* @return lowercase-string|null
5252
*/
53-
public function getLowercaseCharset(): ?string
53+
public function getLowercaseCharsetParameter(): ?string
5454
{
55-
return $this->lowercaseCharset;
55+
return $this->lowercaseCharsetParameter;
5656
}
5757

5858
}

src/Fetcher/SecurityTxtFetcher.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
use Spaze\SecurityTxt\Fetcher\HttpClients\SecurityTxtFetcherHttpClient;
1818
use Spaze\SecurityTxt\Parser\SecurityTxtSplitLines;
1919
use Spaze\SecurityTxt\Parser\SecurityTxtUrlParser;
20-
use Spaze\SecurityTxt\SecurityTxt;
20+
use Spaze\SecurityTxt\SecurityTxtContentType;
2121
use Spaze\SecurityTxt\Violations\SecurityTxtContentTypeInvalid;
2222
use Spaze\SecurityTxt\Violations\SecurityTxtContentTypeWrongCharset;
2323
use Spaze\SecurityTxt\Violations\SecurityTxtTopLevelDiffers;
@@ -213,10 +213,10 @@ private function getResult(SecurityTxtFetcherFetchHostResult $wellKnown, Securit
213213
$this->callOnCallback($this->onFinalUrl, $result->getFinalUrl());
214214

215215
$contentTypeHeader = $result->getContentType();
216-
if ($contentTypeHeader === null || $contentTypeHeader->getLowercaseContentType() !== SecurityTxt::CONTENT_TYPE) {
216+
if ($contentTypeHeader === null || $contentTypeHeader->getLowercaseContentType() !== SecurityTxtContentType::CONTENT_TYPE) {
217217
$errors[] = new SecurityTxtContentTypeInvalid($result->getUrl(), $contentTypeHeader?->getContentType());
218-
} elseif ($contentTypeHeader->getLowercaseCharset() !== SecurityTxt::CHARSET) {
219-
$errors[] = new SecurityTxtContentTypeWrongCharset($result->getUrl(), $contentTypeHeader->getContentType(), $contentTypeHeader->getCharset());
218+
} elseif ($contentTypeHeader->getLowercaseCharsetParameter() !== SecurityTxtContentType::CHARSET_PARAMETER) {
219+
$errors[] = new SecurityTxtContentTypeWrongCharset($result->getUrl(), $contentTypeHeader->getContentType(), $contentTypeHeader->getCharsetParameter());
220220
}
221221
return new SecurityTxtFetchResult(
222222
$result->getUrl(),

src/Fetcher/SecurityTxtFetcherFetchHostResult.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@
99
final readonly class SecurityTxtFetcherFetchHostResult
1010
{
1111

12-
private ?SecurityTxtContentType $contentType;
12+
private ?SecurityTxtFetchHostContentType $contentType;
1313

1414
private ?string $contents;
1515

@@ -32,7 +32,7 @@ public function __construct(
3232
$this->contentType = null;
3333
} else {
3434
$parts = explode(';', $header, 2);
35-
$this->contentType = new SecurityTxtContentType($parts[0], $parts[1] ?? null);
35+
$this->contentType = new SecurityTxtFetchHostContentType($parts[0], $parts[1] ?? null);
3636
}
3737
$this->contents = $response?->getContents();
3838
$this->isTruncated = $response !== null && $response->isTruncated();
@@ -78,7 +78,7 @@ public function isTruncated(): bool
7878
}
7979

8080

81-
public function getContentType(): ?SecurityTxtContentType
81+
public function getContentType(): ?SecurityTxtFetchHostContentType
8282
{
8383
return $this->contentType;
8484
}

src/SecurityTxt.php

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,6 @@
4040
final class SecurityTxt implements JsonSerializable
4141
{
4242

43-
public const string CONTENT_TYPE = 'text/plain';
44-
public const string CHARSET = 'charset=utf-8';
45-
public const string CONTENT_TYPE_HEADER = self::CONTENT_TYPE . '; ' . self::CHARSET;
46-
4743
private ?string $fileLocation = null;
4844
private ?SecurityTxtExpires $expires = null;
4945
private ?SecurityTxtSignatureVerifyResult $signatureVerifyResult = null;

src/SecurityTxtContentType.php

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?php
2+
declare(strict_types = 1);
3+
4+
namespace Spaze\SecurityTxt;
5+
6+
final readonly class SecurityTxtContentType
7+
{
8+
9+
public const string CONTENT_TYPE = 'text/plain';
10+
public const string CHARSET = 'utf-8';
11+
public const string CHARSET_PARAMETER = 'charset=' . self::CHARSET;
12+
public const string MEDIA_TYPE = self::CONTENT_TYPE . '; ' . self::CHARSET_PARAMETER;
13+
14+
}

src/Violations/SecurityTxtContentTypeInvalid.php

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44
namespace Spaze\SecurityTxt\Violations;
55

6-
use Spaze\SecurityTxt\SecurityTxt;
6+
use Spaze\SecurityTxt\SecurityTxtContentType;
77

88
final class SecurityTxtContentTypeInvalid extends SecurityTxtSpecViolation
99
{
@@ -12,19 +12,19 @@ public function __construct(string $uri, ?string $contentType)
1212
{
1313
if ($contentType !== null) {
1414
$format = 'The file at %s has a %s of %s but it should be a %s of %s with the %s parameter set to %s';
15-
$values = [$uri, 'Content-Type', $contentType, 'Content-Type', SecurityTxt::CONTENT_TYPE, 'charset', SecurityTxt::CHARSET];
15+
$values = [$uri, 'Content-Type', $contentType, 'Content-Type', SecurityTxtContentType::CONTENT_TYPE, 'charset', SecurityTxtContentType::CHARSET_PARAMETER];
1616
} else {
1717
$format = 'The file at %s has no %s but it should be a %s of %s with the %s parameter set to %s';
18-
$values = [$uri, 'Content-Type', 'Content-Type', SecurityTxt::CONTENT_TYPE, 'charset', SecurityTxt::CHARSET];
18+
$values = [$uri, 'Content-Type', 'Content-Type', SecurityTxtContentType::CONTENT_TYPE, 'charset', SecurityTxtContentType::CHARSET_PARAMETER];
1919
}
2020
parent::__construct(
2121
func_get_args(),
2222
$format,
2323
$values,
2424
'draft-foudil-securitytxt-03',
25-
SecurityTxt::CONTENT_TYPE_HEADER,
25+
SecurityTxtContentType::MEDIA_TYPE,
2626
'Send a correct %s header value of %s with the %s parameter set to %s',
27-
['Content-Type', SecurityTxt::CONTENT_TYPE, 'charset', SecurityTxt::CHARSET],
27+
['Content-Type', SecurityTxtContentType::CONTENT_TYPE, 'charset', SecurityTxtContentType::CHARSET_PARAMETER],
2828
'3',
2929
);
3030
}

src/Violations/SecurityTxtContentTypeWrongCharset.php

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -3,24 +3,24 @@
33

44
namespace Spaze\SecurityTxt\Violations;
55

6-
use Spaze\SecurityTxt\SecurityTxt;
6+
use Spaze\SecurityTxt\SecurityTxtContentType;
77

88
final class SecurityTxtContentTypeWrongCharset extends SecurityTxtSpecViolation
99
{
1010

11-
public function __construct(string $uri, string $contentType, ?string $charset)
11+
public function __construct(string $uri, string $contentType, ?string $charsetParameter)
1212
{
13-
$format = $charset !== null
13+
$format = $charsetParameter !== null
1414
? 'The file at %s has a correct %s of %s but the %s parameter should be changed to %s'
1515
: 'The file at %s has a correct %s of %s but the %s parameter is missing';
1616
parent::__construct(
1717
func_get_args(),
1818
$format,
19-
$charset !== null ? [$uri, 'Content-Type', $contentType, $charset, SecurityTxt::CHARSET] : [$uri, 'Content-Type', $contentType, SecurityTxt::CHARSET],
19+
$charsetParameter !== null ? [$uri, 'Content-Type', $contentType, $charsetParameter, SecurityTxtContentType::CHARSET_PARAMETER] : [$uri, 'Content-Type', $contentType, SecurityTxtContentType::CHARSET_PARAMETER],
2020
'draft-foudil-securitytxt-03',
21-
SecurityTxt::CONTENT_TYPE_HEADER,
22-
$charset !== null ? 'Change the parameter to %s' : 'Add a %s parameter',
23-
[SecurityTxt::CHARSET],
21+
SecurityTxtContentType::MEDIA_TYPE,
22+
$charsetParameter !== null ? 'Change the parameter to %s' : 'Add a %s parameter',
23+
[SecurityTxtContentType::CHARSET_PARAMETER],
2424
'3',
2525
);
2626
}

tests/Fetcher/SecurityTxtFetcherFetchHostResultTest.phpt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ final class SecurityTxtFetcherFetchHostResultTest extends TestCase
2121
$contentType = $wellKnown->getContentType();
2222
assert($contentType !== null);
2323
Assert::same('text/html', $contentType->getLowercaseContentType());
24-
Assert::same('charset=win-1337', $contentType->getLowercaseCharset());
24+
Assert::same('charset=win-1337', $contentType->getLowercaseCharsetParameter());
2525
}
2626

2727
}

tests/Fetcher/SecurityTxtFetcherTest.phpt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ use Spaze\SecurityTxt\Fetcher\Exceptions\SecurityTxtTooManyRedirectsException;
1515
use Spaze\SecurityTxt\Fetcher\HttpClients\SecurityTxtFetcherHttpClient;
1616
use Spaze\SecurityTxt\Parser\SecurityTxtSplitLines;
1717
use Spaze\SecurityTxt\Parser\SecurityTxtUrlParser;
18-
use Spaze\SecurityTxt\SecurityTxt;
18+
use Spaze\SecurityTxt\SecurityTxtContentType;
1919
use Spaze\SecurityTxt\Violations\SecurityTxtTopLevelDiffers;
2020
use Tester\Assert;
2121
use Tester\TestCase;
@@ -232,7 +232,7 @@ final class SecurityTxtFetcherTest extends TestCase
232232
{
233233
$httpClient = $this->getHttpClient(new SecurityTxtFetcherResponse(123, [], 'random', false));
234234
$fetcher = new SecurityTxtFetcher($httpClient, $this->urlParser, $this->splitLines);
235-
$fetcherResponseWellKnown = new SecurityTxtFetcherResponse(200, ['content-type' => SecurityTxt::CONTENT_TYPE_HEADER], $contentsWellKnown, false);
235+
$fetcherResponseWellKnown = new SecurityTxtFetcherResponse(200, ['content-type' => SecurityTxtContentType::MEDIA_TYPE], $contentsWellKnown, false);
236236
$fetcherResponseTopLevel = new SecurityTxtFetcherResponse(200, [], $contentsTopLevel, false);
237237
$wellKnown = new SecurityTxtFetcherFetchHostResult('https://url1.example/', $finalUrlWellKnown, '192.0.2.1', DNS_A, 200, $fetcherResponseWellKnown);
238238
$topLevel = new SecurityTxtFetcherFetchHostResult('https://url2.example/', $finalUrlTopLevel, '198.51.100.1', DNS_A, 200, $fetcherResponseTopLevel);

0 commit comments

Comments
 (0)