________________________________________________________________________

This file is part of Logtalk <https://logtalk.org/>
SPDX-FileCopyrightText: 1998-2026 Paulo Moura <pmoura@logtalk.org>
SPDX-License-Identifier: Apache-2.0

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

    http://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
________________________________________________________________________


`http_digest`
=============

This library provides HTTP Digest authentication helpers on top of the
normalized HTTP stack.

This library can be used with backend Prolog systems that support unbound
integer arithmetic and the `sockets` library: ECLiPSe, SICStus Prolog,
SWI-Prolog, Trealla Prolog, and XVM.


API documentation
-----------------

Open the [../../apis/library_index.html#http_digest](../../apis/library_index.html#http_digest)
link in a web browser.


Loading
-------

To load the library, load the `loader.lgt` file:

	| ?- logtalk_load(http_digest(loader)).


Testing
-------

To test this library, load the `tester.lgt` file:

	| ?- logtalk_load(http_digest(tester)).


Usage overview
--------------

The library provides these public entities:

- `http_digest_verifier_protocol`
	server-side verifier protocol for looking up stored Digest HA1 values
- `http_digest`
	core Digest parsing, generation, request authorization, request protection,
	challenge building, and `Authentication-Info` response decoration
- `http_server_core_digest_handler(_, _, _, _)`
	portable handler wrapper that applies Digest protection and response
	decoration around another object implementing `http_handler_protocol`
- `http_router_digest_auth(_, _, _)`
	router companion category that protects routes declaring `digest_auth/1`
	metadata and decorates successful protected responses with
	`Authentication-Info`
- `http_client_digest_session`
	stateful client helper that preserves cookies and retries once when the
	server replies with a `401` Digest challenge

The library design keeps the Digest core object stateless and deterministic.
State is kept only where it is operationally useful: in verifier objects
supplied by applications and in the optional client-side session helper used
for cookie storage.

The server-side entities are portable across the backends supported by the
normalized HTTP library. The `http_client_digest_session` helper additionally
depends on the socket-backed HTTP client stack and is therefore available on
the same backends supported by the `http_client` and `http_socket_transport` libraries.

Use `http_digest` directly when you need explicit control over Digest
challenge parsing and request verification:

	| ?- http_digest::unauthorized_response(Challenge, Response, [realm('private'), nonce_secret('secret')]).

Wrap a normal handler with `http_server_core_digest_handler(_, _, _, _)` when you
want a portable middleware-style integration point for Digest verification:

	| ?- Handler = http_server_core_digest_handler(verifier, app_handler, [realm('private'), nonce_secret('secret')], []).

Use `http_router_digest_auth(_, _, _)` in router objects importing
`http_router` when you want per-route protection driven by normal route
metadata:

	authorize_routed_request(Request, Action) :-
		^^authorize_digest_auth_request(Request, Action).

	response_middleware(digest_authentication_info, add_digest_authentication_info).

	route_metadata(show_secret, [digest_auth([])]).

Use `http_client_digest_session` when you need cookie persistence plus
automatic retry after a `401` Digest challenge:

	| ?- http_client_digest_session::open(Session, 'Mufasa', 'Circle Of Life'),
	     http_client_digest_session::get(Session, 'http://127.0.0.1:8080/protected', Response, []),
	     http_client_digest_session::close(Session).

The current client helper is reactive: it sends the initial request without an
`Authorization` header and retries automatically only after receiving a Digest
challenge. This keeps the helper small and avoids maintaining speculative
challenge caches inside the client session state.

For `add_authentication_info/4`, the `nextnonce` option accepts three forms:

- `nextnonce(false)` omits the `nextnonce` field
- `nextnonce(true)` generates a fresh nonce using `nonce_secret/1`
- `nextnonce(Nonce)` emits the explicit nonce atom verbatim


Current scope
-------------

- deterministic Digest header parsing and generation for challenges,
  authorizations, and `Authentication-Info`
- `auth` and `auth-int` quality-of-protection request and response digest
	computation, with `auth-int` hashing transfer-decoded entity-body bytes
- server-side request protection through explicit verifier objects
- middleware-style handler wrapping for server integration
- route-level protection and successful-response `Authentication-Info`
	decoration through `http_router_digest_auth(_, _, _)` plus the
	`authorize_routed_request/2` and `response_middleware/2` router hooks
- client-side Digest retry on top of the existing socket-backed transport and
	cookie-jar support, including `https://` URLs when the selected transport
	parameterization supports secure schemes
- MD5, SHA-256, and SHA-512-256 based Digest computations through the `hashes`
	and `hmac` libraries; when no algorithm option is provided, the default
	challenge algorithm remains `sha256`


Non-implemented features
------------------------

- proactive client-side challenge caching across requests
- shared or persistent nonce replay stores
