jasny / http-digest
PSR-7 client and server middleware for HTTP Digest header creation and validation as described in RFC 3230
Requires
- php: >=7.2.0
- improved/improved: ^0.1.0
- psr/http-factory: ^1.0
- psr/http-message: ^1.0
- psr/http-server-middleware: ^1.0
- willdurand/negotiation: ^2.3
Requires (Dev)
- guzzlehttp/guzzle: ^6.3
- jasny/php-code-quality: ^2.3
- php-http/client-common: ^2.0
- php-http/mock-client: ^1.3
This package is auto-updated.
Last update: 2024-10-16 08:51:48 UTC
README
PSR-7 client and server middleware for HTTP Digest header creation and validation as described in RFC 3230. Supports MD5, SHA, SHA-256 and SHA-512 (RFC 5843).
The Digest
header contains a hash of the body.
Digest: SHA=thvDyvhfIqlvFe+A9MYgxAfm1q5=
The Want-Digest message header field indicates the sender's desire to receive an instance digest on messages associated with the Request-URI.
Want-Digest: MD5;q=0.3, SHA;q=1
Installation
composer require jasny/http-digest
Usage
Create the HttpDigest
service to create and verify digests. Give the server priorities for supported algorithms. This
value should be similar to those in the Want-Digest
header.
use Jasny\HttpDigest\HttpDigest; $service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]);
The priorities may also be specified as string.
$service = new HttpDigest("MD5;q=0.3, SHA;q=1");
The service for content negotiating may be created and passes in the constructor for proper DI.
use Jasny\HttpDigest\HttpDigest; $negotiator = new DigestNegotiator(); $service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"], $negotiator);
Creating a digest
You can use the service to create a digest for content.
$digest = $service->create($body);
Verifying a digest
You can use the service to verify the digest.
$service->verify($body, $digest);
If the digest doesn't match or if the algorithm is unsupported, a HttpDigestException
is thrown.
Priorities and the Want-Digest
header
You can change the priorities using withPriorities()
. This will create a new copy of the service.
$newService = $service->withPriorities(["MD5;q=0.3", "SHA;q=0.5", "SHA-256;q=1"]);
To get the configured priorities use getPriorities()
. The getWantDigest()
function returns the priorities in as a
string in the format expected for Wanted-Digest
.
$priorities = $service->getPriorities(); $header = $service->getWantDigest();
Server middleware
Server middleware can be used to verify the digest of PSR-7 requests.
When the middleware is used, requests with a body (like POST
or GET
requests) must contain a Digest
header.
If the Digest
header is missing, invalid or doesn't meet the requirements, the middleware will return a
400 Bad Request
response with a With-Digest
header and the handler will not be called.
Single pass middleware (PSR-15)
The middleware implements the PSR-15 MiddlewareInterface
. As PSR standard many new libraries support this type of
middleware, for example Zend Stratigility.
You're required to supply a PSR-17 response factory,
to create a 400 Bad Request
response for requests with invalid signatures.
use Jasny\HttpDigest\HttpDigest; use Jasny\HttpDigest\ServerMiddleware; use Zend\Stratigility\MiddlewarePipe; use Zend\Diactoros\ResponseFactory; $service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]); $responseFactory = new ResponseFactory(); $middleware = new ServerMiddleware($service, $responseFactory); $app = new MiddlewarePipe(); $app->pipe($middleware);
Double pass middleware
Many PHP libraries support double pass middleware. These are callables with the following signature;
fn(ServerRequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
To get a callback to be used by libraries as Jasny Router and
Relay, use the asDoublePass()
method.
use Jasny\HttpDigest\HttpDigest; use Jasny\HttpDigest\ServerMiddleware; use Relay\RelayBuilder; $service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]); $middleware = new ServerMiddleware($service); $relayBuilder = new RelayBuilder($resolver); $relay = $relayBuilder->newInstance([ $middleware->asDoublePass(), ]); $response = $relay($request, $baseResponse);
Client middleware
Client middleware can be used to sign requests send by PSR-7 compatible HTTP clients like Guzzle and HTTPlug.
use Jasny\HttpDigest\HttpDigest; use Jasny\HttpDigest\ClientMiddleware; $service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]); $middleware = new ClientMiddleware($service);
Double pass middleware
The client middleware can be used by any client that does support double pass middleware. Such middleware are callables with the following signature;
fn(RequestInterface $request, ResponseInterface $response, callable $next): ResponseInterface
Most HTTP clients do not support double pass middleware, but a type of single pass instead. However more general purpose PSR-7 middleware libraries, like Relay, do support double pass.
use Relay\RelayBuilder; $relayBuilder = new RelayBuilder($resolver); $relay = $relayBuilder->newInstance([ $middleware->asDoublePass(), ]); $response = $relay($request, $baseResponse);
The client middleware does not conform to PSR-15 (single pass) as that is intended for server requests only.
Guzzle
Guzzle is the most popular HTTP Client for PHP. The middleware has a forGuzzle()
method
that creates a callback which can be used as Guzzle middleware.
use GuzzleHttp\HandlerStack; use GuzzleHttp\Client; use Jasny\HttpDigest\HttpDigest; use Jasny\HttpDigest\ClientMiddleware; $service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]); $middleware = new ClientMiddleware($service); $stack = new HandlerStack(); $stack->push($middleware->forGuzzle()); $client = new Client(['handler' => $stack]);
HTTPlug
HTTPlug is the HTTP client of PHP-HTTP. It allows you to write reusable libraries and applications that need an HTTP client without binding to a specific implementation.
The forHttplug()
method for the middleware creates an object that can be used as HTTPlug plugin.
use Http\Discovery\HttpClientDiscovery; use Http\Client\Common\PluginClient; use Jasny\HttpDigest\HttpDigest; use Jasny\HttpDigest\ClientMiddleware; $service = new HttpDigest(["MD5;q=0.3", "SHA;q=1"]); $middleware = new ClientMiddleware($service); $pluginClient = new PluginClient( HttpClientDiscovery::find(), [ $middleware->forHttplug(), ] );