✨ Publish
This commit is contained in:
parent
61ab586f4f
commit
5ae31d8a07
@ -8,7 +8,7 @@ A blazing fast reverse proxy with a lot of shining features.
|
||||
2. Static file hosting
|
||||
3. ~~Analytics and Metrics~~
|
||||
4. Integrate with CI/CD
|
||||
5. ~~Webhook integration~~
|
||||
5. Webhook integration
|
||||
6. ~~Web management panel~~
|
||||
7. **Blazing fast ⚡**
|
||||
|
||||
|
@ -12,6 +12,7 @@
|
||||
],
|
||||
"upstreams": [
|
||||
{
|
||||
"id": "example",
|
||||
"name": "Example Upstream",
|
||||
"uri": "file://C:\\site"
|
||||
}
|
||||
|
@ -13,8 +13,14 @@ func InitAdministration() *fiber.App {
|
||||
ServerHeader: fmt.Sprintf("RoadSign Administration v%s", roadsign.AppVersion),
|
||||
DisableStartupMessage: true,
|
||||
EnableIPValidation: true,
|
||||
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
|
||||
TrustedProxies: viper.GetStringSlice("security.administration_trusted_proxies"),
|
||||
})
|
||||
|
||||
webhooks := app.Group("/webhooks").Name("WebHooks")
|
||||
{
|
||||
webhooks.Put("/publish/:site/:upstream", doPublish)
|
||||
}
|
||||
|
||||
return app
|
||||
}
|
||||
|
63
pkg/administration/publish.go
Normal file
63
pkg/administration/publish.go
Normal file
@ -0,0 +1,63 @@
|
||||
package administration
|
||||
|
||||
import (
|
||||
"code.smartsheep.studio/goatworks/roadsign/pkg/fs"
|
||||
"code.smartsheep.studio/goatworks/roadsign/pkg/sign"
|
||||
"github.com/gofiber/fiber/v2"
|
||||
"github.com/google/uuid"
|
||||
"os"
|
||||
"path/filepath"
|
||||
)
|
||||
|
||||
func doPublish(ctx *fiber.Ctx) error {
|
||||
var upstream *sign.UpstreamConfig
|
||||
for _, item := range sign.App.Sites {
|
||||
if item.ID == ctx.Params("site") {
|
||||
for _, stream := range item.Upstreams {
|
||||
if stream.ID == ctx.Params("upstream") {
|
||||
upstream = &stream
|
||||
break
|
||||
}
|
||||
}
|
||||
break
|
||||
}
|
||||
}
|
||||
|
||||
if upstream == nil {
|
||||
return fiber.ErrNotFound
|
||||
} else if upstream.GetType() != sign.UpstreamTypeFile {
|
||||
return fiber.ErrUnprocessableEntity
|
||||
}
|
||||
|
||||
workdir, _ := upstream.GetRawURI()
|
||||
|
||||
if ctx.Query("overwrite", "yes") == "yes" {
|
||||
files, _ := filepath.Glob(filepath.Join(workdir, "*"))
|
||||
for _, file := range files {
|
||||
_ = os.Remove(file)
|
||||
}
|
||||
}
|
||||
|
||||
if form, err := ctx.MultipartForm(); err == nil {
|
||||
files := form.File["attachments"]
|
||||
for _, file := range files {
|
||||
mimetype := file.Header["Content-Type"][0]
|
||||
switch mimetype {
|
||||
case "application/zip":
|
||||
dst := filepath.Join(os.TempDir(), uuid.NewString()+".zip")
|
||||
if err := ctx.SaveFile(file, dst); err != nil {
|
||||
return err
|
||||
} else {
|
||||
_ = fs.Unzip(dst, workdir)
|
||||
}
|
||||
default:
|
||||
dst := filepath.Join(workdir, file.Filename)
|
||||
if err := ctx.SaveFile(file, dst); err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return ctx.SendStatus(fiber.StatusOK)
|
||||
}
|
@ -34,7 +34,7 @@ func main() {
|
||||
if err := sign.ReadInConfig(viper.GetString("paths.configs")); err != nil {
|
||||
log.Panic().Err(err).Msg("An error occurred when loading configurations.")
|
||||
} else {
|
||||
log.Debug().Any("sites", sign.C).Msg("All configuration has been loaded.")
|
||||
log.Debug().Any("sites", sign.App).Msg("All configuration has been loaded.")
|
||||
}
|
||||
|
||||
// Init hypertext server
|
||||
|
72
pkg/fs/zip.go
Normal file
72
pkg/fs/zip.go
Normal file
@ -0,0 +1,72 @@
|
||||
package fs
|
||||
|
||||
import (
|
||||
"archive/zip"
|
||||
"fmt"
|
||||
"io"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
)
|
||||
|
||||
func Unzip(src, dest string) error {
|
||||
r, err := zip.OpenReader(src)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := r.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
_ = os.MkdirAll(dest, 0755)
|
||||
|
||||
extract := func(f *zip.File) error {
|
||||
rc, err := f.Open()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := rc.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
path := filepath.Join(dest, f.Name)
|
||||
|
||||
if !strings.HasPrefix(path, filepath.Clean(dest)+string(os.PathSeparator)) {
|
||||
return fmt.Errorf("illegal file path: %s", path)
|
||||
}
|
||||
|
||||
if f.FileInfo().IsDir() {
|
||||
_ = os.MkdirAll(path, f.Mode())
|
||||
} else {
|
||||
_ = os.MkdirAll(filepath.Dir(path), f.Mode())
|
||||
f, err := os.OpenFile(path, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
defer func() {
|
||||
if err := f.Close(); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}()
|
||||
|
||||
_, err = io.Copy(f, rc)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
for _, f := range r.File {
|
||||
err := extract(f)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
@ -16,7 +16,6 @@ func InitServer() *fiber.App {
|
||||
ServerHeader: fmt.Sprintf("RoadSign v%s", roadsign.AppVersion),
|
||||
DisableStartupMessage: true,
|
||||
EnableIPValidation: true,
|
||||
EnablePrintRoutes: viper.GetBool("debug.print_routes"),
|
||||
Prefork: viper.GetBool("performance.prefork"),
|
||||
BodyLimit: viper.GetInt("hypertext.limitation.max_body_size"),
|
||||
})
|
||||
|
@ -15,7 +15,7 @@ func UseProxies(app *fiber.App) {
|
||||
headers := ctx.GetReqHeaders()
|
||||
|
||||
// Filtering sites
|
||||
for _, site := range sign.C.Sites {
|
||||
for _, site := range sign.App.Sites {
|
||||
// Matching rules
|
||||
for _, rule := range site.Rules {
|
||||
if !lo.Contains(rule.Host, host) {
|
||||
@ -95,7 +95,7 @@ func makeResponse(ctx *fiber.Ctx, site sign.SiteConfig) error {
|
||||
}
|
||||
|
||||
// Forward
|
||||
err := sign.C.Forward(ctx, site)
|
||||
err := sign.App.Forward(ctx, site)
|
||||
|
||||
// Modify response
|
||||
for _, transformer := range site.Transformers {
|
||||
|
@ -8,7 +8,7 @@ import (
|
||||
"strings"
|
||||
)
|
||||
|
||||
var C *AppConfig
|
||||
var App *AppConfig
|
||||
|
||||
func ReadInConfig(root string) error {
|
||||
cfg := &AppConfig{
|
||||
@ -37,7 +37,7 @@ func ReadInConfig(root string) error {
|
||||
return err
|
||||
}
|
||||
|
||||
C = cfg
|
||||
App = cfg
|
||||
|
||||
return nil
|
||||
}
|
||||
|
@ -15,6 +15,8 @@ const (
|
||||
)
|
||||
|
||||
type UpstreamConfig struct {
|
||||
ID string `json:"id"`
|
||||
|
||||
Name string `json:"name"`
|
||||
URI string `json:"uri"`
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user