improve (static): attempt at statically compile everything - revamp

This commit is contained in:
=
2019-04-27 18:13:43 +10:00
parent 2c7feed57a
commit ca5198ac0b
23 changed files with 319 additions and 195 deletions

View File

@ -234,7 +234,9 @@ func FileCat(ctx App, res http.ResponseWriter, req *http.Request) {
if contentLength != -1 { if contentLength != -1 {
header.Set("Content-Length", fmt.Sprintf("%d", contentLength)) header.Set("Content-Length", fmt.Sprintf("%d", contentLength))
} }
if header.Get("Content-Type") == "" {
header.Set("Content-Type", GetMimeType(req.URL.Query().Get("path"))) header.Set("Content-Type", GetMimeType(req.URL.Query().Get("path")))
}
if header.Get("Content-Security-Policy") == "" { if header.Get("Content-Security-Policy") == "" {
header.Set("Content-Security-Policy", "default-src 'none'; img-src 'self'; style-src 'unsafe-inline'") header.Set("Content-Security-Policy", "default-src 'none'; img-src 'self'; style-src 'unsafe-inline'")
} }

View File

@ -1,40 +1,15 @@
package plugin package plugin
import ( import (
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_image_light"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_backblaze"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_dav"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_backend_mysql"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_security_scanner"
_ "github.com/mickael-kerjean/filestash/server/plugin/plg_security_svg"
. "github.com/mickael-kerjean/filestash/server/common" . "github.com/mickael-kerjean/filestash/server/common"
"os"
"path/filepath"
plg "plugin"
"strings"
) )
func init() { func init() {
ex, _ := os.Executable() Log.Debug("Plugin loader")
pPath := filepath.Join(filepath.Dir(ex), PLUGIN_PATH)
file, err := os.Open(pPath)
if err != nil {
return
}
files, err := file.Readdir(0)
for i:=0; i < len(files); i++ {
name := files[i].Name()
if strings.HasPrefix(name, ".") {
continue
}
Log.Debug("Load plugin: '%s'", name)
p, err := plg.Open(pPath + "/" + name)
if err != nil {
Log.Warning("Can't load plugin: %s => %v", name, err)
continue
}
fn, err := p.Lookup("Init")
if err != nil {
Log.Warning("Can't register plugin: %s => %v", name, err)
continue
}
if obj, ok := fn.(func(config *Configuration)); ok {
obj(&Config)
}
}
} }

View File

@ -1,4 +1,4 @@
package main package plg_backend_backblaze
import ( import (
"bytes" "bytes"
@ -38,7 +38,7 @@ type BackblazeError struct {
Status int `json:"status"` Status int `json:"status"`
} }
func Init(config *Configuration) { func init() {
Backend.Register("backblaze", Backblaze{}) Backend.Register("backblaze", Backblaze{})
BackblazeCache = NewAppCache() BackblazeCache = NewAppCache()
cachePath := filepath.Join(GetCurrentDir(), BackblazeCachePath) cachePath := filepath.Join(GetCurrentDir(), BackblazeCachePath)

View File

@ -1,10 +1,4 @@
package main package plg_backend_dav
/*
* Compilation
* ===========
* go build -buildmode=plugin -o dist/data/plugin/backend_dav.so server/plugin/plg_backend_dav/index.go
*/
import ( import (
"encoding/xml" "encoding/xml"
@ -28,7 +22,7 @@ const (
CALDAV string = "caldav" CALDAV string = "caldav"
) )
func Init(config *Configuration) { func init() {
DavCache = NewAppCache(2, 1) DavCache = NewAppCache(2, 1)
Backend.Register(CARDDAV, Dav{}) Backend.Register(CARDDAV, Dav{})
Backend.Register(CALDAV, Dav{}) Backend.Register(CALDAV, Dav{})

View File

@ -1,4 +1,4 @@
package main package plg_backend_mysql
import ( import (
"database/sql" "database/sql"
@ -20,7 +20,7 @@ type Mysql struct {
db *sql.DB db *sql.DB
} }
func Init(config *Configuration) { func init() {
Backend.Register("mysql", Mysql{}) Backend.Register("mysql", Mysql{})
} }

View File

@ -1,3 +0,0 @@
#!/bin/sh
go build -buildmode=plugin -o ../../../dist/data/plugin/image.so index.go

View File

@ -0,0 +1,18 @@
plg_image_light rely on a few libraries for:
- image transcoding: libtranscode.a: a library build on top of of libraw
- image resizing: libresize.a: a library built on top of libvips
To create the libraries to be used by Filestash:
./create_libtranscode.sh
./create_libresize.sh
To test the libraries are working fine:
```
# libtranscode:
gcc -Wall -c src/libtranscode_test.c
gcc -o main_transcode.bin libtranscode_test.o -lm -lgomp -llcms2 -lstdc++ -L. -l:libtranscode.a
# libresize:
gcc -Wall -c src/libresize_test.c `pkg-config --cflags glib-2.0`
gcc -o main_resize.bin libresize_test.o -lm -lgmodule-2.0 -lgobject-2.0 -lglib-2.0 -L. -l:libresize.a
```

View File

@ -0,0 +1,88 @@
#!/bin/sh
# This script is run like this:
# docker run --name debian -ti -v /home/:/home/ debian bash
# cd /path/to/this/script
# ./create_libresize.sh
set -e
################################################
# Tooling
apt update
apt install -y curl make gcc g++ xz-utils pkg-config python3-pip autoconf libtool unzip python-setuptools cmake git
pip3 install --user meson ninja
export PATH=~/.local/bin:$PATH
################################################
# Stage 1: Get libvips and its dependencies + recompile for less headaches
INITIAL_PATH=`pwd`
mkdir -p /tmp/filestash/libresize/tmp
cd /tmp/filestash/libresize
apt install -y libvips-dev
cd tmp
curl -L -X GET https://github.com/libvips/libvips/releases/download/v8.7.0/vips-8.7.0.tar.gz > libvips.tar.gz
tar -zxf libvips.tar.gz
cd vips-8.7.0/
./configure --enable-static --without-magick --without-lcms --without-OpenEXR --without-nifti --without-pdfium --without-rsvg --without-matio --without-libwebp --without-cfitsio --without-zlib --without-poppler --without-pangoft2 --enable-introspection=no --without-openslide
make -j 8
make install
cd $INITIAL_PATH
################################################
# Stage 2: Create our own library as a static build
gcc -Wall -c src/libresize.c `pkg-config --cflags glib-2.0`
ar rcs libresize.a libresize.o
rm *.o
################################################
# Stage 3: Gather and assemble all the bits and pieces together
#ar x /tmp/libresize.a
ar x /usr/local/lib/libvips.a
ar x /usr/lib/x86_64-linux-gnu/libz.a
ar x /usr/lib/x86_64-linux-gnu/libbz2.a
ar x /usr/lib/x86_64-linux-gnu/libjpeg.a
ar x /usr/lib/x86_64-linux-gnu/libgif.a
ar x /usr/lib/x86_64-linux-gnu/libdl.a
ar x /usr/lib/x86_64-linux-gnu/libicui18n.a
ar x /usr/lib/x86_64-linux-gnu/libthread.a
ar x /usr/lib/x86_64-linux-gnu/libgsf-1.a
ar x /usr/lib/x86_64-linux-gnu/libicuuc.a
ar x /usr/lib/x86_64-linux-gnu/libicudata.a
ar x /usr/lib/x86_64-linux-gnu/liblzma.a
ar x /usr/lib/x86_64-linux-gnu/libfreetype.a
ar x /usr/lib/x86_64-linux-gnu/liblqr-1.a
ar x /usr/lib/x86_64-linux-gnu/libfftw3.a
ar x /usr/lib/x86_64-linux-gnu/libfontconfig.a
ar x /usr/lib/x86_64-linux-gnu/libXext.a
ar x /usr/lib/x86_64-linux-gnu/libSM.a
ar x /usr/lib/x86_64-linux-gnu/liblXt.a
ar x /usr/lib/x86_64-linux-gnu/libX11.a
ar x /usr/lib/x86_64-linux-gnu/libgomp.a
ar x /usr/lib/x86_64-linux-gnu/liborc-0.4.a
ar x /usr/lib/x86_64-linux-gnu/libltdl.a
ar x /usr/lib/x86_64-linux-gnu/librt.a
ar x /usr/lib/x86_64-linux-gnu/libharfbuzz.a
ar x /usr/lib/x86_64-linux-gnu/libgraphite2.a
ar x /usr/lib/x86_64-linux-gnu/libexpat.a
ar x /usr/lib/x86_64-linux-gnu/libgio-2.0.a
ar x /usr/lib/x86_64-linux-gnu/libpng16.a
ar x /usr/lib/x86_64-linux-gnu/libpixman-1.a
ar x /usr/lib/x86_64-linux-gnu/libxcb.a
ar x /usr/lib/x86_64-linux-gnu/libjbig.a
ar x /usr/lib/x86_64-linux-gnu/libexif.a
ar x /usr/lib/x86_64-linux-gnu/libxcb-shm
ar x /usr/lib/x86_64-linux-gnu/libxcb-render
ar x /usr/lib/x86_64-linux-gnu/libXrender
ar x /usr/lib/x86_64-linux-gnu/libpcre.a
ar x /usr/lib/x86_64-linux-gnu/libhdf5.a
ar x /usr/lib/x86_64-linux-gnu/libresolv
ar x /usr/lib/x86_64-linux-gnu/libXau
ar x /usr/lib/x86_64-linux-gnu/libXdmcp
ar x /usr/lib/x86_64-linux-gnu/libtiff.a
ar x /usr/lib/x86_64-linux-gnu/libgdk_pixbuf-2.0.a
ar x /usr/lib/x86_64-linux-gnu/libpangoft2-1.0.a
ar x /usr/lib/x86_64-linux-gnu/libIlmThread.a
ar x /usr/lib/x86_64-linux-gnu/libpoppler.a
ar rcs libresize.a *.o
rm *.o *.ao

View File

@ -0,0 +1,29 @@
#!/bin/sh
# This script is run like this:
# docker run --name debian -ti -v /home/:/home/ debian bash
# cd /path/to/this/script
# ./create_libresize.sh
set -e
################################################
# Tooling
apt update
apt install -y curl make gcc g++ xz-utils pkg-config python3-pip autoconf libtool unzip python-setuptools cmake git
pip3 install --user meson ninja
export PATH=~/.local/bin:$PATH
################################################
# Stage 1: Get libraw and its dependencies
apt install libraw-dev
################################################
# Stage 2: Create our own library as a static build
gcc -Wall -c src/libtranscode.c
################################################
# Stage 3: Gather and assemble all the bits and pieces together
ar x /usr/lib/x86_64-linux-gnu/libraw.a
ar x /usr/lib/x86_64-linux-gnu/libjpeg.a
ar rcs libtranscode.a *.o
rm *.o *.ao

View File

@ -1,16 +1,7 @@
#include <stdlib.h> #include <stdio.h>
#include <vips/vips.h> #include <vips/vips.h>
int resizer_init(const int ncpu){ int image_resize(const char *filename, void **buf, size_t *len, int size, int crop, int quality, int exif){
if(VIPS_INIT("filestash")){
return 1;
}
vips_concurrency_set(1);
vips_cache_set_max(0);
return 0;
}
int resizer_process(const char *input, const char *output, int size, int crop, int quality, int exif){
VipsImage *img; VipsImage *img;
int err; int err;
@ -21,7 +12,7 @@ int resizer_process(const char *input, const char *output, int size, int crop, i
if(crop == VIPS_INTERESTING_CENTRE){ if(crop == VIPS_INTERESTING_CENTRE){
// Generate a thumbnails: a square picture crop in the center // Generate a thumbnails: a square picture crop in the center
err = vips_thumbnail(input, &img, size, err = vips_thumbnail(filename, &img, size,
"size", VIPS_SIZE_BOTH, "size", VIPS_SIZE_BOTH,
"auto_rotate", TRUE, "auto_rotate", TRUE,
"crop", VIPS_INTERESTING_CENTRE, "crop", VIPS_INTERESTING_CENTRE,
@ -29,7 +20,7 @@ int resizer_process(const char *input, const char *output, int size, int crop, i
); );
}else{ }else{
// normal resize of an image with libvips // normal resize of an image with libvips
err = vips_thumbnail(input, &img, size, err = vips_thumbnail(filename, &img, size,
"size", VIPS_SIZE_DOWN, "size", VIPS_SIZE_DOWN,
"auto_rotate", TRUE, "auto_rotate", TRUE,
"crop", VIPS_INTERESTING_NONE, "crop", VIPS_INTERESTING_NONE,
@ -40,7 +31,15 @@ int resizer_process(const char *input, const char *output, int size, int crop, i
return err; return err;
} }
err = vips_jpegsave(img, output, NULL); err = vips_jpegsave_buffer(img, buf, len, "Q", quality, "strip", exif, NULL);
g_object_unref(img); g_object_unref(img);
return err; return err;
} }
void __attribute__ ((constructor)) initLibrary(void) {
VIPS_INIT("imagevips");
vips_cache_set_max(0);
}
void __attribute__ ((destructor)) cleanUpLibrary(void) {
vips_shutdown();
}

View File

@ -0,0 +1,4 @@
#include <stdio.h>
#include <vips/vips.h>
int image_resize(const char *filename, void **buf, size_t *len, int size, int crop, int quality, int exif);

View File

@ -0,0 +1,29 @@
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include "libresize.h"
double benchmark_image_resize(int n, const char*input);
int main(int argc, char **argv) {
if(argc != 2){
printf("missing argument: need a path to an image\n");
exit(1);
}
printf("=> benchmark %s: %.2fms\n", argv[1], benchmark_image_resize(20, argv[1]));
}
double benchmark_image_resize(int n, const char* input) {
double total = 0;
void *buffer;
size_t len;
int i = 0;
for(i=0; i<n; i++){
clock_t begin = clock();
image_resize(input, &buffer, &len, 200, 1, 90, 0);
clock_t end = clock();
total += (double)(end - begin) / CLOCKS_PER_SEC * 1000;
}
return total / n;
}

View File

@ -1,14 +1,9 @@
#include <stdlib.h> #include <stdlib.h>
#include <libraw/libraw.h> #include <libraw/libraw.h>
int save_thumbnail(const char *filename, libraw_data_t *raw){ int save_thumbnail(const char *filename, libraw_data_t *raw);
int err;
err = libraw_dcraw_thumb_writer(raw, filename);
libraw_close(raw);
return err;
}
int raw_process(const char* filename, int min_width){ int image_transcode_compute(const char* filename, int min_width) {
int err; int err;
libraw_data_t *raw; libraw_data_t *raw;
int thumbnail_working = 0; int thumbnail_working = 0;
@ -65,3 +60,10 @@ int raw_process(const char* filename, int min_width){
libraw_close(raw); libraw_close(raw);
return 0; return 0;
} }
int save_thumbnail(const char *filename, libraw_data_t *raw){
int err;
err = libraw_dcraw_thumb_writer(raw, filename);
libraw_close(raw);
return err;
}

View File

@ -0,0 +1,4 @@
#include <stdlib.h>
#include <libraw/libraw.h>
int image_transcode_compute(const char* filename, int min_width);

View File

@ -0,0 +1,25 @@
#include <stdio.h>
#include <time.h>
#include "libtranscode.h"
double benchmark_image_transcode(int n, const char*input);
int main(int argc, char **argv) {
if(argc != 2){
printf("missing argument: need a path to an image\n");
exit(1);
}
printf("=> benchmark %s: %.2fms\n", argv[1], benchmark_image_transcode(20, argv[1]));
}
double benchmark_image_transcode(int n, const char* input) {
double total = 0;
int i = 0;
for(i=0; i<n; i++){
clock_t begin = clock();
image_transcode_compute(input, 200);
clock_t end = clock();
total += (double)(end - begin) / CLOCKS_PER_SEC * 1000;
}
return total / n;
}

View File

@ -1,9 +1,8 @@
package main package plg_image_light
import ( import (
"fmt" "fmt"
. "github.com/mickael-kerjean/filestash/server/common" . "github.com/mickael-kerjean/filestash/server/common"
"github.com/mickael-kerjean/filestash/server/plugin/plg_image_light/lib"
"io" "io"
"net/http" "net/http"
"os" "os"
@ -12,17 +11,11 @@ import (
"strconv" "strconv"
) )
const ( const ImageCachePath = "data/cache/image/"
ImageCachePath = "data/cache/image/"
)
var Config *Configuration
func Init(conf *Configuration) {
Config = conf
func init() {
plugin_enable := func() bool { plugin_enable := func() bool {
return conf.Get("features.image.enable_image").Schema(func(f *FormElement) *FormElement { return Config.Get("features.image.enable_image").Schema(func(f *FormElement) *FormElement {
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }
@ -36,7 +29,7 @@ func Init(conf *Configuration) {
plugin_enable() plugin_enable()
thumb_size := func() int { thumb_size := func() int {
return conf.Get("features.image.thumbnail_size").Schema(func(f *FormElement) *FormElement { return Config.Get("features.image.thumbnail_size").Schema(func(f *FormElement) *FormElement {
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }
@ -52,7 +45,7 @@ func Init(conf *Configuration) {
thumb_size() thumb_size()
thumb_quality := func() int { thumb_quality := func() int {
return conf.Get("features.image.thumbnail_quality").Schema(func(f *FormElement) *FormElement { return Config.Get("features.image.thumbnail_quality").Schema(func(f *FormElement) *FormElement {
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }
@ -68,7 +61,7 @@ func Init(conf *Configuration) {
thumb_quality() thumb_quality()
thumb_caching := func() int { thumb_caching := func() int {
return conf.Get("features.image.thumbnail_caching").Schema(func(f *FormElement) *FormElement { return Config.Get("features.image.thumbnail_caching").Schema(func(f *FormElement) *FormElement {
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }
@ -84,7 +77,7 @@ func Init(conf *Configuration) {
thumb_caching() thumb_caching()
image_quality := func() int { image_quality := func() int {
return conf.Get("features.image.image_quality").Schema(func(f *FormElement) *FormElement { return Config.Get("features.image.image_quality").Schema(func(f *FormElement) *FormElement {
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }
@ -100,7 +93,7 @@ func Init(conf *Configuration) {
image_quality() image_quality()
image_caching := func() int { image_caching := func() int {
return conf.Get("features.image.image_caching").Schema(func(f *FormElement) *FormElement { return Config.Get("features.image.image_caching").Schema(func(f *FormElement) *FormElement {
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }
@ -139,9 +132,8 @@ func Init(conf *Configuration) {
///////////////////////// /////////////////////////
// Specify transformation // Specify transformation
transform := &lib.Transform{ transform := &Transform{
Input: GetAbsolutePath(ImageCachePath + "imagein_" + QuickString(10)), Input: GetAbsolutePath(ImageCachePath + "imagein_" + QuickString(10)),
Output: GetAbsolutePath(ImageCachePath + "imageout_" + QuickString(10)),
Size: thumb_size(), Size: thumb_size(),
Crop: true, Crop: true,
Quality: thumb_quality(), Quality: thumb_quality(),
@ -163,7 +155,7 @@ func Init(conf *Configuration) {
///////////////////////////// /////////////////////////////
// Insert file in the fs // Insert file in the fs
// => lower RAM usage while processing // => impedance matching with something usable by CGO
file, err := os.OpenFile(transform.Input, os.O_WRONLY|os.O_CREATE, os.ModePerm) file, err := os.OpenFile(transform.Input, os.O_WRONLY|os.O_CREATE, os.ModePerm)
if err != nil { if err != nil {
return reader, ErrFilesystemError return reader, ErrFilesystemError
@ -173,13 +165,12 @@ func Init(conf *Configuration) {
reader.Close() reader.Close()
defer func() { defer func() {
os.Remove(transform.Input) os.Remove(transform.Input)
os.Remove(transform.Output)
}() }()
///////////////////////// /////////////////////////
// Transcode RAW image // Transcode RAW image
if lib.IsRaw(mType) { if IsRaw(mType) {
if lib.ExtractPreview(transform) == nil { if ExtractPreview(transform) == nil {
mType = "image/jpeg" mType = "image/jpeg"
(*res).Header().Set("Content-Type", mType) (*res).Header().Set("Content-Type", mType)
} else { } else {
@ -188,11 +179,19 @@ func Init(conf *Configuration) {
} }
///////////////////////// /////////////////////////
// Final stage: resizing // final stage: resizing
if mType != "image/jpeg" && mType != "image/png" && mType != "image/gif" && mType != "image/tiff" { if mType != "image/jpeg" && mType != "image/png" && mType != "image/gif" && mType != "image/tiff" {
return reader, nil return reader, nil
} }
return lib.CreateThumbnail(transform) return CreateThumbnail(transform)
}) })
} }
type Transform struct {
Input string
Size int
Crop bool
Quality int
Exif bool
}

View File

@ -1,4 +0,0 @@
#include <stdlib.h>
#include <libraw/libraw.h>
int raw_process(const char* filename, int min_width);

View File

@ -1,62 +0,0 @@
package lib
// #cgo pkg-config: vips
// #include <resizer.h>
// #include <stdlib.h>
import "C"
import (
. "github.com/mickael-kerjean/filestash/server/common"
"io"
"os"
"runtime"
"unsafe"
"sync"
)
var (
LIBVIPS_INSTALLED = false
VIPS_LOCK = &sync.Mutex{}
)
type Transform struct {
Input string
Output string
Size int
Crop bool
Quality int
Exif bool
}
func init() {
if C.resizer_init(C.int(runtime.NumCPU())) != 0 {
Log.Warning("Can't load libvips")
return
}
LIBVIPS_INSTALLED = true
}
func CreateThumbnail(t *Transform) (io.ReadCloser, error) {
if LIBVIPS_INSTALLED == false {
return nil, NewError("Libvips not installed", 501)
}
filenameInput := C.CString(t.Input)
defer C.free(unsafe.Pointer(filenameInput))
filenameOutput := C.CString(t.Output)
defer C.free(unsafe.Pointer(filenameOutput))
VIPS_LOCK.Lock()
if C.resizer_process(filenameInput, filenameOutput, C.int(t.Size), boolToCInt(t.Crop), C.int(t.Quality), boolToCInt(t.Exif)) != 0 {
return nil, NewError("", 500)
}
VIPS_LOCK.Unlock()
return os.OpenFile(t.Output, os.O_RDONLY, os.ModePerm)
}
func boolToCInt(val bool) C.int {
if val == false {
return C.int(0)
}
return C.int(1)
}

View File

@ -1,6 +0,0 @@
#include <stdlib.h>
#include <vips/vips.h>
int resizer_init(const int ncpu);
int resizer_process(const char *input, const char *output, int size, int crop, int quality, int exif);

View File

@ -0,0 +1,39 @@
package plg_image_light
// #cgo pkg-config:glib-2.0
// #cgo CFLAGS: -I./deps/src
// #cgo LDFLAGS: -lm -lgmodule-2.0 -lgobject-2.0 -lglib-2.0 -ldl -L./deps -l:libresize.a
// #include "libresize.h"
import "C"
import (
"context"
. "github.com/mickael-kerjean/filestash/server/common"
"golang.org/x/sync/semaphore"
"io"
"unsafe"
)
var VIPS_LOCK = semaphore.NewWeighted(int64(10))
func CreateThumbnail(t *Transform) (io.ReadCloser, error) {
VIPS_LOCK.Acquire(context.Background(), 1)
defer VIPS_LOCK.Release(1)
filename := C.CString(t.Input)
defer C.free(unsafe.Pointer(filename))
var buffer unsafe.Pointer
len := C.size_t(0)
if C.image_resize(filename, &buffer, &len, C.int(t.Size), boolToCInt(t.Crop), C.int(t.Quality), boolToCInt(t.Exif)) != 0 {
return nil, NewError("", 500)
}
buf := C.GoBytes(buffer, C.int(len))
C.g_free(C.gpointer(buffer))
return NewReadCloserFromBytes(buf), nil
}
func boolToCInt(val bool) C.int {
if val == false {
return C.int(0)
}
return C.int(1)
}

View File

@ -1,18 +1,17 @@
package lib package plg_image_light
// #cgo CFLAGS: -I./deps/src
// #cgo pkg-config: libraw // #cgo LDFLAGS: -lm -lgomp -llcms2 -lstdc++ -L./deps -l:libtranscode.a
// #include <raw.h> // #include "libtranscode.h"
// #include <stdlib.h>
import "C" import "C"
import ( import (
"context"
"golang.org/x/sync/semaphore"
. "github.com/mickael-kerjean/filestash/server/common" . "github.com/mickael-kerjean/filestash/server/common"
"math/rand"
"time"
"unsafe" "unsafe"
) )
const LIBRAW_MEMORY_ERROR = -1 var LIBRAW_LOCK = semaphore.NewWeighted(int64(5))
func IsRaw(mType string) bool { func IsRaw(mType string) bool {
switch mType { switch mType {
@ -46,20 +45,14 @@ func IsRaw(mType string) bool {
} }
func ExtractPreview(t *Transform) error { func ExtractPreview(t *Transform) error {
filename := C.CString(t.Input) LIBRAW_LOCK.Acquire(context.Background(), 1)
err := C.raw_process(filename, C.int(t.Size)) defer LIBRAW_LOCK.Release(1)
if err == LIBRAW_MEMORY_ERROR {
// libraw acts weird sometimes and I couldn't
// find a way to increase its available memory :(
r := rand.Intn(2000) + 500
time.Sleep(time.Duration(r) * time.Millisecond)
C.free(unsafe.Pointer(filename))
return ExtractPreview(t)
} else if err != 0 {
C.free(unsafe.Pointer(filename))
return NewError("", 500)
}
C.free(unsafe.Pointer(filename)) filename := C.CString(t.Input)
defer C.free(unsafe.Pointer(filename))
if err := C.image_transcode_compute(filename, C.int(t.Size)); err != 0 {
return ErrNotValid
}
return nil return nil
} }

View File

@ -1,5 +1,4 @@
// This plugins attempt to crash http scanners used by script kiddies package plg_security_scanner
package main
import ( import (
"bytes" "bytes"
@ -16,8 +15,8 @@ var (
billionsOfLol *bytes.Buffer billionsOfLol *bytes.Buffer
) )
func Init(config *Configuration) { func init() {
if plugin_enable := config.Get("features.protection.enable").Schema(func(f *FormElement) *FormElement{ if plugin_enable := Config.Get("features.protection.enable").Schema(func(f *FormElement) *FormElement{
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }

View File

@ -1,4 +1,4 @@
package main package plg_security_svg
import ( import (
. "github.com/mickael-kerjean/filestash/server/common" . "github.com/mickael-kerjean/filestash/server/common"
@ -8,9 +8,9 @@ import (
"regexp" "regexp"
) )
func Init(conf *Configuration) { func init() {
disable_svg := func() bool { disable_svg := func() bool {
return conf.Get("features.protection.disable_svg").Schema(func(f *FormElement) *FormElement { return Config.Get("features.protection.disable_svg").Schema(func(f *FormElement) *FormElement {
if f == nil { if f == nil {
f = &FormElement{} f = &FormElement{}
} }