cvanloo / rmsgo

Remote Storage implementation in Go

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Go remoteStorage Library

An implementation of the remoteStorage protocol written in Go.

go get -u github.com/cvanloo/rmsgo

Example Usage

package main

import (
    "os"
    "github.com/cvanloo/rmsgo"
)

const (
    PersistFile = "/var/rms/persist"
    RemoteRoot  = "/storage/"
    StorageRoot = "/var/rms/storage/"
)

func main() {
    opts, err := rmsgo.Configure(RemoteRoot, StorageRoot)
    if err != nil {
        log.Fatal(err)
    }
    opts.UseErrorHandler(func(err error) {
        log.Fatalf("remote storage: unhandled error: %v", err)
    })
    opts.UseAuthentication(func(r *http.Request, bearer string) (rmsgo.User, bool) {
        // [!] TODO: Your authentication logic here...
        //       Return one of your own users.
        return rmsgo.UserReadWrite{}, true
    })

    persistFile, err := os.Open(PersistFile)
    if err != nil {
        log.Fatal(err)
    }

    // Restore server state
    err = rmsgo.Load(persistFile)
    if err != nil {
        log.Fatal(err)
    }

    defer func() {
        // At shutdown: persist server state
        persistFile.Truncate(0)
        persistFile.Seek(0, io.SeekStart)
        err = rmsgo.Persist(persistFile)
        if err != nil {
            log.Fatal(err)
        }
    }()

    // Register remote storage endpoints to the http.DefaultServeMux
    rmsgo.Register(nil)
    http.ListenAndServe(":8080", nil) // [!] TODO: Use TLS
}

With Request Logging

func logger(next http.Handler) http.Handler {
    return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
        start := time.Now()
        lrw := rmsgo.NewLoggingResponseWriter(w)

        // [!] pass request on to remote storage server
        next.ServeHTTP(lrw, r)

        duration := time.Since(start)

        // - Mom! Can we have slog?
        // - No darling, we have slog at home.
        // slog at home:
        log.Printf("%v", map[string]any{
            "method":   r.Method,
            "uri":      r.RequestURI,
            "duration": duration,
            "status":   lrw.Status,
            "size":     lrw.Size,
        })
    })
}

func main() {
    opts, err := rmsgo.Configure(RemoteRoot, StorageRoot)
    if err != nil {
        log.Fatal(err)
    }

    // [!] Register custom middleware
    opts.UseMiddleware(logger)

    // [!] Other configuration...

    rmsgo.Register(nil)
    http.ListenAndServe(":8080", nil) // [!] TODO: Use TLS
}

All Configuration Options

  • [Required] Configure
    • remoteRoot: URL path below which the server is accessible. (e.g. "/storage/")
    • storageRoot: Location on server's file system to store remoteStorage documents. (e.g. "/var/rms/storage/")
  • [Recommended] UseAuthentication configure how requests are authenticated and control access permissions of users.
    • There are some default users, but for fine grained control custom users can be provided.
    • UserReadOnly has read access to any folder/document
    • UserReadWrite has read and write access to any folder/document
    • UserReadPublic can only read public folders
  • [Recommended] UseAllowedOrigins allow-list of hosts that may make requests to the server. Per default any host is allowed.
  • [Optional] UseAllowOrigin for more control, specify a function that decides based on the request if it is allowed or not. If this option is specified, UseAllowedOrigins has no effect.
  • [Not Recommended] AllowAnyReadWrite allow even unauthenticated requests to create, read, and delete any documents on the server. Has no effect if UseAuthentication is specified.
  • [Optional] UseErrorHandler to catch unhandled errors. Default behavior is to log.Printf the error.
  • [Optional] UseMiddleware to intercept requests before they are passed to the remote storage handler.

Register registers the remote storage handler to a ServeMux.

About

Remote Storage implementation in Go

License:The Unlicense


Languages

Language:Go 99.6%Language:Makefile 0.4%