gowebdav

repository·master·Indexed 18 days ago

https://github.com/studio-b12/gowebdav

A Go library and command-line tool for interacting with WebDAV servers. It provides a client for managing remote files and directories via operations such as upload, download, move, and list. The package includes a flexible authentication system supporting Basic, Digest, and Passport 1.4 methods, as well as a CLI tool that supports operations like LS, STAT, MKDIR, GET, PUT, MV, and DEL.

Tokens
7.5K
Snippets
34
Records
40
Agent score
58%

What's inside gowebdav

  1. Create a gowebdav wrapper script

    master

    To simplify usage and securely manage credentials (e.g., using pass), you can create a shell wrapper script. This allows you to run commands against a specific server without manually providing the URL, user, or password every time.

    Example wrapper content:

    #!/bin/sh
    
    ROOT="https://my.dav.server/" \
    USER="foo" \
    PASSWORD="$(pass dav/foo@my.dav.server)" \
    gowebdav $@

    After creating the file, make it executable with chmod a+x <filename>.

  2. Use the gowebdav package

    master
    The gowebdav package is a WebDAV client library that provides programmatic access to WebDAV servers. It also includes a command-line tool for interacting with WebDAV services from the terminal. Developers can import this package into Go projects to perform WebDAV operations like file management and directory traversal.
  3. Configure gowebdav environment variables

    master

    The gowebdav CLI uses environment variables to manage connection details. Setting these improves the user experience by avoiding repetitive arguments.

    Required/Recommended variables:

    • ROOT: The URL of the target WebDAV server (e.g., https://webdav.mydomain.me/user_root_folder).
    • USER: The login username for the server.
    • PASSWORD: The password for the server.
  4. How the Authorizer and Authenticator abstractions work together

    master

    The authentication system is built on two primary abstractions:

    1. Authorizer: A factory for creating authenticators. It manages the available authentication methods and decides which Authenticator to provide for a specific request. It handles the logic of negotiating between multiple possible methods (via negoAuth) or providing a single fixed method (via preemptiveAuthorizer).
    2. Authenticator: Represents a specific authentication mechanism (like Basic or Digest). While an Authorizer manages the strategy, an Authenticator manages the execution of a single request's credentials and the verification of its response.

    The Request Lifecycle: When a request is made, the Authorizer provides an Authenticator (often wrapped in an authShim). The shim ensures that if an authentication round-trip is required (e.g., due to a 401 response), the request body can be re-read (buffered or seeked) to allow the redo operation to succeed.

  5. Use gowebdav CLI commands

    master

    The gowebdav tool uses the -X flag to specify the operation to perform on the remote server.

    Available Operations:

    • LS: List the contents of a specified folder.
    • STAT: Get information about a specific file or folder.
    • MKDIR: Create a new folder.
    • MKDIRALL: Create a directory path including any missing parent directories.
    • GET: Download a file from the server to a local path. If no local path is provided, it downloads to the current directory.
    • PUT: Upload a local file to a specified path on the server.
    • MV: Move or rename a file/folder on the remote server.
    • DEL: Delete a file from the remote server.
    # List folder contents
    gowebdav -X LS temp
    
    # Get file info
    gowebdav -X STAT temp/file.txt
    
    # Create directory
    gowebdav -X MKDIRALL path/to/new/folder
    
    # Download file
    gowebdav -X GET temp/document.rtf /tmp/webdav/document.rtf
    
    # Upload file
    gowebdav -X PUT temp/uploaded.txt /tmp/webdav/to_upload.txt
    
    # Move/Rename file
    gowebdav -X MV temp/file.txt temp/moved_file.txt
    
    # Delete file
    gowebdav -X DEL temp/file.txt
  6. Initialize Digest authentication with NewDigestAuth

    master

    Use NewDigestAuth to create a new DigestAuth instance. This function requires the user's login credentials and an *http.Response object that contains the Www-Authenticate header (typically from a 401 Unauthorized response) to extract necessary digest parameters like nonce, realm, and qop.

    // Assuming 'resp' is an *http.Response received from a 401 challenge
    auth, err := gowebdav.NewDigestAuth("my_user", "my_password", resp)
    if err != nil {
        // handle error
    }
  7. File methods

    master

    The File type provides the following exported methods for retrieving metadata:

    • Path() string: Returns the full path of the file.
    • Name() string: Returns the name of the file.
    • ContentType() string: Returns the MIME content type.
    • Size() int64: Returns the size of the file in bytes.
    • Mode() os.FileMode: Returns the file mode. Directories return 0775 | os.ModeDir; files return 0664.
    • ModTime() time.Time: Returns the last modified time.
    • ETag() string: Returns the ETag.
    • IsDir() bool: Returns true if the item is a directory.
    • Sys() interface{}: Returns nil (placeholder for underlying system data).
    • String() string: Returns a formatted string representation of the file or directory information.
  8. Read directory contents with ReadDir

    master

    The ReadDir(path string) method returns a slice of os.FileInfo representing the contents of the remote directory. It uses PROPFIND to retrieve metadata like name, size, modification time, and whether the item is a collection (directory).

    files, err := client.ReadDir("/remote/path")
    if err != nil {
        log.Fatal(err)
    }
    for _, f := range files {
        fmt.Printf("Name: %s, IsDir: %v, Size: %d\n", f.Name(), f.IsDir(), f.Size())
    }
  9. Verify authentication status with PassportAuth.Verify

    master

    The Verify method checks the response from a server to determine if the authentication session is still valid or if a re-authentication is required. It handles HTTP redirect status codes (301, 302, 307, 308) and 401 Unauthorized errors.

    Returns:

    • redo (bool): If true, the client should retry the request (e.g., after a redirect or re-authentication).
    • err (error): Returns a NewPathError if a 401 Unauthorized is encountered or if authentication fails during a redirect.
    redo, err := auth.Verify(httpClient, response, "/remote/path")
    if err != nil {
        // handle error
    }
    if redo {
        // retry the request
    }
  10. Use preemptive authentication with NewPreemptiveAuth

    master

    If you know exactly which authentication method the server requires and want to avoid the overhead of negotiation, use NewPreemptiveAuth(auth Authenticator). This authorizer will use the provided Authenticator for every request regardless of any Www-Authenticate headers sent by the server.

    Constraints:

    • It only supports a single authentication method.
    • Calling AddAuthenticator on a preemptive authorizer will panic.
    • It is a high-performance implementation without synchronization, making it suitable for BasicAuth even within goroutines.
    // Assuming basicAuth is an existing Authenticator instance
    preemptiveAz := gowebdav.NewPreemptiveAuth(basicAuth)
  11. Configure custom authentication methods with NewEmptyAuth

    master

    If you want full control over which authentication methods are supported, use NewEmptyAuth(). You can then register your own authentication factories using AddAuthenticator(key string, fn AuthFactory). The order in which you add authenticators determines the priority during negotiation (FIFO).

    Warning: Calling AddAuthenticator with a key that is already registered will cause a panic.

    authorizer := gowebdav.NewEmptyAuth()
    
    // Register a custom factory
    authorizer.AddAuthenticator("my-custom-auth", func(c *http.Client, rs *http.Response, path string) (gowebdav.Authenticator, error) {
        return &MyCustomAuth{}, nil
    })