feature (dynamic): make configuration dynamic

This commit is contained in:
MickaelK 2024-03-12 23:52:16 +11:00
parent 845c4584d3
commit 9e142d5de5
31 changed files with 631 additions and 542 deletions

View file

@ -27,6 +27,11 @@ func start(routes *mux.Router) {
os.Exit(1)
return
}
InitConfig()
InitPluginList(embed.EmbedPluginList)
for _, fn := range Hooks.Get.Onload() {
fn()
}
var wg sync.WaitGroup
for _, obj := range Hooks.Get.Starter() {
wg.Add(1)
@ -35,11 +40,5 @@ func start(routes *mux.Router) {
wg.Done()
}()
}
go func() {
InitPluginList(embed.EmbedPluginList)
for _, fn := range Hooks.Get.Onload() {
go fn()
}
}()
wg.Wait()
}

View file

@ -49,7 +49,7 @@ type FormElement struct {
Required bool `json:"required"`
}
func init() {
func InitConfig() {
Config = NewConfiguration()
Config.Load()
Config.Initialise()

View file

@ -21,16 +21,17 @@ import (
"os"
)
var (
configPath string = GetAbsolutePath(CONFIG_PATH, "config.json")
configKeysToEncrypt []string = []string{
var configKeysToEncrypt []string = []string{
"middleware.identity_provider.params",
"middleware.attribute_mapping.params",
}
)
func configPath() string {
return GetAbsolutePath(CONFIG_PATH, "config.json")
}
func LoadConfig() ([]byte, error) {
file, err := os.OpenFile(configPath, os.O_RDONLY, os.ModePerm)
file, err := os.OpenFile(configPath(), os.O_RDONLY, os.ModePerm)
if err != nil {
if os.IsNotExist(err) {
os.MkdirAll(GetAbsolutePath(CONFIG_PATH), os.ModePerm)
@ -70,12 +71,12 @@ func LoadConfig() ([]byte, error) {
}
func SaveConfig(v []byte) error {
file, err := os.Create(configPath)
file, err := os.Create(configPath())
if err != nil {
return fmt.Errorf(
"Filestash needs to be able to create/edit its own configuration which it can't at the moment. "+
"Change the permission for filestash to create and edit `%s`",
configPath,
configPath(),
)
}

View file

@ -17,17 +17,32 @@ const (
)
var (
LOG_PATH = "data/state/log/"
CONFIG_PATH = "data/state/config/"
DB_PATH = "data/state/db/"
FTS_PATH = "data/state/search/"
CERT_PATH = "data/state/certs/"
TMP_PATH = "data/cache/tmp/"
CONFIG_PATH = "state/config/"
CERT_PATH = "state/certs/"
DB_PATH = "state/db/"
FTS_PATH = "state/search/"
LOG_PATH = "state/log/"
TMP_PATH = "cache/tmp/"
)
func init() {
os.MkdirAll(filepath.Join(GetCurrentDir(), LOG_PATH), os.ModePerm)
// STEP1: setup app path
rootPath := "data/"
if p := os.Getenv("FILESTASH_PATH"); p != "" {
rootPath = p
}
LOG_PATH = filepath.Join(rootPath, LOG_PATH)
CONFIG_PATH = filepath.Join(rootPath, CONFIG_PATH)
DB_PATH = filepath.Join(rootPath, DB_PATH)
FTS_PATH = filepath.Join(rootPath, FTS_PATH)
CERT_PATH = filepath.Join(rootPath, CERT_PATH)
TMP_PATH = filepath.Join(rootPath, TMP_PATH)
// STEP2: initialise the config
os.MkdirAll(filepath.Join(GetCurrentDir(), CERT_PATH), os.ModePerm)
os.MkdirAll(filepath.Join(GetCurrentDir(), DB_PATH), os.ModePerm)
os.MkdirAll(filepath.Join(GetCurrentDir(), FTS_PATH), os.ModePerm)
os.MkdirAll(filepath.Join(GetCurrentDir(), LOG_PATH), os.ModePerm)
os.RemoveAll(filepath.Join(GetCurrentDir(), TMP_PATH))
os.MkdirAll(filepath.Join(GetCurrentDir(), TMP_PATH), os.ModePerm)
}

View file

@ -1,12 +1,13 @@
package common
import (
"github.com/gorilla/mux"
"io"
"io/fs"
"net/http"
"path/filepath"
"strings"
"github.com/gorilla/mux"
)
type Plugin struct {

View file

@ -40,7 +40,7 @@ func generateNewCertificate(root *x509.Certificate, key *rsa.PrivateKey) (*x509.
}
func pullCertificateFromFS() (*x509.Certificate, []byte, error) {
file, err := os.OpenFile(certPEMPath, os.O_RDONLY, os.ModePerm)
file, err := os.OpenFile(certPEMPath(), os.O_RDONLY, os.ModePerm)
if err != nil {
return nil, nil, err
}
@ -58,7 +58,7 @@ func pullCertificateFromFS() (*x509.Certificate, []byte, error) {
}
func saveCertificateToFS(certPEM []byte) error {
file, err := os.OpenFile(certPEMPath, os.O_WRONLY|os.O_CREATE, 0600)
file, err := os.OpenFile(certPEMPath(), os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
}
@ -69,5 +69,5 @@ func saveCertificateToFS(certPEM []byte) error {
}
func clearCert() {
os.Remove(certPEMPath)
os.Remove(certPEMPath())
}

View file

@ -2,14 +2,20 @@ package ssl
import (
. "github.com/mickael-kerjean/filestash/server/common"
"os"
)
var keyPEMPath string = GetAbsolutePath(CERT_PATH, "key.pem")
var certPEMPath string = GetAbsolutePath(CERT_PATH, "cert.pem")
var (
keyPEMPath func() string
certPEMPath func() string
)
func init() {
os.MkdirAll(GetAbsolutePath(CERT_PATH), os.ModePerm)
keyPEMPath = func() string {
return GetAbsolutePath(CERT_PATH, "key.pem")
}
certPEMPath = func() string {
return GetAbsolutePath(CERT_PATH, "cert.pem")
}
}
func Clear() {

View file

@ -37,7 +37,7 @@ func generateNewPrivateKey() (*rsa.PrivateKey, []byte, error) {
}
func pullPrivateKeyFromFS() (*rsa.PrivateKey, []byte, error) {
file, err := os.OpenFile(keyPEMPath, os.O_RDONLY, os.ModePerm)
file, err := os.OpenFile(keyPEMPath(), os.O_RDONLY, os.ModePerm)
if err != nil {
return nil, nil, err
}
@ -56,7 +56,7 @@ func pullPrivateKeyFromFS() (*rsa.PrivateKey, []byte, error) {
}
func savePrivateKeyToFS(privatePEM []byte) error {
file, err := os.OpenFile(keyPEMPath, os.O_WRONLY|os.O_CREATE, 0600)
file, err := os.OpenFile(keyPEMPath(), os.O_WRONLY|os.O_CREATE, 0600)
if err != nil {
return err
}
@ -69,5 +69,5 @@ func savePrivateKeyToFS(privatePEM []byte) error {
}
func clearPrivateKey() {
os.Remove(keyPEMPath)
os.Remove(keyPEMPath())
}

View file

@ -32,11 +32,6 @@ var (
)
func init() {
FileCache = NewAppCache()
cachePath := GetAbsolutePath(TMP_PATH)
FileCache.OnEvict(func(key string, value interface{}) {
os.RemoveAll(filepath.Join(cachePath, key))
})
ZipTimeout = func() int {
return Config.Get("features.protection.zip_timeout").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -50,7 +45,13 @@ func init() {
return f
}).Int()
}
FileCache = NewAppCache()
FileCache.OnEvict(func(key string, value interface{}) {
os.RemoveAll(filepath.Join(GetAbsolutePath(TMP_PATH), key))
})
Hooks.Register.Onload(func() {
ZipTimeout()
})
}
func FileLs(ctx *App, res http.ResponseWriter, req *http.Request) {

View file

@ -9,6 +9,19 @@ import (
"time"
)
var telemetry = Telemetry{Data: make([]LogEntry, 0)}
func init() {
Hooks.Register.Onload(func() {
go func() {
for {
time.Sleep(10 * time.Second)
telemetry.Flush()
}
}()
})
}
type Middleware func(func(*App, http.ResponseWriter, *http.Request)) func(*App, http.ResponseWriter, *http.Request)
func NewMiddlewareChain(fn func(*App, http.ResponseWriter, *http.Request), m []Middleware, app App) http.HandlerFunc {
@ -108,7 +121,7 @@ func Logger(ctx App, res http.ResponseWriter, req *http.Request) {
RequestID: func() string {
defer func() string {
if r := recover(); r != nil {
Log.Debug("middleware::index get header '%s'", r)
return "oops"
}
return "null"
}()
@ -161,14 +174,3 @@ func (this *Telemetry) Flush() {
}
resp.Body.Close()
}
var telemetry Telemetry = Telemetry{Data: make([]LogEntry, 0)}
func init() {
go func() {
for {
time.Sleep(10 * time.Second)
telemetry.Flush()
}
}()
}

View file

@ -4,17 +4,15 @@ import (
"database/sql"
. "github.com/mickael-kerjean/filestash/server/common"
_ "modernc.org/sqlite"
"os"
"time"
)
var DB *sql.DB
func init() {
cachePath := GetAbsolutePath(DB_PATH)
os.MkdirAll(cachePath, os.ModePerm)
Hooks.Register.Onload(func() {
var err error
if DB, err = sql.Open("sqlite", cachePath+"/share.sql?_fk=true"); err != nil {
if DB, err = sql.Open("sqlite", GetAbsolutePath(DB_PATH)+"/share.sql?_fk=true"); err != nil {
Log.Error("model::index sqlite open error '%s'", err.Error())
return
}
@ -37,6 +35,7 @@ func init() {
go func() {
autovacuum()
}()
})
}
func autovacuum() {

View file

@ -10,28 +10,20 @@ package model
import (
"context"
"fmt"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/net/webdav"
"io"
"net/http"
"os"
"path/filepath"
"strings"
"time"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/net/webdav"
)
const DAVCachePath = "data/cache/webdav/"
var (
cachePath string
webdavCache AppCache
)
var webdavCache AppCache
func init() {
cachePath = GetAbsolutePath(DAVCachePath) + "/"
os.RemoveAll(cachePath)
os.MkdirAll(cachePath, os.ModePerm)
webdavCache = NewQuickCache(20, 10)
webdavCache.OnEvict(func(filename string, _ interface{}) {
os.Remove(filename)
@ -64,7 +56,7 @@ func (this WebdavFs) Mkdir(ctx context.Context, name string, perm os.FileMode) e
}
func (this *WebdavFs) OpenFile(ctx context.Context, name string, flag int, perm os.FileMode) (webdav.File, error) {
cachePath := fmt.Sprintf("%stmp_%s", cachePath, Hash(this.id+name, 20))
cachePath := filepath.Join(GetAbsolutePath(TMP_PATH), "webdav_"+Hash(this.id+name, 20))
fwriteFile := func() *os.File {
if this.req.Method == "PUT" {
f, err := os.OpenFile(cachePath+"_writer", os.O_WRONLY|os.O_CREATE|os.O_EXCL, os.ModePerm)
@ -119,7 +111,7 @@ func (this *WebdavFs) Stat(ctx context.Context, name string) (os.FileInfo, error
this.webdavFile = &WebdavFile{
path: fullname,
backend: this.backend,
cache: fmt.Sprintf("%stmp_%s", cachePath, Hash(this.id+name, 20)),
cache: filepath.Join(GetAbsolutePath(TMP_PATH), "webdav_"+Hash(this.id+name, 20)),
}
return this.webdavFile.Stat()
}

View file

@ -19,6 +19,7 @@ import (
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_local"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_mysql"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nfs"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nfs4"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_nop"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_s3"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_samba"
@ -39,5 +40,5 @@ import (
)
func init() {
Log.Debug("Plugin loader")
Hooks.Register.Onload(func() { Log.Debug("plugins loaded") })
}

View file

@ -6,21 +6,20 @@ import (
"encoding/base64"
"encoding/json"
"fmt"
. "github.com/mickael-kerjean/filestash/server/common"
"io"
"io/ioutil"
"net/http"
"net/url"
"os"
"path/filepath"
"strconv"
"strings"
"time"
. "github.com/mickael-kerjean/filestash/server/common"
)
var (
BackblazeCachePath string = "data/cache/tmp/"
BackblazeCache AppCache
)
var BackblazeCache AppCache
type Backblaze struct {
params map[string]string
@ -41,9 +40,6 @@ type BackblazeError struct {
func init() {
Backend.Register("backblaze", Backblaze{})
BackblazeCache = NewAppCache()
cachePath := GetAbsolutePath(BackblazeCachePath)
os.RemoveAll(cachePath)
os.MkdirAll(cachePath, os.ModePerm)
}
func (this Backblaze) Init(params map[string]string, app *App) (IBackend, error) {
@ -429,7 +425,10 @@ func (this Backblaze) Save(path string, file io.Reader) error {
ContentLength int64
Sha1 []byte
}{}
backblazeFileDetail.path = GetAbsolutePath(BackblazeCachePath + "data_" + QuickString(20) + ".dat")
backblazeFileDetail.path = filepath.Join(
GetAbsolutePath(TMP_PATH),
"data_"+QuickString(20)+".dat",
)
f, err := os.OpenFile(backblazeFileDetail.path, os.O_CREATE|os.O_RDWR, os.ModePerm)
if err != nil {
return err

View file

@ -1,17 +1,18 @@
package plg_backend_ftp_only
import (
"crypto/tls"
"fmt"
. "github.com/mickael-kerjean/filestash/server/common"
//"github.com/secsy/goftp" <- FTP issue with microsoft FTP
"github.com/prasad83/goftp"
"io"
"os"
"regexp"
"strconv"
"strings"
"time"
. "github.com/mickael-kerjean/filestash/server/common"
//"github.com/secsy/goftp" <- FTP issue with microsoft FTP
"github.com/prasad83/goftp"
)
var FtpCache AppCache

View file

@ -17,8 +17,6 @@ import (
"time"
)
const GitCachePath = "data/cache/git/"
var GitCache AppCache
type Git struct {
@ -29,9 +27,6 @@ func init() {
Backend.Register("git", Git{})
GitCache = NewAppCache()
cachePath := GetAbsolutePath(GitCachePath)
os.RemoveAll(cachePath)
os.MkdirAll(cachePath, os.ModePerm)
GitCache.OnEvict(func(key string, value interface{}) {
g := value.(*Git)
g.Close()
@ -94,7 +89,10 @@ func (git Git) Init(params map[string]string, app *App) (IBackend, error) {
}
hash := GenerateID(app)
p.basePath = GetAbsolutePath(GitCachePath + "repo_" + hash + "/")
p.basePath = filepath.Join(
GetAbsolutePath(TMP_PATH),
"git_"+hash,
) + "/"
repo, err := g.git.open(p, p.basePath)
g.git.repo = repo

View file

@ -195,7 +195,7 @@ func (this Mysql) Ls(path string) ([]os.FileInfo, error) {
}
rows, err := this.db.Query(fmt.Sprintf(
"SELECT CONCAT(%s) as filename %sFROM %s.%s %s LIMIT 15000",
"SELECT CONCAT(%s) as filename %sFROM %s.%s %s LIMIT 500000",
func() string {
q := strings.Join(extractNamePlus(sqlFields.Select), ", ' - ', ")
if len(sqlFields.Esthetics) != 0 {

View file

@ -154,7 +154,7 @@ func (this Nfs4Share) Rm(path string) error {
}
func (this Nfs4Share) Mv(from string, to string) error {
return ErrNotImplemented
return this.client.Rename(from, to)
}
func (this Nfs4Share) Touch(path string) error {

View file

@ -23,6 +23,10 @@ import (
var (
SECRET_KEY_DERIVATE_FOR_ONLYOFFICE string
OnlyOfficeCache *cache.Cache
plugin_enable func() bool
server_url func() string
can_download func() bool
)
type OnlyOfficeCacheData struct {
@ -32,7 +36,9 @@ type OnlyOfficeCacheData struct {
}
func init() {
plugin_enable := func() bool {
SECRET_KEY_DERIVATE_FOR_ONLYOFFICE = Hash("ONLYOFFICE_"+SECRET_KEY, len(SECRET_KEY))
OnlyOfficeCache = cache.New(720*time.Minute, 720*time.Minute)
plugin_enable = func() bool {
return Config.Get("features.office.enable").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
@ -47,8 +53,9 @@ func init() {
}
return f
}).Bool()
}()
Config.Get("features.office.onlyoffice_server").Schema(func(f *FormElement) *FormElement {
}
server_url = func() string {
return Config.Get("features.office.onlyoffice_server").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
}
@ -63,8 +70,10 @@ func init() {
f.Placeholder = fmt.Sprintf("Default: '%s'", u)
}
return f
})
Config.Get("features.office.can_download").Schema(func(f *FormElement) *FormElement {
}).String()
}
can_download = func() bool {
return Config.Get("features.office.can_download").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
}
@ -74,13 +83,13 @@ func init() {
f.Description = "Display Download button in onlyoffice"
f.Default = true
return f
})
if plugin_enable == false {
return
}).Bool()
}
SECRET_KEY_DERIVATE_FOR_ONLYOFFICE = Hash("ONLYOFFICE_"+SECRET_KEY, len(SECRET_KEY))
Hooks.Register.Onload(func() {
if plugin_enable() == false {
return
}
Hooks.Register.HttpEndpoint(func(r *mux.Router, app *App) error {
oods := r.PathPrefix("/onlyoffice").Subrouter()
oods.PathPrefix("/static/").HandlerFunc(StaticHandler).Methods("GET", "POST")
@ -105,13 +114,12 @@ func init() {
return ["appframe", {"endpoint": "/api/onlyoffice/iframe"}];
}
`)
OnlyOfficeCache = cache.New(720*time.Minute, 720*time.Minute)
})
}
func StaticHandler(res http.ResponseWriter, req *http.Request) {
req.URL.Path = strings.TrimPrefix(req.URL.Path, "/onlyoffice/static")
oodsLocation := Config.Get("features.office.onlyoffice_server").String()
u, err := url.Parse(oodsLocation)
u, err := url.Parse(server_url())
if err != nil {
SendErrorResult(res, err)
return
@ -161,7 +169,7 @@ func IframeContentHandler(ctx *App, res http.ResponseWriter, req *http.Request)
if model.CanRead(ctx) == false {
SendErrorResult(res, ErrPermissionDenied)
return
} else if oodsLocation := Config.Get("features.office.onlyoffice_server").String(); oodsLocation == "" {
} else if server_url() == "" {
res.WriteHeader(http.StatusServiceUnavailable)
res.Write([]byte("<p>The Onlyoffice server hasn't been configured</p>"))
res.Write([]byte("<style>p {color: white; text-align: center; margin-top: 50px; font-size: 20px; opacity: 0.6; font-family: monospace; } </style>"))
@ -365,7 +373,7 @@ func IframeContentHandler(ctx *App, res http.ResponseWriter, req *http.Request)
filetype,
key,
func() string {
if Config.Get("features.office.can_download").Bool() {
if can_download() {
return "true"
}
return "false"

View file

@ -8,11 +8,6 @@ import (
_ "embed"
"encoding/base64"
"encoding/json"
"github.com/creack/pty"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
. "github.com/mickael-kerjean/filestash/server/common"
"golang.org/x/crypto/bcrypt"
"io"
"net/http"
"os"
@ -21,6 +16,13 @@ import (
"syscall"
"time"
"unsafe"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/creack/pty"
"github.com/gorilla/mux"
"github.com/gorilla/websocket"
"golang.org/x/crypto/bcrypt"
)
//go:embed src/app.css
@ -47,11 +49,11 @@ var console_enable = func() bool {
}
func init() {
console_enable()
Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
Hooks.Register.Onload(func() {
if console_enable() == false {
return nil
return
}
Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
r.PathPrefix("/admin/tty/").Handler(
AuthBasic(
func() (string, string) { return "admin", Config.Get("auth.admin").String() },
@ -60,6 +62,7 @@ func init() {
)
return nil
})
})
}
var notAuthorised = func(res http.ResponseWriter, req *http.Request) {

View file

@ -19,8 +19,14 @@ import (
const SYNCTHING_URI = "/admin/syncthing"
var (
plugin_enable func() bool
server_url func() string
)
func init() {
plugin_enable := Config.Get("features.syncthing.enable").Schema(func(f *FormElement) *FormElement {
plugin_enable = func() bool {
return Config.Get("features.syncthing.enable").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
}
@ -34,7 +40,9 @@ func init() {
}
return f
}).Bool()
Config.Get("features.syncthing.server_url").Schema(func(f *FormElement) *FormElement {
}
server_url = func() string {
return Config.Get("features.syncthing.server_url").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
}
@ -49,10 +57,15 @@ func init() {
f.Placeholder = fmt.Sprintf("Default: '%s'", u)
}
return f
}).String()
}
Hooks.Register.Onload(func() {
plugin_enable()
server_url()
})
Hooks.Register.HttpEndpoint(func(r *mux.Router, _ *App) error {
if plugin_enable == false {
if plugin_enable() == false {
return nil
}
r.HandleFunc(SYNCTHING_URI, func(res http.ResponseWriter, req *http.Request) {
@ -121,7 +134,7 @@ func SyncthingProxyHandler(res http.ResponseWriter, req *http.Request) {
}
return "http"
}())
u, err := url.Parse(Config.Get("features.syncthing.server_url").String())
u, err := url.Parse(server_url())
if err != nil {
SendErrorResult(res, err)
return

View file

@ -2,15 +2,15 @@ package plg_image_light
import (
"fmt"
. "github.com/mickael-kerjean/filestash/server/common"
"io"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
)
const ImageCachePath = "data/cache/image/"
. "github.com/mickael-kerjean/filestash/server/common"
)
func init() {
plugin_enable := func() bool {
@ -25,8 +25,6 @@ func init() {
return f
}).Bool()
}
plugin_enable()
thumb_size := func() int {
return Config.Get("features.image.thumbnail_size").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -41,8 +39,6 @@ func init() {
return f
}).Int()
}
thumb_size()
thumb_quality := func() int {
return Config.Get("features.image.thumbnail_quality").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -57,8 +53,6 @@ func init() {
return f
}).Int()
}
thumb_quality()
thumb_caching := func() int {
return Config.Get("features.image.thumbnail_caching").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -73,8 +67,6 @@ func init() {
return f
}).Int()
}
thumb_caching()
image_quality := func() int {
return Config.Get("features.image.image_quality").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -89,8 +81,6 @@ func init() {
return f
}).Int()
}
image_quality()
image_caching := func() int {
return Config.Get("features.image.image_caching").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -105,11 +95,14 @@ func init() {
return f
}).Int()
}
Hooks.Register.Onload(func() {
plugin_enable()
thumb_size()
thumb_quality()
thumb_caching()
image_quality()
image_caching()
cachePath := GetAbsolutePath(ImageCachePath)
os.RemoveAll(cachePath)
os.MkdirAll(cachePath, os.ModePerm)
})
Hooks.Register.ProcessFileContentBeforeSend(func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
if plugin_enable() == false {
@ -134,7 +127,7 @@ func init() {
/////////////////////////
// Specify transformation
transform := &Transform{
Input: GetAbsolutePath(ImageCachePath + "imagein_" + QuickString(10)),
Input: filepath.Join(GetAbsolutePath(TMP_PATH), "imagein_"+QuickString(10)),
Size: thumb_size(),
Crop: true,
Quality: thumb_quality(),

View file

@ -37,7 +37,6 @@ func init() {
return f
}).Bool()
}
SEARCH_ENABLE()
SEARCH_PROCESS_MAX = func() int {
return Config.Get("features.search.process_max").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -52,7 +51,6 @@ func init() {
return f
}).Int()
}
SEARCH_PROCESS_MAX()
SEARCH_PROCESS_PAR = func() int {
return Config.Get("features.search.process_par").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -67,7 +65,6 @@ func init() {
return f
}).Int()
}
SEARCH_PROCESS_PAR()
SEARCH_REINDEX = func() int {
return Config.Get("features.search.reindex_time").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -82,7 +79,6 @@ func init() {
return f
}).Int()
}
SEARCH_REINDEX()
CYCLE_TIME = func() int {
return Config.Get("features.search.cycle_time").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -97,7 +93,6 @@ func init() {
return f
}).Int()
}
CYCLE_TIME()
MAX_INDEXING_FSIZE = func() int {
return Config.Get("features.search.max_size").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -112,7 +107,6 @@ func init() {
return f
}).Int()
}
MAX_INDEXING_FSIZE()
INDEXING_EXT = func() string {
return Config.Get("features.search.indexer_ext").Schema(func(f *FormElement) *FormElement {
if f == nil {
@ -127,6 +121,14 @@ func init() {
return f
}).String()
}
Hooks.Register.Onload(func() {
SEARCH_ENABLE()
SEARCH_PROCESS_MAX()
SEARCH_PROCESS_PAR()
SEARCH_REINDEX()
CYCLE_TIME()
MAX_INDEXING_FSIZE()
INDEXING_EXT()
onChange := Config.ListenForChange()
@ -155,4 +157,5 @@ func init() {
for i := 0; i < SEARCH_PROCESS_PAR(); i++ {
go runner()
}
})
}

View file

@ -25,6 +25,7 @@ func init() {
return f
}).Int()) * time.Millisecond
}
Hooks.Register.Onload(func() {
SEARCH_TIMEOUT()
})
}

File diff suppressed because one or more lines are too long

View file

@ -8,8 +8,12 @@ import (
"regexp"
)
var (
disable_svg func() bool
)
func init() {
disable_svg := func() bool {
disable_svg = func() bool {
return Config.Get("features.protection.disable_svg").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
@ -23,8 +27,10 @@ func init() {
return f
}).Bool()
}
disable_svg()
Hooks.Register.Onload(func() {
if disable_svg() == false {
return
}
Hooks.Register.ProcessFileContentBeforeSend(func(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {
if GetMimeType(req.URL.Query().Get("path")) != "image/svg+xml" {
return reader, nil
@ -41,4 +47,5 @@ func init() {
}
return NewReadCloserFromBytes(txt), nil
})
})
}

View file

@ -2,22 +2,26 @@ package plg_starter_http
import (
"fmt"
"github.com/gorilla/mux"
. "github.com/mickael-kerjean/filestash/server/common"
"net/http"
"time"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/gorilla/mux"
)
func init() {
port := Config.Get("general.port").Int()
Hooks.Register.Starter(func(r *mux.Router) {
Log.Info("[http] starting ...")
port := Config.Get("general.port").Int()
srv := &http.Server{
Addr: fmt.Sprintf(":%d", port),
Handler: r,
}
go ensureAppHasBooted(fmt.Sprintf("http://127.0.0.1:%d/about", port), fmt.Sprintf("[http] listening on :%d", port))
go ensureAppHasBooted(
fmt.Sprintf("http://127.0.0.1:%d/about", port),
fmt.Sprintf("[http] listening on :%d", port),
)
if err := srv.ListenAndServe(); err != nil {
Log.Error("error: %v", err)
return

View file

@ -9,26 +9,37 @@ package plg_starter_http2
import (
"crypto/tls"
"fmt"
"github.com/gorilla/mux"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/filestash/server/common/ssl"
"golang.org/x/crypto/acme/autocert"
"net/http"
"os"
"path/filepath"
"time"
. "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/filestash/server/common/ssl"
"github.com/gorilla/mux"
"golang.org/x/crypto/acme/autocert"
)
var SSL_PATH string = GetAbsolutePath(CERT_PATH, "ssl")
var (
SSL_PATH string
config_port func() int
)
func init() {
config_port = func() int {
return Config.Get("general.port").Int()
}
Hooks.Register.Onload(func() {
SSL_PATH = filepath.Join(GetAbsolutePath(CERT_PATH), "ssl")
os.MkdirAll(SSL_PATH, os.ModePerm)
domain := Config.Get("general.host").String()
})
Hooks.Register.Starter(func(r *mux.Router) {
domain := Config.Get("general.host").String()
Log.Info("[https] starting ...%s", domain)
srv := &http.Server{
Addr: fmt.Sprintf(":https"),
Addr: fmt.Sprintf(":%d", config_port()),
Handler: r,
TLSConfig: &DefaultTLSConfig,
ErrorLog: NewNilLogger(),
@ -56,14 +67,8 @@ func init() {
srv.TLSConfig.GetCertificate = mngr.GetCertificate
}
go ensureAppHasBooted("https://127.0.0.1/about", fmt.Sprintf("[https] started"))
go func() {
if err := srv.ListenAndServeTLS("", ""); err != nil {
Log.Error("[https]: listen_serve %v", err)
return
}
}()
srv := http.Server{
srv = &http.Server{
Addr: fmt.Sprintf(":http"),
ReadTimeout: 5 * time.Second,
WriteTimeout: 5 * time.Second,
@ -78,7 +83,16 @@ func init() {
}),
}
if err := srv.ListenAndServe(); err != nil {
Log.Error("[https]: http_redirect %v", err)
return
}
}()
go ensureAppHasBooted(
fmt.Sprintf("https://127.0.0.1:%d/about", config_port()),
fmt.Sprintf("[https] started"),
)
if err := srv.ListenAndServeTLS("", ""); err != nil {
Log.Error("[https]: listen_serve %v", err)
return
}
})

View file

@ -11,10 +11,9 @@ import (
)
func init() {
Hooks.Register.Starter(func(r *mux.Router) {
domain := Config.Get("general.host").String()
port := Config.Get("general.port").Int()
Hooks.Register.Starter(func(r *mux.Router) {
Log.Info("[https] starting ...%s", domain)
srv := &http.Server{
Addr: fmt.Sprintf(":%d", port),

View file

@ -7,15 +7,16 @@ import (
. "github.com/mickael-kerjean/filestash/server/common"
"net/http"
"os"
"path/filepath"
"time"
)
var TOR_PATH string = GetAbsolutePath(CERT_PATH, "tor")
var (
enable_plugin func() bool
tor_url func() string
)
func init() {
os.MkdirAll(TOR_PATH, os.ModePerm)
enable_tor := func() bool {
enable_plugin = func() bool {
return Config.Get("features.server.tor_enable").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
@ -29,8 +30,8 @@ func init() {
return f
}).Bool()
}
enable_tor()
Config.Get("features.server.tor_url").Schema(func(f *FormElement) *FormElement {
tor_url = func() string {
return Config.Get("features.server.tor_url").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
}
@ -42,16 +43,24 @@ func init() {
f.ReadOnly = true
f.Placeholder = "LOADING... Refresh the page in a few seconds"
return f
})
}).String()
}
Hooks.Register.Onload(func() {
tor_url()
enable_plugin()
})
Hooks.Register.Starter(func(r *mux.Router) {
if enable_tor() == false {
torPath := GetAbsolutePath(CERT_PATH, "tor")
os.MkdirAll(torPath, os.ModePerm)
if enable_plugin() == false {
startTor := false
onChange := Config.ListenForChange()
for {
select {
case <-onChange.Listener:
startTor = enable_tor()
startTor = enable_plugin()
}
if startTor == true {
break
@ -62,7 +71,7 @@ func init() {
Log.Info("[tor] starting ...")
t, err := tor.Start(nil, &tor.StartConf{
DataDir: TOR_PATH,
DataDir: torPath,
})
if err != nil {
Log.Error("[tor] Unable to start Tor: %v", err)

View file

@ -2,8 +2,10 @@ package plg_video_transcoder
import (
"bytes"
"context"
"encoding/base64"
"encoding/json"
"errors"
"fmt"
"io"
"math"
@ -20,11 +22,17 @@ import (
)
const (
HLS_SEGMENT_LENGTH = 30
HLS_SEGMENT_LENGTH = 5
FPS = 30
CLEAR_CACHE_AFTER = 12
VideoCachePath = "data/cache/video/"
)
var (
plugin_enable func() bool
blacklist_format func() string
)
func init() {
ffmpegIsInstalled := false
ffprobeIsInstalled := false
@ -34,7 +42,7 @@ func init() {
if _, err := exec.LookPath("ffprobe"); err == nil {
ffprobeIsInstalled = true
}
plugin_enable := func() bool {
plugin_enable = func() bool {
return Config.Get("features.video.enable_transcoder").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
@ -50,8 +58,7 @@ func init() {
return f
}).Bool()
}
blacklist_format := func() string {
blacklist_format = func() string {
return Config.Get("features.video.blacklist_format").Schema(func(f *FormElement) *FormElement {
if f == nil {
f = &FormElement{}
@ -67,8 +74,9 @@ func init() {
return f
}).String()
}
blacklist_format()
Hooks.Register.Onload(func() {
blacklist_format()
if plugin_enable() == false {
return
} else if ffmpegIsInstalled == false {
@ -112,6 +120,7 @@ func init() {
})
return nil
})
})
}
func hls_playlist(reader io.ReadCloser, ctx *App, res *http.ResponseWriter, req *http.Request) (io.ReadCloser, error) {