feat: file manager on SSH hosts through a machine - open from the plus menu
This commit is contained in:
1 parent
2859e69abe
commit
7e4daeda4c
8 files changed
+202
-11
No files matched your search
@@ -315,6 +315,13 @@ func readPiece(w http.ResponseWriter, r *http.Request) ([]byte, error) {
|
||||
// file. The answer names the transfer and the piece size; the browser then
|
||||
// PUTs the pieces and asks for the result.
|
||||
func (s *Server) handleFSUploadStart(w http.ResponseWriter, r *http.Request) {
|
||||
s.uploadStart(w, r, proto.TaskFSPut, "")
|
||||
}
|
||||
|
||||
// uploadStart starts a file upload to the agent's task (fs.put on the
|
||||
// machine, sshfs.put onto an SSH host through it, conn naming the
|
||||
// connection).
|
||||
func (s *Server) uploadStart(w http.ResponseWriter, r *http.Request, task, conn string) {
|
||||
agentID, p := r.PathValue("id"), r.URL.Query().Get("path")
|
||||
if !s.fsAgent(w, agentID, true) {
|
||||
return
|
||||
@@ -329,19 +336,21 @@ func (s *Server) handleFSUploadStart(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
x := s.xfers.open(agentID, size)
|
||||
go s.runUpload(x, p)
|
||||
go s.runUpload(x, p, task, conn)
|
||||
data, _ := json.Marshal(map[string]any{"id": x.id, "chunk": xferChunk})
|
||||
writeJSON(w, proto.TaskResult{OK: true, Data: data})
|
||||
}
|
||||
|
||||
// runUpload has the agent write the file and keeps the result for the
|
||||
// browser to collect.
|
||||
func (s *Server) runUpload(x *xfer, p string) {
|
||||
func (s *Server) runUpload(x *xfer, p, task, conn string) {
|
||||
ctx, cancel := context.WithTimeout(context.Background(), xferTimeout)
|
||||
defer cancel()
|
||||
args := proto.FSXferArgs{Path: p, Xfer: x.id, Size: x.size, Chunk: xferChunk}
|
||||
res, err := s.waitTask(ctx, x.agentID, proto.TaskFSPut, args, xferTimeout)
|
||||
if err == nil && unknownOp(res) {
|
||||
args := proto.FSXferArgs{Path: p, Xfer: x.id, Size: x.size, Chunk: xferChunk, Conn: conn}
|
||||
res, err := s.waitTask(ctx, x.agentID, task, args, xferTimeout)
|
||||
if err == nil && unknownOp(res) && task != proto.TaskFSPut {
|
||||
res = proto.TaskResult{Error: "агент не умеет файлы по SSH - обновите его"}
|
||||
} else if err == nil && unknownOp(res) {
|
||||
res = s.legacyUpload(ctx, x, p)
|
||||
}
|
||||
if err != nil {
|
||||
@@ -502,6 +511,12 @@ func fileHeaders(w http.ResponseWriter, p string, inline bool) {
|
||||
// one response fed by the pieces the agent sends. inline=1 serves pictures,
|
||||
// video and sound for the page to show.
|
||||
func (s *Server) handleFSDownload(w http.ResponseWriter, r *http.Request) {
|
||||
s.download(w, r, proto.TaskFSSend, "")
|
||||
}
|
||||
|
||||
// download sends a file from the agent's task (fs.send, or sshfs.send for
|
||||
// an SSH host through it) as one response.
|
||||
func (s *Server) download(w http.ResponseWriter, r *http.Request, task, conn string) {
|
||||
agentID, p := r.PathValue("id"), r.URL.Query().Get("path")
|
||||
inline := r.URL.Query().Get("inline") != ""
|
||||
if !s.fsAgent(w, agentID, false) {
|
||||
@@ -511,8 +526,8 @@ func (s *Server) handleFSDownload(w http.ResponseWriter, r *http.Request) {
|
||||
defer s.xfers.drop(x.id)
|
||||
defer x.fail("браузер ушёл") // stops the agent if the response ends early
|
||||
|
||||
raw, _ := json.Marshal(proto.FSXferArgs{Path: p, Xfer: x.id, Size: -1, Chunk: xferChunk})
|
||||
taskID, ch := s.hub.CreateTask(agentID, proto.TaskFSSend, raw)
|
||||
raw, _ := json.Marshal(proto.FSXferArgs{Path: p, Xfer: x.id, Size: -1, Chunk: xferChunk, Conn: conn})
|
||||
taskID, ch := s.hub.CreateTask(agentID, task, raw)
|
||||
defer s.hub.DiscardTask(taskID)
|
||||
// The agent's result: an error ends the transfer wherever it stands.
|
||||
results := make(chan proto.TaskResult, 1)
|
||||
@@ -530,6 +545,10 @@ func (s *Server) handleFSDownload(w http.ResponseWriter, r *http.Request) {
|
||||
select {
|
||||
case <-x.sized:
|
||||
case res := <-results:
|
||||
if unknownOp(res) && task != proto.TaskFSSend {
|
||||
http.Error(w, "агент не умеет файлы по SSH - обновите его", http.StatusBadGateway)
|
||||
return
|
||||
}
|
||||
if unknownOp(res) {
|
||||
s.legacyDownload(w, r, agentID, p, inline)
|
||||
return
|
||||
|
||||
Reference in new issue
Block a user