mirror of
https://github.com/1Panel-dev/1Panel.git
synced 2026-09-22 16:00:51 +00:00
feat: Optimize reverse proxy handling for applications with HTTPS ports. (#12181)
This commit is contained in:
@@ -113,8 +113,8 @@ var catalog = map[string]Meta{
|
||||
EnvKey: "MINIMAX_API_KEY",
|
||||
Enabled: true,
|
||||
Models: []Model{
|
||||
{ID: "minimax/MiniMax-M2.1", Name: "MiniMax M2.1"},
|
||||
{ID: "minimax/MiniMax-M2.1-lightning", Name: "MiniMax M2.1 Lightning"},
|
||||
{ID: "minimax/MiniMax-M2.5", Name: "MiniMax M2.5"},
|
||||
{ID: "minimax/MiniMax-M2.5-highspeed", Name: "MiniMax M2.5 highspeed"},
|
||||
},
|
||||
},
|
||||
"kimi": {
|
||||
|
||||
@@ -114,7 +114,7 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
|
||||
err = errors.New("invalid proxy config, no location found")
|
||||
return
|
||||
}
|
||||
location.UpdateDirective("proxy_pass", []string{req.ProxyPass})
|
||||
applyLocationProxyPass(location, req.ProxyPass, &req.SNI, req.ProxySSLName)
|
||||
location.UpdateDirective("proxy_set_header", []string{"Host", req.ProxyHost})
|
||||
location.ChangePath(req.Modifier, req.Match)
|
||||
// Server Cache Settings
|
||||
@@ -143,15 +143,7 @@ func (w WebsiteService) OperateProxy(req request.WebsiteProxyConfig) (err error)
|
||||
} else {
|
||||
location.RemoveSubFilter()
|
||||
}
|
||||
// SSL Settings
|
||||
if req.SNI {
|
||||
location.UpdateDirective("proxy_ssl_server_name", []string{"on"})
|
||||
if req.ProxySSLName != "" {
|
||||
location.UpdateDirective("proxy_ssl_name", []string{req.ProxySSLName})
|
||||
}
|
||||
} else {
|
||||
location.UpdateDirective("proxy_ssl_server_name", []string{"off"})
|
||||
}
|
||||
// Explicit SNI configuration still takes precedence over the automatic HTTPS upstream default.
|
||||
// CORS Settings
|
||||
if req.Cors {
|
||||
location.UpdateDirective("add_header", []string{"Access-Control-Allow-Origin", req.AllowOrigins, "always"})
|
||||
|
||||
@@ -47,6 +47,30 @@ func handleChineseDomain(domain string) (string, error) {
|
||||
return domain, nil
|
||||
}
|
||||
|
||||
func isHTTPSProxyPass(proxyPass string) bool {
|
||||
return strings.HasPrefix(strings.ToLower(strings.TrimSpace(proxyPass)), "https://")
|
||||
}
|
||||
|
||||
func applyLocationProxyPass(location *components.Location, proxyPass string, sni *bool, proxySSLName string) {
|
||||
location.UpdateDirective("proxy_pass", []string{proxyPass})
|
||||
|
||||
enableSNI := isHTTPSProxyPass(proxyPass)
|
||||
if sni != nil {
|
||||
enableSNI = enableSNI && *sni
|
||||
}
|
||||
if enableSNI {
|
||||
location.UpdateDirective("proxy_ssl_server_name", []string{"on"})
|
||||
} else {
|
||||
location.UpdateDirective("proxy_ssl_server_name", []string{"off"})
|
||||
}
|
||||
|
||||
sslName := "$proxy_host"
|
||||
if proxySSLName != "" {
|
||||
sslName = proxySSLName
|
||||
}
|
||||
location.UpdateDirective("proxy_ssl_name", []string{sslName})
|
||||
}
|
||||
|
||||
func createIndexFile(website *model.Website, runtime *model.Runtime) error {
|
||||
var (
|
||||
indexPath string
|
||||
@@ -122,7 +146,7 @@ func createProxyFile(website *model.Website) error {
|
||||
return errors.New("error")
|
||||
}
|
||||
location.ChangePath("^~", "/")
|
||||
location.UpdateDirective("proxy_pass", []string{website.Proxy})
|
||||
applyLocationProxyPass(location, website.Proxy, nil, "")
|
||||
location.UpdateDirective("proxy_set_header", []string{"Host", "$host"})
|
||||
if err := nginx.WriteConfig(config, nginx.IndentedStyle); err != nil {
|
||||
return buserr.WithErr("ErrUpdateBuWebsite", err)
|
||||
|
||||
@@ -57,7 +57,7 @@
|
||||
<span class="font-medium">{{ $t('website.sni') }}</span>
|
||||
<span class="input-help">{{ $t('website.sniHelper') }}</span>
|
||||
</div>
|
||||
<el-switch v-model="proxy.sni" size="large" />
|
||||
<el-switch v-model="proxy.sni" size="large" @change="handleSNIChange" />
|
||||
</div>
|
||||
|
||||
<el-form-item
|
||||
@@ -237,7 +237,7 @@ import { operateProxyConfig } from '@/api/modules/website';
|
||||
import { checkNumberRange, Rules } from '@/global/form-rules';
|
||||
import i18n from '@/lang';
|
||||
import { FormInstance } from 'element-plus';
|
||||
import { ref } from 'vue';
|
||||
import { ref, watch } from 'vue';
|
||||
import { MsgError, MsgSuccess } from '@/utils/message';
|
||||
import { Website } from '@/api/interface/website';
|
||||
import { Units } from '@/global/mimetype';
|
||||
@@ -258,6 +258,8 @@ const rules = ref({
|
||||
const open = ref(false);
|
||||
const loading = ref(false);
|
||||
const activeTab = ref('basic');
|
||||
const shouldAutoEnableSNI = ref(false);
|
||||
const sniTouched = ref(false);
|
||||
|
||||
const initData = (): Website.ProxyConfig => ({
|
||||
id: 0,
|
||||
@@ -300,6 +302,8 @@ const acceptParams = (proxyParam: Website.ProxyConfig) => {
|
||||
replaces.value = [];
|
||||
proxy.value = proxyParam;
|
||||
activeTab.value = 'basic';
|
||||
shouldAutoEnableSNI.value = proxy.value.operate === 'create';
|
||||
sniTouched.value = false;
|
||||
|
||||
// Initialize browserCache based on cacheTime value
|
||||
if (proxy.value.cacheTime > 0) {
|
||||
@@ -359,6 +363,10 @@ const removeReplace = (index: number) => {
|
||||
replaces.value.splice(index, 1);
|
||||
};
|
||||
|
||||
const handleSNIChange = () => {
|
||||
sniTouched.value = true;
|
||||
};
|
||||
|
||||
const getProxyHost = () => {
|
||||
if (isDomain(proxy.value.proxyAddress)) {
|
||||
proxy.value.proxyHost = proxy.value.proxyAddress;
|
||||
@@ -425,6 +433,16 @@ const getProtocolAndHost = (url: string): { protocol: string; host: string } | n
|
||||
return { protocol: '', host: url };
|
||||
};
|
||||
|
||||
watch(
|
||||
() => proxy.value.proxyProtocol,
|
||||
(protocol) => {
|
||||
if (proxy.value.operate !== 'create' || sniTouched.value || !shouldAutoEnableSNI.value) {
|
||||
return;
|
||||
}
|
||||
proxy.value.sni = protocol === 'https://';
|
||||
},
|
||||
);
|
||||
|
||||
defineExpose({
|
||||
acceptParams,
|
||||
});
|
||||
|
||||
@@ -672,11 +672,31 @@ const getAppByService = async (key: string) => {
|
||||
dbServices.value = res.data;
|
||||
};
|
||||
|
||||
const getProxyTargetFromApp = (app: Pick<App.AppInstalled, 'httpPort' | 'httpsPort'>) => {
|
||||
if ((app.httpPort ?? 0) > 0) {
|
||||
return {
|
||||
protocol: 'http://',
|
||||
address: `127.0.0.1:${app.httpPort}`,
|
||||
};
|
||||
}
|
||||
if ((app.httpsPort ?? 0) > 0) {
|
||||
return {
|
||||
protocol: 'https://',
|
||||
address: `127.0.0.1:${app.httpsPort}`,
|
||||
};
|
||||
}
|
||||
return {
|
||||
protocol: 'http://',
|
||||
address: '',
|
||||
};
|
||||
};
|
||||
|
||||
const changeInstall = () => {
|
||||
appInstalls.value.forEach((app) => {
|
||||
if (app.id === website.value.appInstallId) {
|
||||
website.value.proxyProtocol = 'http://';
|
||||
website.value.proxyAddress = '127.0.0.1:' + app.httpPort;
|
||||
const target = getProxyTargetFromApp(app);
|
||||
website.value.proxyProtocol = target.protocol;
|
||||
website.value.proxyAddress = target.address;
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
Reference in New Issue
Block a user