Files
vServer/Backend/WebServer/proxy_server.go
Falknat f518171825 Proxy - Добавление AutoHTTPS
Включает Автоматическая перенаправление на HTTPS на proxy
2025-10-02 09:34:19 +07:00

132 lines
4.5 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package webserver
import (
"crypto/tls"
"io"
"log"
"net/http"
"strings"
"sync"
"vServer/Backend/config"
tools "vServer/Backend/tools"
)
var (
configMutex sync.RWMutex
)
func StartHandlerProxy(w http.ResponseWriter, r *http.Request) (valid bool) {
valid = false
configMutex.RLock()
defer configMutex.RUnlock()
// Проходим по всем прокси конфигурациям
for _, proxyConfig := range config.ConfigData.Proxy_Service {
// Пропускаем отключенные прокси
if !proxyConfig.Enable {
continue
}
// Проверяем совпадение домена
if r.Host != proxyConfig.ExternalDomain {
continue
}
valid = true
// Проверяем AutoHTTPS - редирект с HTTP на HTTPS
https_check := !(r.TLS == nil)
if !https_check && proxyConfig.AutoHTTPS {
// Перенаправляем на HTTPS
httpsURL := "https://" + r.Host + r.URL.RequestURI()
http.Redirect(w, r, httpsURL, http.StatusMovedPermanently)
tools.Logs_file(0, "P-HTTP", "🔀 IP клиента: "+r.RemoteAddr+" Редирект HTTP → HTTPS: "+r.Host+r.URL.Path, "logs_http.log", false)
return valid
}
// Логирование прокси-запроса
if https_check {
tools.Logs_file(0, "P-HTTPS", "🔍 IP клиента: "+r.RemoteAddr+" Обработка запроса: https://"+r.Host+r.URL.Path+" → "+proxyConfig.LocalAddress+":"+proxyConfig.LocalPort, "logs_https.log", false)
} else {
tools.Logs_file(0, "P-HTTP", "🔍 IP клиента: "+r.RemoteAddr+" Обработка запроса: http://"+r.Host+r.URL.Path+" → "+proxyConfig.LocalAddress+":"+proxyConfig.LocalPort, "logs_http.log", false)
}
// Определяем протокол для локального соединения
protocol := "http"
if proxyConfig.ServiceHTTPSuse {
protocol = "https"
}
// Проксирование на локальный адрес
proxyURL := protocol + "://" + proxyConfig.LocalAddress + ":" + proxyConfig.LocalPort + r.URL.RequestURI()
proxyReq, err := http.NewRequest(r.Method, proxyURL, r.Body)
if err != nil {
http.Error(w, "Ошибка создания прокси-запроса", http.StatusInternalServerError)
return valid
}
// Копируем ВСЕ заголовки без изменений (кроме технических)
for name, values := range r.Header {
// Пропускаем только технические заголовки HTTP/1.1
lowerName := strings.ToLower(name)
if lowerName == "connection" || lowerName == "upgrade" ||
lowerName == "proxy-connection" || lowerName == "te" ||
lowerName == "trailers" || lowerName == "transfer-encoding" {
continue
}
// Копируем заголовок как есть
for _, value := range values {
proxyReq.Header.Add(name, value)
}
}
// Прозрачная передача - никаких дополнительных заголовков
// Все заголовки уже скопированы выше "как есть"
// Выполняем прокси-запрос
client := &http.Client{
// Отключаем автоматическое следование редиректам для корректной работы с авторизацией
CheckRedirect: func(req *http.Request, via []*http.Request) error {
return http.ErrUseLastResponse
},
}
// Для HTTPS соединений настраиваем TLS (если понадобится)
if proxyConfig.ServiceHTTPSuse {
client.Transport = &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true, // Простая настройка для внутренних соединений
},
}
}
resp, err := client.Do(proxyReq)
if err != nil {
http.Error(w, "Ошибка прокси-запроса", http.StatusBadGateway)
tools.Logs_file(1, "PROXY", "Ошибка прокси-запроса: "+err.Error(), "logs_proxy.log", false)
return valid
}
defer resp.Body.Close()
// Прозрачно копируем ВСЕ заголовки ответа без изменений
for name, values := range resp.Header {
for _, value := range values {
w.Header().Add(name, value)
}
}
// Устанавливаем статус код
w.WriteHeader(resp.StatusCode)
// Копируем тело ответа
if _, err := io.Copy(w, resp.Body); err != nil {
log.Printf("Ошибка копирования тела ответа: %v", err)
}
return valid
}
return valid
}