mirror of
https://github.com/wavetermdev/waveterm.git
synced 2025-01-02 18:39:05 +01:00
List Config dir if directory is specified (#468)
* implemented list dir for config * added file stat and path check * addressed comments, added file not found error
This commit is contained in:
parent
b656f4ce0f
commit
0a14a58663
4
src/types/custom.d.ts
vendored
4
src/types/custom.d.ts
vendored
@ -797,12 +797,16 @@ declare global {
|
||||
};
|
||||
|
||||
type FileInfoType = {
|
||||
type: string;
|
||||
name: string;
|
||||
size: number;
|
||||
modts: number;
|
||||
isdir: boolean;
|
||||
perm: number;
|
||||
notfound: boolean;
|
||||
modestr?: string;
|
||||
path?: string;
|
||||
outputpos?: number;
|
||||
};
|
||||
|
||||
type ExtBlob = Blob & {
|
||||
|
@ -11,9 +11,11 @@ import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/fs"
|
||||
"os"
|
||||
"reflect"
|
||||
"sync"
|
||||
"time"
|
||||
|
||||
"github.com/wavetermdev/waveterm/waveshell/pkg/base"
|
||||
"github.com/wavetermdev/waveterm/waveshell/pkg/wlog"
|
||||
@ -58,6 +60,7 @@ const (
|
||||
WriteFileReadyPacketStr = "writefileready" // rpc-response
|
||||
WriteFileDonePacketStr = "writefiledone" // rpc-response
|
||||
FileDataPacketStr = "filedata"
|
||||
FileStatPacketStr = "filestat"
|
||||
LogPacketStr = "log" // logging packet (sent from waveshell back to server)
|
||||
ShellStatePacketStr = "shellstate"
|
||||
|
||||
@ -112,6 +115,7 @@ func init() {
|
||||
TypeStrToFactory[WriteFileDonePacketStr] = reflect.TypeOf(WriteFileDonePacketType{})
|
||||
TypeStrToFactory[LogPacketStr] = reflect.TypeOf(LogPacketType{})
|
||||
TypeStrToFactory[ShellStatePacketStr] = reflect.TypeOf(ShellStatePacketType{})
|
||||
TypeStrToFactory[FileStatPacketStr] = reflect.TypeOf(FileStatPacketType{})
|
||||
|
||||
var _ RpcPacketType = (*RunPacketType)(nil)
|
||||
var _ RpcPacketType = (*GetCmdPacketType)(nil)
|
||||
@ -379,6 +383,51 @@ func MakeReInitPacket() *ReInitPacketType {
|
||||
return &ReInitPacketType{Type: ReInitPacketStr}
|
||||
}
|
||||
|
||||
type FileStatPacketType struct {
|
||||
Type string `json:"type"`
|
||||
Name string `json:"name"`
|
||||
Size int64 `json:"size"`
|
||||
ModTs time.Time `json:"modts"`
|
||||
IsDir bool `json:"isdir"`
|
||||
Perm int `json:"perm"`
|
||||
ModeStr string `json:"modestr"`
|
||||
Error string `json:"error"`
|
||||
Done bool `json:"done"`
|
||||
RespId string `json:"respid"`
|
||||
Path string `json:"path"`
|
||||
}
|
||||
|
||||
func (*FileStatPacketType) GetType() string {
|
||||
return FileStatPacketStr
|
||||
}
|
||||
|
||||
func (p *FileStatPacketType) GetResponseDone() bool {
|
||||
return p.Done
|
||||
}
|
||||
|
||||
func (p *FileStatPacketType) GetResponseId() string {
|
||||
return p.RespId
|
||||
}
|
||||
|
||||
func MakeFileStatPacketType() *FileStatPacketType {
|
||||
return &FileStatPacketType{Type: FileStatPacketStr}
|
||||
}
|
||||
|
||||
func MakeFileStatPacketFromFileInfo(finfo fs.FileInfo, err string, done bool) *FileStatPacketType {
|
||||
resp := MakeFileStatPacketType()
|
||||
resp.Error = err
|
||||
resp.Done = done
|
||||
|
||||
resp.IsDir = finfo.IsDir()
|
||||
resp.Name = finfo.Name()
|
||||
|
||||
resp.Size = finfo.Size()
|
||||
resp.ModTs = finfo.ModTime()
|
||||
resp.Perm = int(finfo.Mode().Perm())
|
||||
resp.ModeStr = finfo.Mode().String()
|
||||
return resp
|
||||
}
|
||||
|
||||
type StreamFilePacketType struct {
|
||||
Type string `json:"type"`
|
||||
ReqId string `json:"reqid"`
|
||||
|
@ -677,6 +677,40 @@ func HandleRunCommand(w http.ResponseWriter, r *http.Request) {
|
||||
WriteJsonSuccess(w, update)
|
||||
}
|
||||
|
||||
func CheckIsDir(dirHandler http.Handler, fileHandler http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
configPath := r.URL.Path
|
||||
configAbsPath, err := filepath.Abs(configPath)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(fmt.Sprintf("error getting absolute path", err)))
|
||||
return
|
||||
}
|
||||
configBaseDir := path.Join(scbase.GetWaveHomeDir(), "config")
|
||||
configFullPath := path.Join(scbase.GetWaveHomeDir(), configAbsPath)
|
||||
if !strings.HasPrefix(configFullPath, configBaseDir) {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(fmt.Sprintf("error: path is not in config folder")))
|
||||
return
|
||||
}
|
||||
fstat, err := os.Stat(configFullPath)
|
||||
if errors.Is(err, fs.ErrNotExist) {
|
||||
w.WriteHeader(404)
|
||||
w.Write([]byte(fmt.Sprintf("file not found: ", configAbsPath)))
|
||||
return
|
||||
} else if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(fmt.Sprintf("file stat err", err)))
|
||||
return
|
||||
}
|
||||
if fstat.IsDir() {
|
||||
AuthKeyMiddleWare(dirHandler).ServeHTTP(w, r)
|
||||
} else {
|
||||
AuthKeyMiddleWare(fileHandler).ServeHTTP(w, r)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
func AuthKeyMiddleWare(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
reqAuthKey := r.Header.Get("X-AuthKey")
|
||||
@ -857,6 +891,39 @@ func doShutdown(reason string) {
|
||||
})
|
||||
}
|
||||
|
||||
func configDirHandler(w http.ResponseWriter, r *http.Request) {
|
||||
log.Printf("running?")
|
||||
configPath := r.URL.Path
|
||||
configFullPath := path.Join(scbase.GetWaveHomeDir(), configPath)
|
||||
dirFile, err := os.Open(configFullPath)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(fmt.Sprintf("error opening specified dir: ", err)))
|
||||
return
|
||||
}
|
||||
entries, err := dirFile.Readdir(0)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(fmt.Sprintf("error getting files: ", err)))
|
||||
return
|
||||
}
|
||||
var files []*packet.FileStatPacketType
|
||||
for index := 0; index < len(entries); index++ {
|
||||
curEntry := entries[index]
|
||||
curFile := packet.MakeFileStatPacketFromFileInfo(curEntry, "", false)
|
||||
files = append(files, curFile)
|
||||
}
|
||||
dirListJson, err := json.Marshal(files)
|
||||
if err != nil {
|
||||
w.WriteHeader(500)
|
||||
w.Write([]byte(fmt.Sprintf("json err: ", err)))
|
||||
return
|
||||
}
|
||||
w.WriteHeader(200)
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Write(dirListJson)
|
||||
}
|
||||
|
||||
func main() {
|
||||
scbase.BuildTime = BuildTime
|
||||
scbase.WaveVersion = WaveVersion
|
||||
@ -953,7 +1020,9 @@ func main() {
|
||||
gr.HandleFunc("/api/write-file", AuthKeyWrap(HandleWriteFile)).Methods("POST")
|
||||
configPath := path.Join(scbase.GetWaveHomeDir(), "config") + "/"
|
||||
log.Printf("[wave] config path: %q\n", configPath)
|
||||
gr.PathPrefix("/config/").Handler(AuthKeyMiddleWare(http.StripPrefix("/config/", http.FileServer(http.Dir(configPath)))))
|
||||
isFileHandler := http.StripPrefix("/config/", http.FileServer(http.Dir(configPath)))
|
||||
isDirHandler := http.HandlerFunc(configDirHandler)
|
||||
gr.PathPrefix("/config/").Handler(CheckIsDir(isDirHandler, isFileHandler))
|
||||
|
||||
serverAddr := MainServerAddr
|
||||
if scbase.IsDevMode() {
|
||||
|
Loading…
Reference in New Issue
Block a user