soap-server
A WSDL-driven SOAP 1.1/1.2 server library for Rust, built on top of axum.
Provide a WSDL file, register async handler closures for each operation, and get a
SOAP 1.1/1.2 endpoint with no boilerplate envelope handling. soap-server is a
transport + dispatch layer (not a code generator or full XSD validator) — see
Capabilities & Limitations
for exactly what it does and does not do.
Features
- SOAP 1.1 and 1.2 — auto-detects version from the
Content-Typeheader and envelope namespace; responds in the same version as the incoming request. - WSDL-driven dispatch — operations are discovered from the WSDL at server build time.
Registering a handler for an operation name that does not exist in the WSDL causes
.build()to returnErr— no runtime panics on misnamed operations. - WS-Security (UsernameToken) — supports
PasswordDigestandPasswordTextauthentication with nonce replay detection and timestamp freshness checks. - XSD structural validation — required elements in the request body are validated against the WSDL/XSD schema before the handler is called.
Installation
soap-server runs on a Tokio runtime; adding tokio with the
full feature is the simplest way to provide one.
Quick Start
use ;
use Bytes;
async
ServerBuilder::from_wsdl_fileloads and parses the WSDL. The builder also accepts raw bytes or a customWsdlLoaderimplementation..handler("MyOperation", ...)registers an async handler. TheBytesyour closure receives is the SOAP Body's first child element as self-contained XML (ancestor namespace declarations are re-emitted on the fragment root). ReturnOk(Bytes)with the response body element (no enclosing envelope needed) orErr(SoapFault)..build()validates all registered operation names against the WSDL and returnsResult<SoapService, BuildError>.svc.into_router()returns anaxum::Routermounted at the URL from the WSDL<service><port address>element.
WS-Security
Call .auth(...) on the builder to require UsernameToken authentication on all
operations:
use ;
use Bytes;
async
- The
.authclosure receives the username from<wsse:UsernameToken>and returns the expected plaintext password (Noneto deny). Digest comparison is performed internally with constant-time equality. - Both
PasswordTextandPasswordDigest(Base64(SHA-1(nonce + created + password))) are accepted. - Nonce replay detection uses a rotating in-memory cache with a default window of 300 s. Timestamp freshness is enforced to ±300 s.
.auth_bypass(["..."])exempts named operations from the security header requirement (useful for clock-sync or discovery operations).- Operations with a missing or invalid
<wsse:Security>header receive aSenderfault.
Multi-WSDL / Multi-Service
Build each service separately and merge the resulting axum::Router instances. Each router
mounts at its own path derived from the respective WSDL:
use ServerBuilder;
async
Documentation
- API reference: https://docs.rs/soap-server
- User guide (mdBook): https://navistau.github.io/soap-server/
Contributing
See CONTRIBUTING.md.
License
Licensed under either of:
at your option.
Unless you explicitly state otherwise, any contribution intentionally submitted for inclusion in this crate by you shall be dual-licensed as above, without any additional terms or conditions.
Copyright Joshua Hogendorn / NavistAu.