Skip to content
This repository has been archived by the owner on Jun 30, 2020. It is now read-only.

Filter list of acceptable headers; use default if the client accepts everything #81

Merged
merged 6 commits into from
Aug 22, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
21 changes: 21 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -711,6 +711,27 @@ $middlewares = [
];
```

You can optionally specify the formats which your server supports, in priority order, with the first element being the default.

```php
//This will only negotiate html, pdf and xml. html is the default.
Middleware::FormatNegotiator([
'html' => [['html', 'htm', 'php'], ['text/html', 'application/xhtml+xml']],
'pdf' => [['pdf'], ['application/pdf', 'application/x-download']],
'xml' => [['xml'], ['text/xml', 'application/xml', 'application/x-xml']]
])
```

If the client requests a format which is not supported by the server, then the default format will be used. If you wish to generate a 406 Not Acceptable response instead, set the default format to null.

```php
//This will generate a 406 Not Acceptable response if the client requests anything other than html.
Middleware::FormatNegotiator([
'html' => [['html', 'htm', 'php'], ['text/html', 'application/xhtml+xml']]
])
->defaultFormat(null)
```

### FormTimestamp

Simple spam protection based on injecting a hidden input in all post forms with the current timestamp. On submit the form, check the time value. If it's less than (for example) 3 seconds ago, assumes it's a bot, so returns a 403 response. You can also set a max number of seconds before the form expires.
Expand Down
44 changes: 33 additions & 11 deletions src/Middleware/FormatNegotiator.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ class FormatNegotiator
/**
* @var string Default format
*/
private $default = 'html';
private $default;

/**
* @var array Available formats with the mime types
Expand Down Expand Up @@ -111,18 +111,35 @@ public function addFormat($format, array $mimeTypes, array $extensions = null)

/**
* Set the default format.
* Set this to null if you want a 406 Not Acceptable response to be generated if no valid format was found.
*
* @param string $format
* @param string|null $format
*
* @return self
*/
public function defaultFormat($format)
{
$this->default = $format;

if (isset($this->formats[$format])) {
$item = $this->formats[$format];
$this->formats = [$format => $item] + $this->formats;
}

return $this;
}

/**
* @param array|null $formats Formats which the server supports, in priority order.
*/
public function __construct($formats = null)
{
if (!empty($formats)) {
$this->formats = $formats;
}
$this->default = key($this->formats);
}

/**
* Execute the middleware.
*
Expand All @@ -135,15 +152,20 @@ public function defaultFormat($format)
public function __invoke(ServerRequestInterface $request, ResponseInterface $response, callable $next)
{
$format = $this->getFromExtension($request) ?: $this->getFromHeader($request) ?: $this->default;
$contentType = $this->formats[$format][1][0].'; charset=utf-8';

$response = $next(
self::setAttribute($request, self::KEY, $format),
$response->withHeader('Content-Type', $contentType)
);

if (!$response->hasHeader('Content-Type')) {
$response = $response->withHeader('Content-Type', $contentType);
if (empty($format)) {
//If no valid accept type was found, and no default was specified, then return 406 Not Acceptable.
$response = $response->withStatus(406);
} else {
$contentType = $this->formats[$format][1][0].'; charset=utf-8';

$response = $next(
self::setAttribute($request, self::KEY, $format),
$response->withHeader('Content-Type', $contentType)
);

if (!$response->hasHeader('Content-Type')) {
$response = $response->withHeader('Content-Type', $contentType);
}
}

return $response;
Expand Down