enhance: Force HTTPS #109

Close #109
This commit is contained in:
0xJacky 2023-04-29 23:03:34 +08:00
parent d5fa42da3c
commit c2a3cb622e
No known key found for this signature in database
GPG key ID: B6E4A6E4A561BAF0
2 changed files with 162 additions and 149 deletions

View file

@ -1,192 +1,192 @@
package service package service
import ( import (
"bufio" "bufio"
"bytes" "bytes"
"github.com/0xJacky/Nginx-UI/server/pkg/nginx" "github.com/0xJacky/Nginx-UI/server/pkg/nginx"
"github.com/0xJacky/Nginx-UI/server/settings" "github.com/0xJacky/Nginx-UI/server/settings"
templ "github.com/0xJacky/Nginx-UI/template" templ "github.com/0xJacky/Nginx-UI/template"
"github.com/BurntSushi/toml" "github.com/BurntSushi/toml"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/tufanbarisyildirim/gonginx/parser" "github.com/tufanbarisyildirim/gonginx/parser"
"io" "io"
"log" "log"
"path/filepath" "path/filepath"
"strings" "strings"
"text/template" "text/template"
) )
type TVariable struct { type TVariable struct {
Type string `json:"type"` Type string `json:"type"`
Name map[string]string `json:"name"` Name map[string]string `json:"name"`
Value interface{} `json:"value"` Value interface{} `json:"value"`
} }
type ConfigInfoItem struct { type ConfigInfoItem struct {
Name string `json:"name"` Name string `json:"name"`
Description map[string]string `json:"description"` Description map[string]string `json:"description"`
Author string `json:"author"` Author string `json:"author"`
Filename string `json:"filename"` Filename string `json:"filename"`
Variables map[string]TVariable `json:"variables"` Variables map[string]TVariable `json:"variables"`
} }
func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) { func GetTemplateInfo(path, name string) (configListItem ConfigInfoItem) {
configListItem = ConfigInfoItem{ configListItem = ConfigInfoItem{
Description: make(map[string]string), Description: make(map[string]string),
Filename: name, Filename: name,
} }
file, _ := templ.DistFS.Open(filepath.Join(path, name)) file, _ := templ.DistFS.Open(filepath.Join(path, name))
defer file.Close() defer file.Close()
r := bufio.NewReader(file) r := bufio.NewReader(file)
bytes, _, err := r.ReadLine() bytes, _, err := r.ReadLine()
if err == io.EOF { if err == io.EOF {
return return
} }
line := strings.TrimSpace(string(bytes)) line := strings.TrimSpace(string(bytes))
if line != "# Nginx UI Template Start" { if line != "# Nginx UI Template Start" {
return return
} }
var content string var content string
for { for {
bytes, _, err = r.ReadLine() bytes, _, err = r.ReadLine()
if err == io.EOF { if err == io.EOF {
break break
} }
line = strings.TrimSpace(string(bytes)) line = strings.TrimSpace(string(bytes))
if line == "# Nginx UI Template End" { if line == "# Nginx UI Template End" {
break break
} }
content += line + "\n" content += line + "\n"
} }
_, err = toml.Decode(content, &configListItem) _, err = toml.Decode(content, &configListItem)
if err != nil { if err != nil {
log.Println("toml.Decode", err.Error()) log.Println("toml.Decode", err.Error())
} }
return return
} }
type ConfigDetail struct { type ConfigDetail struct {
Custom string `json:"custom"` Custom string `json:"custom"`
nginx.NgxServer nginx.NgxServer
} }
func ParseTemplate(path, name string, bindData map[string]TVariable) (c ConfigDetail, err error) { func ParseTemplate(path, name string, bindData map[string]TVariable) (c ConfigDetail, err error) {
file, err := templ.DistFS.Open(filepath.Join(path, name)) file, err := templ.DistFS.Open(filepath.Join(path, name))
if err != nil { if err != nil {
err = errors.Wrap(err, "error tokenized template") err = errors.Wrap(err, "error tokenized template")
return return
} }
defer file.Close() defer file.Close()
r := bufio.NewReader(file) r := bufio.NewReader(file)
var flag bool var flag bool
custom := "" custom := ""
content := "" content := ""
for { for {
bytes, _, err := r.ReadLine() lineBytes, _, err := r.ReadLine()
if err == io.EOF { if err == io.EOF {
break break
} }
orig := string(bytes) orig := string(lineBytes)
line := strings.TrimSpace(orig) line := strings.TrimSpace(orig)
switch { switch {
case line == "# Nginx UI Custom Start": case line == "# Nginx UI Custom Start":
flag = true flag = true
case line == "# Nginx UI Custom End": case line == "# Nginx UI Custom End":
flag = false flag = false
case flag == true: case flag == true:
custom += orig + "\n" custom += orig + "\n"
case flag == false: case flag == false:
content += orig + "\n" content += orig + "\n"
} }
} }
data := gin.H{ data := gin.H{
"HTTPPORT": settings.ServerSettings.HttpPort, "HTTPPORT": settings.ServerSettings.HttpPort,
"HTTP01PORT": settings.ServerSettings.HTTPChallengePort, "HTTP01PORT": settings.ServerSettings.HTTPChallengePort,
} }
for k, v := range bindData { for k, v := range bindData {
data[k] = v.Value data[k] = v.Value
} }
t, err := template.New(name).Parse(custom) t, err := template.New(name).Parse(custom)
if err != nil { if err != nil {
err = errors.Wrap(err, "error parse template.custom") err = errors.Wrap(err, "error parse template.custom")
return return
} }
var buf bytes.Buffer var buf bytes.Buffer
err = t.Execute(&buf, data) err = t.Execute(&buf, data)
if err != nil { if err != nil {
err = errors.Wrap(err, "error execute template") err = errors.Wrap(err, "error execute template")
return return
} }
custom = strings.TrimSpace(buf.String()) custom = strings.TrimSpace(buf.String())
templatePart := strings.Split(content, "# Nginx UI Template End") templatePart := strings.Split(content, "# Nginx UI Template End")
if len(templatePart) < 2 { if len(templatePart) < 2 {
return return
} }
content = templatePart[1] content = templatePart[1]
t, err = template.New(name).Parse(content) t, err = template.New(name).Parse(content)
if err != nil { if err != nil {
err = errors.Wrap(err, "error parse template") err = errors.Wrap(err, "error parse template")
return return
} }
buf.Reset() buf.Reset()
err = t.Execute(&buf, data) err = t.Execute(&buf, data)
if err != nil { if err != nil {
err = errors.Wrap(err, "error execute template") err = errors.Wrap(err, "error execute template")
return return
} }
content = buf.String() content = buf.String()
p := parser.NewStringParser(content) p := parser.NewStringParser(content)
config := p.Parse() config := p.Parse()
c.Custom = custom c.Custom = custom
for _, d := range config.GetDirectives() { for _, d := range config.GetDirectives() {
switch d.GetName() { switch d.GetName() {
case nginx.Location: case nginx.Location:
l := &nginx.NgxLocation{ l := &nginx.NgxLocation{
Path: strings.Join(d.GetParameters(), " "), Path: strings.Join(d.GetParameters(), " "),
} }
l.ParseLocation(d, 0) l.ParseLocation(d, 0)
c.NgxServer.Locations = append(c.NgxServer.Locations, l) c.NgxServer.Locations = append(c.NgxServer.Locations, l)
default: default:
dir := &nginx.NgxDirective{ dir := &nginx.NgxDirective{
Directive: d.GetName(), Directive: d.GetName(),
} }
dir.ParseDirective(d, 0) dir.ParseDirective(d, 0)
c.NgxServer.Directives = append(c.NgxServer.Directives, dir) c.NgxServer.Directives = append(c.NgxServer.Directives, dir)
} }
} }
return return
} }
func GetTemplateList(path string) (configList []ConfigInfoItem, err error) { func GetTemplateList(path string) (configList []ConfigInfoItem, err error) {
configs, err := templ.DistFS.ReadDir(path) configs, err := templ.DistFS.ReadDir(path)
if err != nil { if err != nil {
err = errors.Wrap(err, "error get template list") err = errors.Wrap(err, "error get template list")
return return
} }
for _, config := range configs { for _, config := range configs {
configList = append(configList, GetTemplateInfo(path, config.Name())) configList = append(configList, GetTemplateInfo(path, config.Name()))
} }
return return
} }

View file

@ -2,5 +2,18 @@
name = "HTTP to HTTPS" name = "HTTP to HTTPS"
author = "@0xJacky" author = "@0xJacky"
description = { en = "HTTP force redirect to HTTPS Config", zh_CN = "HTTP 强制跳转 HTTPS 配置"} description = { en = "HTTP force redirect to HTTPS Config", zh_CN = "HTTP 强制跳转 HTTPS 配置"}
[variables.host]
type = "string"
name = { en = "Host", zh_CN = "主机"}
value = ""
# Nginx UI Template End # Nginx UI Template End
{{- if .host }}
if ($host == {{ .host }}) {
return 307 https://$server_name$request_uri;
}
return 404;
{{ else }}
return 307 https://$server_name$request_uri; return 307 https://$server_name$request_uri;
{{- end }}