Skip to content

Possible new architecture for resolving WebDAV paths #67

@jwodder

Description

@jwodder

WIP design document for a new code architecture

  • Rename DandiDav to Dav

  • Give Dav a register(name: &Component, handler: Box<dyn DavHandler>, description: &str) -> Result<(), DuplicateNameError> method for registering a handler for a WebDAV hierarchy to serve under /{name}/

    • description is used as the "Type" value for the hierarchy in the root HTML view
    • As an alternative to boxing, the type of handler could instead be an enum using enum dispatch.
  • Add a DavHandler trait with the following methods:

    • get_resource(&self, path: Vec<Component>) -> Result<DavResource, DavError>
    • get_resource_with_children(&self, path: Vec<Component>) -> Result<DavResourceWithChildren, DavError>

    Note that path may be empty (i.e., when a client requests /{name}/), and so PurePath cannot be used here.

    Note that these methods will be async, which may have implications for boxability of trait objects; cf. https://blog.rust-lang.org/2023/12/21/async-fn-rpit-in-traits.html.

  • Add a DandiDav struct implementing DavHandler for serving resources under /dandisets/; move all code specific to /dandisets/ here

    • This struct will implement resolution of paths under /dandisets/, currently implemented by the current DandiDav type via DavPath
  • Add a ZarrMan struct implementing DavHandler for serving resources under /zarrs/

  • Idea: The internal implementations of the DavHandler types could traverse their hierarchies as follows:

    • Locations in a handler's hierarchy are represented by an enum with variants for different depths & similar (cf. DavPath and zarrman::ReqPath)

    • The handler instantiates a location enum with the root variant and then applies each component in path in turn by calling an into_child(self, name: Component) -> Result<Self, DavError> method

      • This method returns Err if it can be easily determined (sans IO) that the path so far is invalid/does not exist
    • Details for the final location are then retrieved based on the location enum's final state

  • Whose responsibility is it to prepend the /{name}/ component to hrefs in responses?

    • If the DavHandlers don't prepend it, what would the paths of their root collections be? None?
    • Give DavResource[WithChildren] a prepend_path(&mut self, path: &PureDirPath) method for calling by Dav after delegating to a handler?
    • Idea: Make name(&self) -> &'static str a method of DavHandler, and make it the DavHandlers' responsibility to prepend the name
      • This will be more reasonable if enum dispatch is used instead of boxing.

Sub-issues

Metadata

Metadata

Assignees

No one assigned

    Labels

    code qualityNonfunctional improvements to the codebaseunder considerationDev has not yet decided whether or how to implement

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions