Skip to content

Commit

Permalink
expose invoke-go-api to renderer process
Browse files Browse the repository at this point in the history
  • Loading branch information
jyyi1 committed Nov 14, 2024
1 parent 1b40ee1 commit ba4201f
Show file tree
Hide file tree
Showing 5 changed files with 30 additions and 21 deletions.
11 changes: 0 additions & 11 deletions client/electron/go_helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,6 @@
*/

import {pathToEmbeddedTun2socksBinary} from './app_paths';
import {invokeGoApi} from './go_plugin';
import {ChildProcessHelper} from './process';
import {TransportConfigJson} from '../src/www/app/outline_server_repository/vpn';

Expand Down Expand Up @@ -58,13 +57,3 @@ export async function checkUDPConnectivity(
}
return true;
}

/**
* Fetches a resource from the given URL.
*
* @param url The URL of the resource to fetch.
* @returns A Promise that resolves to the fetched content as a string.
*/
export function fetchResource(url: string): Promise<string> {
return invokeGoApi('FetchResource', url);
}
4 changes: 3 additions & 1 deletion client/electron/go_plugin.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ import {pathToBackendLibrary} from './app_paths';

let invokeGoAPIFunc: Function | undefined;

export type GoApiName = 'FetchResource';

/**
* Calls a Go function by invoking the `InvokeGoAPI` function in the native backend library.
*
Expand All @@ -33,7 +35,7 @@ let invokeGoAPIFunc: Function | undefined;
* in `./client/go/outline/electron/go_plugin.go`.
*/
export async function invokeGoApi(
api: 'FetchResource',
api: GoApiName,
input: string
): Promise<string> {
if (!invokeGoAPIFunc) {
Expand Down
17 changes: 13 additions & 4 deletions client/electron/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import {
import {autoUpdater} from 'electron-updater';

import {lookupIp} from './connectivity';
import {fetchResource} from './go_helpers';
import {GoApiName, invokeGoApi} from './go_plugin';
import {GoVpnTunnel} from './go_vpn_tunnel';
import {installRoutingServices, RoutingDaemon} from './routing_service';
import {TunnelStore} from './tunnel_store';
Expand Down Expand Up @@ -501,10 +501,19 @@ function main() {
mainWindow?.webContents.send('outline-ipc-push-clipboard');
});

// Fetches a resource (usually the dynamic key config) from a remote URL.
// This IPC handler allows the renderer process to call Go API functions exposed by the backend.
// It takes two arguments:
// - api: The name of the Go API function to call.
// - input: A string representing the input data to the Go function.
//
// The handler returns the output string from the Go function if successful.
// Both the input string and output string need to be interpreted by the renderer process according
// to the specific API being called.
// If Go function encounters an error, it throws an Error that can be parsed by the `PlatformError`.
ipcMain.handle(
'outline-ipc-fetch-resource',
(_, url: string): Promise<string> => fetchResource(url)
'outline-ipc-invoke-go-api',
(_, api: GoApiName, input: string): Promise<string> =>
invokeGoApi(api, input)
);

// Connects to a proxy server specified by a config.
Expand Down
13 changes: 9 additions & 4 deletions client/go/outline/electron/go_plugin.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ package main
// InvokeGoAPIResult is a struct used to pass result from Go to TypeScript boundary.
typedef struct InvokeGoAPIResult_t
{
// A string representing the result of the Go function call.
// A string representing the result of the Go function call.
// This may be a raw string or a JSON string depending on the API call.
const char *Output;
Expand Down Expand Up @@ -50,7 +50,7 @@ const (
FetchResourceAPI = "FetchResource"
)

// InvokeGoFunc is the unified entry point for TypeScript to invoke various Go functions.
// InvokeGoAPI is the unified entry point for TypeScript to invoke various Go functions.
//
// The input and output are all defined as string, but they may represent either a raw string,
// or a JSON string depending on the API call.
Expand Down Expand Up @@ -81,6 +81,9 @@ func InvokeGoAPI(api *C.char, input *C.char) C.InvokeGoAPIResult {
// newCGoString allocates memory for a C string based on the given Go string.
// It should be paired with [FreeCGoString] to avoid memory leaks.
func newCGoString(s string) *C.char {
if s == "" {
return nil
}
res := C.CString(s)
slog.Debug("malloc CGoString", "addr", res)
return res
Expand All @@ -91,8 +94,10 @@ func newCGoString(s string) *C.char {
//
//export FreeCGoString
func FreeCGoString(s *C.char) {
slog.Debug("free CGoString", "addr", s)
C.free(unsafe.Pointer(s))
if s != nil {
slog.Debug("free CGoString", "addr", s)
C.free(unsafe.Pointer(s))
}
}

// marshalCGoErrorJson marshals a PlatformError to a C style JSON string.
Expand Down
6 changes: 5 additions & 1 deletion client/src/www/app/resource_fetcher.electron.ts
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,11 @@ import {PlatformError} from '../model/platform_error';
export class ElectronResourceFetcher implements ResourceFetcher {
async fetch(url: string): Promise<string> {
try {
return await window.electron.methodChannel.invoke('fetch-resource', url);
return await window.electron.methodChannel.invoke(
'invoke-go-api',
'FetchResource',
url
);
} catch (e) {
throw PlatformError.parseFrom(e);
}
Expand Down

0 comments on commit ba4201f

Please sign in to comment.