fixing some functions
This commit is contained in:
+110
-19
@@ -16,6 +16,47 @@ import (
|
||||
"github.com/sirupsen/logrus"
|
||||
)
|
||||
|
||||
const (
|
||||
acmeChallengePrefix = "/.well-known/acme-challenge/"
|
||||
acmeWellknownPrefix = "/.well-known/acme-wellknown/"
|
||||
)
|
||||
|
||||
// IsAcmeWellKnownPath reports whether path is an ACME HTTP-01 challenge URL.
|
||||
func IsAcmeWellKnownPath(path string) bool {
|
||||
return strings.HasPrefix(path, acmeChallengePrefix) || strings.HasPrefix(path, acmeWellknownPrefix)
|
||||
}
|
||||
|
||||
func acmeTokenFromPath(path string) (token string, layout string, ok bool) {
|
||||
switch {
|
||||
case strings.HasPrefix(path, acmeChallengePrefix):
|
||||
layout = acmeChallengePrefix
|
||||
token = strings.TrimPrefix(path, acmeChallengePrefix)
|
||||
case strings.HasPrefix(path, acmeWellknownPrefix):
|
||||
layout = acmeWellknownPrefix
|
||||
token = strings.TrimPrefix(path, acmeWellknownPrefix)
|
||||
default:
|
||||
return "", "", false
|
||||
}
|
||||
if token == "" || strings.Contains(token, "..") {
|
||||
return "", "", false
|
||||
}
|
||||
return token, layout, true
|
||||
}
|
||||
|
||||
func acmeFilePaths(wellKnownDir, token string) []string {
|
||||
return []string{
|
||||
filepath.Join(wellKnownDir, "acme-challenge", token),
|
||||
filepath.Join(wellKnownDir, token),
|
||||
}
|
||||
}
|
||||
|
||||
func defaultAcmeWritePath(wellKnownDir, token, layout string) string {
|
||||
if layout == acmeWellknownPrefix {
|
||||
return filepath.Join(wellKnownDir, token)
|
||||
}
|
||||
return filepath.Join(wellKnownDir, "acme-challenge", token)
|
||||
}
|
||||
|
||||
// stripHostPort возвращает только имя хоста, если в строке был порт.
|
||||
func stripHostPort(host string) string {
|
||||
h, _, err := net.SplitHostPort(host)
|
||||
@@ -143,9 +184,15 @@ type reverseProxiesHandler struct {
|
||||
func (rph reverseProxiesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||
logrus.Infof("Incoming request: %s %s from %s (Host: %s)", r.Method, r.URL.Path, r.RemoteAddr, r.Host)
|
||||
|
||||
if strings.HasPrefix(r.URL.Path, "/.well-known/acme-wellknown/") {
|
||||
logrus.Infof("Handling .well-known/acme-wellknown request: %s", r.URL.Path)
|
||||
rph.handleWellKnown(w, r)
|
||||
if strings.HasPrefix(r.URL.Path, acmeChallengePrefix) || strings.HasPrefix(r.URL.Path, acmeWellknownPrefix) {
|
||||
token, layout, ok := acmeTokenFromPath(r.URL.Path)
|
||||
if !ok {
|
||||
logrus.Warnf("Invalid .well-known path: %s", r.URL.Path)
|
||||
http.Error(w, "Invalid path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
logrus.Infof("Handling ACME well-known request: %s (layout=%s)", r.URL.Path, layout)
|
||||
rph.handleWellKnown(w, r, token, layout)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -194,7 +241,7 @@ func (rph reverseProxiesHandler) getHostList() []string {
|
||||
return hosts
|
||||
}
|
||||
|
||||
func (rph reverseProxiesHandler) handleWellKnown(w http.ResponseWriter, r *http.Request) {
|
||||
func (rph reverseProxiesHandler) handleWellKnown(w http.ResponseWriter, r *http.Request, token, layout string) {
|
||||
// Проверяем и при необходимости монтируем NFS перед обработкой
|
||||
if err := nfs.EnsureMounted(); err != nil {
|
||||
logrus.Errorf("Failed to ensure NFS is mounted: %v", err)
|
||||
@@ -202,23 +249,18 @@ func (rph reverseProxiesHandler) handleWellKnown(w http.ResponseWriter, r *http.
|
||||
return
|
||||
}
|
||||
|
||||
path := strings.TrimPrefix(r.URL.Path, "/.well-known/acme-wellknown/")
|
||||
if path == "" || strings.Contains(path, "..") {
|
||||
logrus.Warnf("Invalid .well-known path: %s", r.URL.Path)
|
||||
http.Error(w, "Invalid path", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
fullPath := filepath.Join(rph.WellKnownDir, path)
|
||||
logrus.Infof("Well-known request: method=%s, path=%s, fullPath=%s", r.Method, path, fullPath)
|
||||
paths := acmeFilePaths(rph.WellKnownDir, token)
|
||||
logrus.Infof("Well-known request: method=%s, token=%s, layout=%s, paths=%v",
|
||||
r.Method, token, layout, paths)
|
||||
switch r.Method {
|
||||
case "GET", "HEAD":
|
||||
data, err := ioutil.ReadFile(fullPath)
|
||||
data, _, err := readFirstExisting(paths)
|
||||
if err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
logrus.Errorf("Error reading file %s: %v", fullPath, err)
|
||||
logrus.Errorf("Error reading ACME challenge files %v: %v", paths, err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -234,14 +276,18 @@ func (rph reverseProxiesHandler) handleWellKnown(w http.ResponseWriter, r *http.
|
||||
http.Error(w, "Bad request", http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
dir := filepath.Dir(fullPath)
|
||||
writePath := existingAcmePath(paths)
|
||||
if writePath == "" {
|
||||
writePath = defaultAcmeWritePath(rph.WellKnownDir, token, layout)
|
||||
}
|
||||
dir := filepath.Dir(writePath)
|
||||
if err := os.MkdirAll(dir, 0755); err != nil {
|
||||
logrus.Errorf("Error creating directory %s: %v", dir, err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
if err := ioutil.WriteFile(fullPath, data, 0644); err != nil {
|
||||
logrus.Errorf("Error writing file %s: %v", fullPath, err)
|
||||
if err := ioutil.WriteFile(writePath, data, 0644); err != nil {
|
||||
logrus.Errorf("Error writing file %s: %v", writePath, err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -252,12 +298,12 @@ func (rph reverseProxiesHandler) handleWellKnown(w http.ResponseWriter, r *http.
|
||||
w.Write([]byte("File created successfully"))
|
||||
}
|
||||
case "DELETE":
|
||||
if err := os.Remove(fullPath); err != nil {
|
||||
if err := removeFirstExisting(paths); err != nil {
|
||||
if os.IsNotExist(err) {
|
||||
http.NotFound(w, r)
|
||||
return
|
||||
}
|
||||
logrus.Errorf("Error deleting file %s: %v", fullPath, err)
|
||||
logrus.Errorf("Error deleting ACME challenge files %v: %v", paths, err)
|
||||
http.Error(w, "Internal server error", http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
@@ -267,3 +313,48 @@ func (rph reverseProxiesHandler) handleWellKnown(w http.ResponseWriter, r *http.
|
||||
http.Error(w, "Method not allowed", http.StatusMethodNotAllowed)
|
||||
}
|
||||
}
|
||||
|
||||
func readFirstExisting(paths []string) ([]byte, string, error) {
|
||||
var lastErr error
|
||||
for _, path := range paths {
|
||||
data, err := ioutil.ReadFile(path)
|
||||
if err == nil {
|
||||
return data, path, nil
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
return nil, "", err
|
||||
}
|
||||
lastErr = err
|
||||
}
|
||||
if lastErr == nil {
|
||||
lastErr = os.ErrNotExist
|
||||
}
|
||||
return nil, "", lastErr
|
||||
}
|
||||
|
||||
func existingAcmePath(paths []string) string {
|
||||
for _, path := range paths {
|
||||
if _, err := os.Stat(path); err == nil {
|
||||
return path
|
||||
}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
|
||||
func removeFirstExisting(paths []string) error {
|
||||
var lastErr error
|
||||
for _, path := range paths {
|
||||
err := os.Remove(path)
|
||||
if err == nil {
|
||||
return nil
|
||||
}
|
||||
if !os.IsNotExist(err) {
|
||||
return err
|
||||
}
|
||||
lastErr = err
|
||||
}
|
||||
if lastErr == nil {
|
||||
lastErr = os.ErrNotExist
|
||||
}
|
||||
return lastErr
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user