🎨 Fix network serving TLS on mobile devices (#17119)

* Until now, the TLS would only work via the fixed port proxy, which
   isn't used on mobile devices.
 * Move the logic for the multiplexer out of the fixed port logic
 * Use the newly moved multiplexer logic for the regular server as well,
   whenever the fixed port and the server port match.
This commit is contained in:
Davide Garberi 2026-03-02 09:43:27 +01:00 committed by GitHub
parent 7912100136
commit 0cc061dec8
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 71 additions and 32 deletions

View file

@ -18,6 +18,7 @@ package proxy
import (
"crypto/tls"
"errors"
"net"
"net/http"
"net/http/httputil"
@ -51,39 +52,10 @@ func InitFixedPortService(host string, useTLS bool, certPath, keyPath string) {
return
}
m := cmux.New(ln)
// Match TLS connections (first byte 0x16 indicates TLS handshake)
tlsL := m.Match(cmux.TLS())
// Match HTTP (anything else)
httpL := m.Match(cmux.Any())
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
logging.LogWarnf("failed to load TLS cert for fixed port service: %s", err)
ln.Close()
return
}
tlsConfig := &tls.Config{Certificates: []tls.Certificate{cert}}
tlsListener := tls.NewListener(tlsL, tlsConfig)
go func() {
httpServer := &http.Server{Handler: proxy}
if err := httpServer.Serve(httpL); err != nil && err != cmux.ErrListenerClosed {
logging.LogWarnf("fixed port HTTP server error: %s", err)
if serveErr := util.ServeMultiplexed(ln, proxy, certPath, keyPath, nil); serveErr != nil {
if serveErr != cmux.ErrListenerClosed && !errors.Is(serveErr, http.ErrServerClosed) {
logging.LogWarnf("fixed port cmux serve error: %s", serveErr)
}
}()
go func() {
httpsServer := &http.Server{Handler: proxy}
if err := httpsServer.Serve(tlsListener); err != nil && err != cmux.ErrListenerClosed {
logging.LogWarnf("fixed port HTTPS server error: %s", err)
}
}()
if err := m.Serve(); err != nil && err != cmux.ErrListenerClosed {
logging.LogWarnf("fixed port cmux serve error: %s", err)
}
} else {
logging.LogInfof("fixed port service [%s] is running", addr)

View file

@ -47,6 +47,7 @@ import (
"github.com/siyuan-note/siyuan/kernel/model"
"github.com/siyuan-note/siyuan/kernel/server/proxy"
"github.com/siyuan-note/siyuan/kernel/util"
"github.com/soheilhy/cmux"
"golang.org/x/net/webdav"
)
@ -244,6 +245,20 @@ func Serve(fastMode bool, cookieKey string) {
Handler: ginServer,
}
if useTLS && (util.FixedPort == util.ServerPort || util.IsPortOpen(util.FixedPort)) {
if err = util.ServeMultiplexed(ln, ginServer, certPath, keyPath, util.HttpServer); err != nil {
if errors.Is(err, http.ErrServerClosed) || err == cmux.ErrListenerClosed {
return
}
if !fastMode {
logging.LogErrorf("boot kernel failed: %s", err)
os.Exit(logging.ExitCodeUnavailablePort)
}
}
return
}
if err = util.HttpServer.Serve(ln); err != nil {
if errors.Is(err, http.ErrServerClosed) {
return

52
kernel/util/cmux.go Normal file
View file

@ -0,0 +1,52 @@
package util
import (
"crypto/tls"
"errors"
"net"
"net/http"
"github.com/siyuan-note/logging"
"github.com/soheilhy/cmux"
)
func ServeMultiplexed(ln net.Listener, handler http.Handler, certPath, keyPath string, httpServer *http.Server) error {
m := cmux.New(ln)
tlsL := m.Match(cmux.TLS())
httpL := m.Match(cmux.Any())
cert, err := tls.LoadX509KeyPair(certPath, keyPath)
if err != nil {
logging.LogErrorf("failed to load TLS cert for multiplexing: %s", err)
return err
}
tlsConfig := &tls.Config{
Certificates: []tls.Certificate{cert},
}
tlsListener := tls.NewListener(tlsL, tlsConfig)
if httpServer == nil {
httpServer = &http.Server{Handler: handler}
} else {
httpServer.Handler = handler
}
httpsServer := &http.Server{Handler: handler}
go func() {
if serveErr := httpServer.Serve(httpL); serveErr != nil && serveErr != cmux.ErrListenerClosed && !errors.Is(serveErr, http.ErrServerClosed) {
logging.LogErrorf("multiplexed HTTP server error: %s", serveErr)
}
}()
go func() {
if serveErr := httpsServer.Serve(tlsListener); serveErr != nil && serveErr != cmux.ErrListenerClosed && !errors.Is(serveErr, http.ErrServerClosed) {
logging.LogErrorf("multiplexed HTTPS server error: %s", serveErr)
}
}()
return m.Serve()
}