proxied fetch support

This commit is contained in:
josc146 2024-03-26 21:23:09 +08:00
parent c2799c9494
commit 08bc342fd6
6 changed files with 96 additions and 0 deletions

View File

@ -7,7 +7,11 @@ import (
"context" "context"
"errors" "errors"
"io" "io"
"log"
"net"
"net/http" "net/http"
"net/http/httputil"
"net/url"
"os" "os"
"os/exec" "os/exec"
"path/filepath" "path/filepath"
@ -27,6 +31,7 @@ type App struct {
HasConfigData bool HasConfigData bool
ConfigData map[string]any ConfigData map[string]any
Dev bool Dev bool
proxyPort int
exDir string exDir string
cmdPrefix string cmdPrefix string
} }
@ -36,6 +41,57 @@ func NewApp() *App {
return &App{} return &App{}
} }
func (a *App) newFetchProxy() {
go func() {
handler := func(w http.ResponseWriter, r *http.Request) {
if r.Method == "OPTIONS" {
w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS")
w.Header().Set("Access-Control-Allow-Headers", "*")
w.Header().Set("Access-Control-Allow-Origin", "*")
return
}
proxy := &httputil.ReverseProxy{
ModifyResponse: func(res *http.Response) error {
res.Header.Set("Access-Control-Allow-Origin", "*")
return nil
},
Director: func(req *http.Request) {
realTarget := req.Header.Get("Real-Target")
if realTarget != "" {
target, err := url.Parse(realTarget)
if err != nil {
log.Printf("Error parsing target URL: %v\n", err)
return
}
req.Header.Set("Accept", "*/*")
req.Header.Del("Origin")
req.Header.Del("Referer")
req.Header.Del("Real-Target")
req.Header.Del("Sec-Fetch-Dest")
req.Header.Del("Sec-Fetch-Mode")
req.Header.Del("Sec-Fetch-Site")
req.URL.Scheme = target.Scheme
req.URL.Host = target.Host
req.URL.Path = target.Path
log.Println("Proxying to", realTarget)
} else {
log.Println("Real-Target header is missing")
}
},
}
proxy.ServeHTTP(w, r)
}
http.HandleFunc("/", handler)
listener, err := net.Listen("tcp", "127.0.0.1:0")
if err != nil {
return
}
a.proxyPort = listener.Addr().(*net.TCPAddr).Port
http.Serve(listener, nil)
}()
}
// startup is called when the app starts. The context is saved // startup is called when the app starts. The context is saved
// so we can call the runtime methods // so we can call the runtime methods
func (a *App) OnStartup(ctx context.Context) { func (a *App) OnStartup(ctx context.Context) {
@ -76,6 +132,7 @@ func (a *App) OnStartup(ctx context.Context) {
a.midiLoop() a.midiLoop()
a.watchFs() a.watchFs()
a.monitorHardware() a.monitorHardware()
a.newFetchProxy()
} }
func (a *App) OnBeforeClose(ctx context.Context) bool { func (a *App) OnBeforeClose(ctx context.Context) bool {
@ -239,3 +296,7 @@ func (a *App) RestartApp() error {
func (a *App) GetPlatform() string { func (a *App) GetPlatform() string {
return runtime.GOOS return runtime.GOOS
} }
func (a *App) GetProxyPort() int {
return a.proxyPort
}

View File

@ -63,6 +63,7 @@ class CommonStore {
monitorData: MonitorData | null = null; monitorData: MonitorData | null = null;
depComplete: boolean = false; depComplete: boolean = false;
platform: Platform = 'windows'; platform: Platform = 'windows';
proxyPort: number = 0;
lastModelName: string = ''; lastModelName: string = '';
// presets manager // presets manager
editingPreset: Preset | null = null; editingPreset: Preset | null = null;
@ -323,6 +324,10 @@ class CommonStore {
this.platform = value; this.platform = value;
} }
setProxyPort(value: number) {
this.proxyPort = value;
}
setCurrentInput(value: string) { setCurrentInput(value: string) {
this.currentInput = value; this.currentInput = value;
} }

View File

@ -310,6 +310,24 @@ export function bytesToReadable(size: number) {
else return bytesToGb(size) + ' GB'; else return bytesToGb(size) + ' GB';
} }
export async function getReqUrl(port: number, path: string, isCore: boolean = false): Promise<{
url: string,
headers: { [key: string]: string }
}> {
const realUrl = getServerRoot(port, isCore) + path;
if (commonStore.platform === 'web')
return {
url: realUrl,
headers: {}
};
if (!commonStore.proxyPort)
await GetProxyPort().then(p => commonStore.setProxyPort(p));
return {
url: `http://127.0.0.1:${commonStore.proxyPort}`,
headers: { 'Real-Target': realUrl }
};
}
export function getServerRoot(defaultLocalPort: number, isCore: boolean = false) { export function getServerRoot(defaultLocalPort: number, isCore: boolean = false) {
const coreCustomApiUrl = commonStore.settings.coreApiUrl.trim().replace(/\/$/, ''); const coreCustomApiUrl = commonStore.settings.coreApiUrl.trim().replace(/\/$/, '');
if (isCore && coreCustomApiUrl) if (isCore && coreCustomApiUrl)

View File

@ -115,6 +115,12 @@ if (!window.go) {
defineApp('ListDirFiles', async () => { defineApp('ListDirFiles', async () => {
return [] return []
}) })
defineApp('GetAbsPath', async (path) => {
return path
})
defineApp('GetProxyPort', async () => {
return 0
})
defineApp('OpenOpenFileDialog', webOpenOpenFileDialog) defineApp('OpenOpenFileDialog', webOpenOpenFileDialog)
defineApp('OpenSaveFileDialog', async (filterPattern, defaultFileName, savedContent) => { defineApp('OpenSaveFileDialog', async (filterPattern, defaultFileName, savedContent) => {
const saver = await import('file-saver') const saver = await import('file-saver')

View File

@ -32,6 +32,8 @@ export function GetAbsPath(arg1:string):Promise<string>;
export function GetPlatform():Promise<string>; export function GetPlatform():Promise<string>;
export function GetProxyPort():Promise<number>;
export function GetPyError():Promise<string>; export function GetPyError():Promise<string>;
export function InstallPyDep(arg1:string,arg2:boolean):Promise<string>; export function InstallPyDep(arg1:string,arg2:boolean):Promise<string>;

View File

@ -62,6 +62,10 @@ export function GetPlatform() {
return window['go']['backend_golang']['App']['GetPlatform'](); return window['go']['backend_golang']['App']['GetPlatform']();
} }
export function GetProxyPort() {
return window['go']['backend_golang']['App']['GetProxyPort']();
}
export function GetPyError() { export function GetPyError() {
return window['go']['backend_golang']['App']['GetPyError'](); return window['go']['backend_golang']['App']['GetPyError']();
} }