Architecture¶
Every WebDAV request passes through this runtime flow:
Request Pipeline¶
WebDavController::__invoke()accepts the incoming request for/webdav/{space}/{path?}.- If no Basic Auth attempt is present, the controller returns
401 UnauthorizedwithWWW-Authenticate. - If credentials are present,
WebDavServerFactory::make(request)builds the SabreDAV server instance. DefaultRequestContextResolver::resolve(request)gathers the runtime context:RequestBasicCredentialsExtractor::extract(request)parses credentialsValidatorPrincipalAuthenticator::authenticate(username, password)resolves the principal throughCredentialValidatorInterfaceRequestSpaceKeyResolver::resolve(request)resolves{space}or falls back toconfig('webdav-server.storage.default_space')SpaceResolverInterface::resolve(principal, spaceKey)resolves the effective storage target as aWebDavStorageSpaceValueObject; the default implementationDefaultSpaceResolverdelegates path assembly toPathResolverInterface— the formula{root}/{prefix}/{principal.id}lives in exactly one place- the gathered runtime DTO is
RequestContextDto StorageRootBuilder::build(principal, space)creates the SabreDAV root tree:StorageRootCollectionStorageDirectory/StorageFile- Before filesystem operations execute, node classes call
PathAuthorizationInterface. On denial, the package throwsSabre\DAV\Exception\Forbidden. - Allowed operations run against the resolved Laravel filesystem disk.
SabreServerConfigurator::configure(server, spaceKey)applies runtime configuration such as the effective base URI, optional SabreDAV logger wiring, and user-defined tagged SabreDAV plugins in addition to the package defaults.ServerRunnerInterface::run(server)hands off execution to the runtime adapter.- The default adapter
SabreServerRunnerstarts SabreDAV and terminates the request lifecycle.
All extension points are bound via bindIf() in WebdavServerServiceProvider, so app-level bindings can override defaults.
The package architecture is intended to remain SOLID-compliant and to prefer established design patterns such as
Factory, Strategy, Builder, and Adapter where they clearly fit recurring problems.
Note
The runtime pipeline and its extension boundaries are documented as explicit parts of the package design.
Related Decisions¶
- ADR 0001: Test Architecture And Layering
- ADR 0002: WebDAV Request Pipeline And Runtime Boundary
- ADR 0005: WebDAV Space Key And Storage Space Mapping
- ADR 0006: Path Authorization Via Laravel Gates And Policies
- ADR 0007: SabreDAV Runtime Decoupling
- ADR 0008: SOLID Compliance And Established Design Patterns
- ADR 0014: Additional SabreDAV Plugins Via Tagged Service Provider Registration
Runtime Notes¶
- The package registers the route shape
'/webdav/{space}/{path?}'. OPTIONS /webdav/{space}/is routed into SabreDAV so capability discovery reaches the DAV runtime instead of Laravel's method handling.- Root-level
PROPFINDrequests for/webdav/{space}/return normal SabreDAV207 Multi-StatusXML responses, even when the resolved storage root is still empty. spaceKeyis resolved from the{space}route parameter viaRequestSpaceKeyResolver; falls back toconfig('webdav-server.storage.default_space', 'default')if the parameter is absent.- Auth-related extractor/authenticator failures throw domain exceptions:
MissingCredentialsExceptionInvalidCredentialsException- Account and storage resolution also use package exception hierarchies:
AccountNotFoundExceptionAccountDisabledExceptionInvalidAccountConfigurationExceptionSpaceNotConfiguredExceptionInvalidSpaceConfigurationExceptionInvalidDefaultSpaceConfigurationExceptionStreamReadExceptionPathResolverInterfaceowns the user-scoped path assembly formula ({root}/{prefix}/{principal.id});DefaultSpaceResolverdelegates to it and theWebDavPathFacade exposes it to application code.- Controller runtime execution is delegated via
ServerRunnerInterface. - Default runner is
SabreServerRunner, which starts SabreDAV and terminates the request lifecycle. - CSRF bypass is registered in
WebdavServerServiceProvider::registerCsrfException(). - CSRF middleware resolution is version-tolerant:
Illuminate\Foundation\Http\Middleware\PreventRequestForgery(Laravel 13+)- fallback:
Illuminate\Foundation\Http\Middleware\VerifyCsrfToken(Laravel 12) - CSRF route prefix comes from
config('webdav-server.route_prefix')and falls back toconfig('webdav-server.base_uri'). - Base URI for SabreDAV is configured in
SabreServerConfiguratorviaconfig('webdav-server.base_uri', '/webdav/'). - Additional SabreDAV
ServerPlugininstances can be attached from the consuming application by tagging them withWebdavServerServiceProvider::sabrePluginTag(). - Package logging is controlled through
config('webdav-server.logging.driver')andconfig('webdav-server.logging.level', 'info'). - When
logging.driverisnull, package logging and SabreDAV logging are disabled completely. infois used for operational events such as authentication and authorization outcomes.debugis used for request parsing, context resolution, storage resolution, Gate checks, server construction, and SabreDAV runtime configuration.- Additional debug logging traces Windows-relevant DAV handling such as
OPTIONS, rootPROPFIND, request depth, and the effective SabreDAVbaseUri.