mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-02-22 02:41:23 +01:00
fix stream-file urls to use new remoteuri (#1984)
This commit is contained in:
parent
1929c70e04
commit
e15d38a795
@ -87,7 +87,10 @@ export function shFrameNavHandler(event: Electron.Event<Electron.WebContentsWill
|
|||||||
}
|
}
|
||||||
if (
|
if (
|
||||||
event.frame.name == "pdfview" &&
|
event.frame.name == "pdfview" &&
|
||||||
(url.startsWith("blob:file:///") || url.startsWith(getWebServerEndpoint() + "/wave/stream-file?"))
|
(url.startsWith("blob:file:///") ||
|
||||||
|
url.startsWith(getWebServerEndpoint() + "/wave/stream-file?") ||
|
||||||
|
url.startsWith(getWebServerEndpoint() + "/wave/stream-file/") ||
|
||||||
|
url.startsWith(getWebServerEndpoint() + "/wave/stream-local-file?"))
|
||||||
) {
|
) {
|
||||||
// allowed
|
// allowed
|
||||||
return;
|
return;
|
||||||
|
@ -240,7 +240,9 @@ electron.ipcMain.on("webview-image-contextmenu", (event: electron.IpcMainEvent,
|
|||||||
});
|
});
|
||||||
|
|
||||||
electron.ipcMain.on("download", (event, payload) => {
|
electron.ipcMain.on("download", (event, payload) => {
|
||||||
const streamingUrl = getWebServerEndpoint() + "/wave/stream-file?path=" + encodeURIComponent(payload.filePath);
|
const baseName = encodeURIComponent(path.basename(payload.filePath));
|
||||||
|
const streamingUrl =
|
||||||
|
getWebServerEndpoint() + "/wave/stream-file/" + baseName + "?path=" + encodeURIComponent(payload.filePath);
|
||||||
event.sender.downloadURL(streamingUrl);
|
event.sender.downloadURL(streamingUrl);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -241,6 +241,7 @@ const BlockFrame_Header = ({
|
|||||||
icon: "link-slash",
|
icon: "link-slash",
|
||||||
title: "wsh is not installed for this connection",
|
title: "wsh is not installed for this connection",
|
||||||
};
|
};
|
||||||
|
const showNoWshButton = manageConnection && wshProblem && !util.isBlank(connName) && !connName.startsWith("aws:");
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div
|
<div
|
||||||
@ -263,9 +264,7 @@ const BlockFrame_Header = ({
|
|||||||
changeConnModalAtom={changeConnModalAtom}
|
changeConnModalAtom={changeConnModalAtom}
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
{manageConnection && wshProblem && (
|
{showNoWshButton && <IconButton decl={wshInstallButton} className="block-frame-header-iconbutton" />}
|
||||||
<IconButton decl={wshInstallButton} className="block-frame-header-iconbutton" />
|
|
||||||
)}
|
|
||||||
<div className="block-frame-textelems-wrapper">{headerTextElems}</div>
|
<div className="block-frame-textelems-wrapper">{headerTextElems}</div>
|
||||||
<div className="block-frame-end-icons">{endIconsElem}</div>
|
<div className="block-frame-end-icons">{endIconsElem}</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
import { RpcApi } from "@/app/store/wshclientapi";
|
import { RpcApi } from "@/app/store/wshclientapi";
|
||||||
import { TabRpcClient } from "@/app/store/wshrpcutil";
|
import { TabRpcClient } from "@/app/store/wshrpcutil";
|
||||||
import { getWebServerEndpoint } from "@/util/endpoints";
|
import { getWebServerEndpoint } from "@/util/endpoints";
|
||||||
import { isBlank, makeConnRoute } from "@/util/util";
|
import { formatRemoteUri } from "@/util/waveutil";
|
||||||
import parseSrcSet from "parse-srcset";
|
import parseSrcSet from "parse-srcset";
|
||||||
|
|
||||||
export type MarkdownContentBlockType = {
|
export type MarkdownContentBlockType = {
|
||||||
@ -158,19 +158,13 @@ export const resolveRemoteFile = async (filepath: string, resolveOpts: MarkdownR
|
|||||||
if (!filepath || filepath.startsWith("http://") || filepath.startsWith("https://")) {
|
if (!filepath || filepath.startsWith("http://") || filepath.startsWith("https://")) {
|
||||||
return filepath;
|
return filepath;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const route = makeConnRoute(resolveOpts.connName);
|
const baseDirUri = formatRemoteUri(resolveOpts.baseDir, resolveOpts.connName);
|
||||||
const fileInfo = await RpcApi.RemoteFileJoinCommand(TabRpcClient, [resolveOpts.baseDir, filepath], {
|
const fileInfo = await RpcApi.FileJoinCommand(TabRpcClient, [baseDirUri, filepath]);
|
||||||
route: route,
|
const remoteUri = formatRemoteUri(fileInfo.path, resolveOpts.connName);
|
||||||
});
|
console.log("markdown resolve", resolveOpts, filepath, "=>", baseDirUri, remoteUri);
|
||||||
|
|
||||||
const usp = new URLSearchParams();
|
const usp = new URLSearchParams();
|
||||||
usp.set("path", fileInfo.path);
|
usp.set("path", remoteUri);
|
||||||
if (!isBlank(resolveOpts.connName)) {
|
|
||||||
usp.set("connection", resolveOpts.connName);
|
|
||||||
}
|
|
||||||
|
|
||||||
return getWebServerEndpoint() + "/wave/stream-file?" + usp.toString();
|
return getWebServerEndpoint() + "/wave/stream-file?" + usp.toString();
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
console.warn("Failed to resolve remote file:", filepath, err);
|
console.warn("Failed to resolve remote file:", filepath, err);
|
||||||
|
@ -348,6 +348,7 @@ const ChangeConnectionBlockModal = React.memo(
|
|||||||
const connStatusMap = new Map<string, ConnStatus>();
|
const connStatusMap = new Map<string, ConnStatus>();
|
||||||
const fullConfig = jotai.useAtomValue(atoms.fullConfigAtom);
|
const fullConfig = jotai.useAtomValue(atoms.fullConfigAtom);
|
||||||
let filterOutNowsh = util.useAtomValueSafe(viewModel.filterOutNowsh) ?? true;
|
let filterOutNowsh = util.useAtomValueSafe(viewModel.filterOutNowsh) ?? true;
|
||||||
|
const showS3 = util.useAtomValueSafe(viewModel.showS3) ?? false;
|
||||||
|
|
||||||
let maxActiveConnNum = 1;
|
let maxActiveConnNum = 1;
|
||||||
for (const conn of allConnStatus) {
|
for (const conn of allConnStatus) {
|
||||||
@ -436,14 +437,17 @@ const ChangeConnectionBlockModal = React.memo(
|
|||||||
fullConfig,
|
fullConfig,
|
||||||
filterOutNowsh
|
filterOutNowsh
|
||||||
);
|
);
|
||||||
const s3Suggestions = getS3Suggestions(
|
let s3Suggestions: SuggestionConnectionScope = null;
|
||||||
s3List,
|
if (showS3) {
|
||||||
connection,
|
s3Suggestions = getS3Suggestions(
|
||||||
connSelected,
|
s3List,
|
||||||
connStatusMap,
|
connection,
|
||||||
fullConfig,
|
connSelected,
|
||||||
filterOutNowsh
|
connStatusMap,
|
||||||
);
|
fullConfig,
|
||||||
|
filterOutNowsh
|
||||||
|
);
|
||||||
|
}
|
||||||
const connectionsEditItem = getConnectionsEditItem(changeConnModalAtom, connSelected);
|
const connectionsEditItem = getConnectionsEditItem(changeConnModalAtom, connSelected);
|
||||||
const disconnectItem = getDisconnectItem(connection, connStatusMap);
|
const disconnectItem = getDisconnectItem(connection, connStatusMap);
|
||||||
const newConnectionSuggestionItem = getNewConnectionSuggestionItem(
|
const newConnectionSuggestionItem = getNewConnectionSuggestionItem(
|
||||||
|
@ -9,9 +9,10 @@ import { ContextMenuModel } from "@/app/store/contextmenu";
|
|||||||
import { PLATFORM, atoms, createBlock, getApi, globalStore } from "@/app/store/global";
|
import { PLATFORM, atoms, createBlock, getApi, globalStore } from "@/app/store/global";
|
||||||
import { RpcApi } from "@/app/store/wshclientapi";
|
import { RpcApi } from "@/app/store/wshclientapi";
|
||||||
import { TabRpcClient } from "@/app/store/wshrpcutil";
|
import { TabRpcClient } from "@/app/store/wshrpcutil";
|
||||||
import { formatRemoteUri, type PreviewModel } from "@/app/view/preview/preview";
|
import { type PreviewModel } from "@/app/view/preview/preview";
|
||||||
import { checkKeyPressed, isCharacterKeyEvent } from "@/util/keyutil";
|
import { checkKeyPressed, isCharacterKeyEvent } from "@/util/keyutil";
|
||||||
import { fireAndForget, isBlank, makeNativeLabel } from "@/util/util";
|
import { fireAndForget, isBlank, makeNativeLabel } from "@/util/util";
|
||||||
|
import { formatRemoteUri } from "@/util/waveutil";
|
||||||
import { offset, useDismiss, useFloating, useInteractions } from "@floating-ui/react";
|
import { offset, useDismiss, useFloating, useInteractions } from "@floating-ui/react";
|
||||||
import {
|
import {
|
||||||
Column,
|
Column,
|
||||||
@ -575,7 +576,8 @@ function TableBody({
|
|||||||
{
|
{
|
||||||
label: "Download File",
|
label: "Download File",
|
||||||
click: () => {
|
click: () => {
|
||||||
getApi().downloadFile(normPath);
|
const remoteUri = formatRemoteUri(finfo.path, conn);
|
||||||
|
getApi().downloadFile(remoteUri);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
@ -38,6 +38,7 @@ import {
|
|||||||
makeNativeLabel,
|
makeNativeLabel,
|
||||||
stringToBase64,
|
stringToBase64,
|
||||||
} from "@/util/util";
|
} from "@/util/util";
|
||||||
|
import { formatRemoteUri } from "@/util/waveutil";
|
||||||
import { Monaco } from "@monaco-editor/react";
|
import { Monaco } from "@monaco-editor/react";
|
||||||
import clsx from "clsx";
|
import clsx from "clsx";
|
||||||
import { Atom, atom, Getter, PrimitiveAtom, useAtom, useAtomValue, useSetAtom, WritableAtom } from "jotai";
|
import { Atom, atom, Getter, PrimitiveAtom, useAtom, useAtomValue, useSetAtom, WritableAtom } from "jotai";
|
||||||
@ -180,6 +181,8 @@ export class PreviewModel implements ViewModel {
|
|||||||
directoryKeyDownHandler: (waveEvent: WaveKeyboardEvent) => boolean;
|
directoryKeyDownHandler: (waveEvent: WaveKeyboardEvent) => boolean;
|
||||||
codeEditKeyDownHandler: (waveEvent: WaveKeyboardEvent) => boolean;
|
codeEditKeyDownHandler: (waveEvent: WaveKeyboardEvent) => boolean;
|
||||||
|
|
||||||
|
showS3 = atom(true);
|
||||||
|
|
||||||
constructor(blockId: string, nodeModel: BlockNodeModel) {
|
constructor(blockId: string, nodeModel: BlockNodeModel) {
|
||||||
this.viewType = "preview";
|
this.viewType = "preview";
|
||||||
this.blockId = blockId;
|
this.blockId = blockId;
|
||||||
@ -936,13 +939,14 @@ function StreamingPreview({ model }: SpecializedViewProps) {
|
|||||||
const conn = useAtomValue(model.connection);
|
const conn = useAtomValue(model.connection);
|
||||||
const fileInfo = useAtomValue(model.statFile);
|
const fileInfo = useAtomValue(model.statFile);
|
||||||
const filePath = fileInfo.path;
|
const filePath = fileInfo.path;
|
||||||
|
const remotePath = formatRemoteUri(filePath, conn);
|
||||||
const usp = new URLSearchParams();
|
const usp = new URLSearchParams();
|
||||||
usp.set("path", filePath);
|
usp.set("path", remotePath);
|
||||||
if (conn != null) {
|
if (conn != null) {
|
||||||
usp.set("connection", conn);
|
usp.set("connection", conn);
|
||||||
}
|
}
|
||||||
const streamingUrl = getWebServerEndpoint() + "/wave/stream-file?" + usp.toString();
|
const streamingUrl = `${getWebServerEndpoint()}/wave/stream-file?${usp.toString()}`;
|
||||||
if (fileInfo.mimetype == "application/pdf") {
|
if (fileInfo.mimetype === "application/pdf") {
|
||||||
return (
|
return (
|
||||||
<div className="view-preview view-preview-pdf">
|
<div className="view-preview view-preview-pdf">
|
||||||
<iframe src={streamingUrl} width="100%" height="100%" name="pdfview" />
|
<iframe src={streamingUrl} width="100%" height="100%" name="pdfview" />
|
||||||
@ -1304,16 +1308,4 @@ const ErrorOverlay = memo(({ errorMsg, resetOverlay }: { errorMsg: ErrorMsg; res
|
|||||||
);
|
);
|
||||||
});
|
});
|
||||||
|
|
||||||
function formatRemoteUri(path: string, connection: string): string {
|
export { PreviewView };
|
||||||
connection = connection ?? "local";
|
|
||||||
// TODO: We need a better way to handle s3 paths
|
|
||||||
let retVal: string;
|
|
||||||
if (connection.startsWith("aws:")) {
|
|
||||||
retVal = `${connection}:s3://${path ?? ""}`;
|
|
||||||
} else {
|
|
||||||
retVal = `wsh://${connection}/${path}`;
|
|
||||||
}
|
|
||||||
return retVal;
|
|
||||||
}
|
|
||||||
|
|
||||||
export { formatRemoteUri, PreviewView };
|
|
||||||
|
@ -119,7 +119,8 @@ function TermSticker({ sticker, config }: { sticker: StickerType; config: Sticke
|
|||||||
if (sticker.imgsrc == null) {
|
if (sticker.imgsrc == null) {
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const streamingUrl = getWebServerEndpoint() + "/wave/stream-file?path=" + encodeURIComponent(sticker.imgsrc);
|
const streamingUrl =
|
||||||
|
getWebServerEndpoint() + "/wave/stream-local-file?path=" + encodeURIComponent(sticker.imgsrc);
|
||||||
return (
|
return (
|
||||||
<div className="term-sticker term-sticker-image" style={style} onClick={clickHandler}>
|
<div className="term-sticker term-sticker-image" style={style} onClick={clickHandler}>
|
||||||
<img src={streamingUrl} />
|
<img src={streamingUrl} />
|
||||||
|
3
frontend/types/custom.d.ts
vendored
3
frontend/types/custom.d.ts
vendored
@ -292,6 +292,9 @@ declare global {
|
|||||||
// If true, filters out 'nowsh' connections (when managing connections)
|
// If true, filters out 'nowsh' connections (when managing connections)
|
||||||
filterOutNowsh?: jotai.Atom<boolean>;
|
filterOutNowsh?: jotai.Atom<boolean>;
|
||||||
|
|
||||||
|
// if true, show s3 connections in picker
|
||||||
|
showS3?: jotai.Atom<boolean>;
|
||||||
|
|
||||||
// If true, removes padding inside the block content area.
|
// If true, removes padding inside the block content area.
|
||||||
noPadding?: jotai.Atom<boolean>;
|
noPadding?: jotai.Atom<boolean>;
|
||||||
|
|
||||||
|
@ -7,7 +7,9 @@ import { generate as generateCSS, parse as parseCSS, walk as walkCSS } from "css
|
|||||||
|
|
||||||
function encodeFileURL(file: string) {
|
function encodeFileURL(file: string) {
|
||||||
const webEndpoint = getWebServerEndpoint();
|
const webEndpoint = getWebServerEndpoint();
|
||||||
return webEndpoint + `/wave/stream-file?path=${encodeURIComponent(file)}&no404=1`;
|
const fileUri = formatRemoteUri(file, "local");
|
||||||
|
const rtn = webEndpoint + `/wave/stream-file?path=${encodeURIComponent(fileUri)}&no404=1`;
|
||||||
|
return rtn;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function processBackgroundUrls(cssText: string): string {
|
export function processBackgroundUrls(cssText: string): string {
|
||||||
@ -86,3 +88,15 @@ export function computeBgStyleFromMeta(meta: MetaType, defaultOpacity: number =
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function formatRemoteUri(path: string, connection: string): string {
|
||||||
|
connection = connection ?? "local";
|
||||||
|
// TODO: We need a better way to handle s3 paths
|
||||||
|
let retVal: string;
|
||||||
|
if (connection.startsWith("aws:")) {
|
||||||
|
retVal = `${connection}:s3://${path ?? ""}`;
|
||||||
|
} else {
|
||||||
|
retVal = `wsh://${connection}/${path}`;
|
||||||
|
}
|
||||||
|
return retVal;
|
||||||
|
}
|
||||||
|
@ -774,20 +774,13 @@ func (c S3Client) Delete(ctx context.Context, conn *connparse.Connection, recurs
|
|||||||
|
|
||||||
func (c S3Client) Join(ctx context.Context, conn *connparse.Connection, parts ...string) (*wshrpc.FileInfo, error) {
|
func (c S3Client) Join(ctx context.Context, conn *connparse.Connection, parts ...string) (*wshrpc.FileInfo, error) {
|
||||||
var joinParts []string
|
var joinParts []string
|
||||||
if conn.Host == "" || conn.Host == fspath.Separator {
|
if conn.Path == "" || conn.Path == fspath.Separator {
|
||||||
if conn.Path == "" || conn.Path == fspath.Separator {
|
joinParts = parts
|
||||||
joinParts = parts
|
|
||||||
} else {
|
|
||||||
joinParts = append([]string{conn.Path}, parts...)
|
|
||||||
}
|
|
||||||
} else if conn.Path == "" || conn.Path == "/" {
|
|
||||||
joinParts = append([]string{conn.Host}, parts...)
|
|
||||||
} else {
|
} else {
|
||||||
joinParts = append([]string{conn.Host, conn.Path}, parts...)
|
joinParts = append([]string{conn.Path}, parts...)
|
||||||
}
|
}
|
||||||
|
|
||||||
conn.Path = fspath.Join(joinParts...)
|
conn.Path = fspath.Join(joinParts...)
|
||||||
|
|
||||||
return c.Stat(ctx, conn)
|
return c.Stat(ctx, conn)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -25,6 +25,7 @@ import (
|
|||||||
"github.com/wavetermdev/waveterm/pkg/docsite"
|
"github.com/wavetermdev/waveterm/pkg/docsite"
|
||||||
"github.com/wavetermdev/waveterm/pkg/filestore"
|
"github.com/wavetermdev/waveterm/pkg/filestore"
|
||||||
"github.com/wavetermdev/waveterm/pkg/panichandler"
|
"github.com/wavetermdev/waveterm/pkg/panichandler"
|
||||||
|
"github.com/wavetermdev/waveterm/pkg/remote/fileshare"
|
||||||
"github.com/wavetermdev/waveterm/pkg/schema"
|
"github.com/wavetermdev/waveterm/pkg/schema"
|
||||||
"github.com/wavetermdev/waveterm/pkg/service"
|
"github.com/wavetermdev/waveterm/pkg/service"
|
||||||
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
|
"github.com/wavetermdev/waveterm/pkg/util/utilfn"
|
||||||
@ -251,6 +252,10 @@ func handleRemoteStreamFile(w http.ResponseWriter, req *http.Request, conn strin
|
|||||||
route := wshutil.MakeConnectionRouteId(conn)
|
route := wshutil.MakeConnectionRouteId(conn)
|
||||||
rpcOpts := &wshrpc.RpcOpts{Route: route, Timeout: 60 * 1000}
|
rpcOpts := &wshrpc.RpcOpts{Route: route, Timeout: 60 * 1000}
|
||||||
rtnCh := wshclient.RemoteStreamFileCommand(client, streamFileData, rpcOpts)
|
rtnCh := wshclient.RemoteStreamFileCommand(client, streamFileData, rpcOpts)
|
||||||
|
return handleRemoteStreamFileFromCh(w, req, path, rtnCh, rpcOpts.StreamCancelFn, no404)
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRemoteStreamFileFromCh(w http.ResponseWriter, req *http.Request, path string, rtnCh <-chan wshrpc.RespOrErrorUnion[wshrpc.FileData], streamCancelFn func(), no404 bool) error {
|
||||||
firstPk := true
|
firstPk := true
|
||||||
var fileInfo *wshrpc.FileInfo
|
var fileInfo *wshrpc.FileInfo
|
||||||
loopDone := false
|
loopDone := false
|
||||||
@ -265,7 +270,9 @@ func handleRemoteStreamFile(w http.ResponseWriter, req *http.Request, conn strin
|
|||||||
for {
|
for {
|
||||||
select {
|
select {
|
||||||
case <-ctx.Done():
|
case <-ctx.Done():
|
||||||
rpcOpts.StreamCancelFn()
|
if streamCancelFn != nil {
|
||||||
|
streamCancelFn()
|
||||||
|
}
|
||||||
return ctx.Err()
|
return ctx.Err()
|
||||||
case respUnion, ok := <-rtnCh:
|
case respUnion, ok := <-rtnCh:
|
||||||
if !ok {
|
if !ok {
|
||||||
@ -311,6 +318,16 @@ func handleRemoteStreamFile(w http.ResponseWriter, req *http.Request, conn strin
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func handleStreamLocalFile(w http.ResponseWriter, r *http.Request) {
|
||||||
|
path := r.URL.Query().Get("path")
|
||||||
|
if path == "" {
|
||||||
|
http.Error(w, "path is required", http.StatusBadRequest)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
no404 := r.URL.Query().Get("no404")
|
||||||
|
handleLocalStreamFile(w, r, path, no404 != "")
|
||||||
|
}
|
||||||
|
|
||||||
func handleStreamFile(w http.ResponseWriter, r *http.Request) {
|
func handleStreamFile(w http.ResponseWriter, r *http.Request) {
|
||||||
conn := r.URL.Query().Get("connection")
|
conn := r.URL.Query().Get("connection")
|
||||||
if conn == "" {
|
if conn == "" {
|
||||||
@ -322,14 +339,16 @@ func handleStreamFile(w http.ResponseWriter, r *http.Request) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
no404 := r.URL.Query().Get("no404")
|
no404 := r.URL.Query().Get("no404")
|
||||||
if conn == wshrpc.LocalConnName {
|
data := wshrpc.FileData{
|
||||||
handleLocalStreamFile(w, r, path, no404 != "")
|
Info: &wshrpc.FileInfo{
|
||||||
} else {
|
Path: path,
|
||||||
err := handleRemoteStreamFile(w, r, conn, path, no404 != "")
|
},
|
||||||
if err != nil {
|
}
|
||||||
log.Printf("error streaming remote file %q %q: %v\n", conn, path, err)
|
rtnCh := fileshare.ReadStream(r.Context(), data)
|
||||||
http.Error(w, fmt.Sprintf("error streaming file: %v", err), http.StatusInternalServerError)
|
err := handleRemoteStreamFileFromCh(w, r, path, rtnCh, nil, no404 != "")
|
||||||
}
|
if err != nil {
|
||||||
|
log.Printf("error streaming file %q %q: %v\n", conn, path, err)
|
||||||
|
http.Error(w, fmt.Sprintf("error streaming file: %v", err), http.StatusInternalServerError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -423,7 +442,9 @@ const schemaPrefix = "/schema/"
|
|||||||
// blocking
|
// blocking
|
||||||
func RunWebServer(listener net.Listener) {
|
func RunWebServer(listener net.Listener) {
|
||||||
gr := mux.NewRouter()
|
gr := mux.NewRouter()
|
||||||
|
gr.HandleFunc("/wave/stream-local-file", WebFnWrap(WebFnOpts{AllowCaching: true}, handleStreamLocalFile))
|
||||||
gr.HandleFunc("/wave/stream-file", WebFnWrap(WebFnOpts{AllowCaching: true}, handleStreamFile))
|
gr.HandleFunc("/wave/stream-file", WebFnWrap(WebFnOpts{AllowCaching: true}, handleStreamFile))
|
||||||
|
gr.PathPrefix("/wave/stream-file/").HandlerFunc(WebFnWrap(WebFnOpts{AllowCaching: true}, handleStreamFile))
|
||||||
gr.HandleFunc("/wave/file", WebFnWrap(WebFnOpts{AllowCaching: false}, handleWaveFile))
|
gr.HandleFunc("/wave/file", WebFnWrap(WebFnOpts{AllowCaching: false}, handleWaveFile))
|
||||||
gr.HandleFunc("/wave/service", WebFnWrap(WebFnOpts{JsonErrors: true}, handleService))
|
gr.HandleFunc("/wave/service", WebFnWrap(WebFnOpts{JsonErrors: true}, handleService))
|
||||||
gr.HandleFunc("/vdom/{uuid}/{path:.*}", WebFnWrap(WebFnOpts{AllowCaching: true}, handleVDom))
|
gr.HandleFunc("/vdom/{uuid}/{path:.*}", WebFnWrap(WebFnOpts{AllowCaching: true}, handleVDom))
|
||||||
|
Loading…
Reference in New Issue
Block a user