package core import ( "encoding/json" "fmt" "net/http" "net/rpc/jsonrpc" "os" "path/filepath" "strings" "time" ) // 压缩文件 type ZipBlock struct { Basepath string // 基础路径 Curpath string // 当前路径 SelFile []string // 选中的文件 RemoteAddr string // 远程主机地址,带端口 RemotePath string // 远程主机的存储路径 } // 返回的结果结构 type FsResp struct { Status int `json:"status"` Message string `json:"message"` Data map[string]interface{} `json:"data"` } // 远程调用压缩包 func SendZip(w http.ResponseWriter, r *http.Request) { r.ParseForm() // 文件 zipfarr := r.Form["sfiles"] // zipfarr 切割成数组 zipfarr = strings.Split(zipfarr[0], ",") // 选中的路径,可以为空 wtculpath := r.Form["curpath"] // 服务器ip地址 serip := r.Form["serverip"] if serip[0] == "" { http.Error(w, "remote server ip is blank!", http.StatusInternalServerError) return } // 获取远程服务器信息 remoteaddr := r.Form["remoteaddr"] if remoteaddr[0] == "" { http.Error(w, "remote server addr is blank!", http.StatusInternalServerError) return } // 远程的路径信息 remotepath := r.Form["remotepath"] if remotepath[0] == "" { http.Error(w, "remote server path is blank!", http.StatusInternalServerError) return } // 构建 zipblock := ZipBlock{ Basepath: "/www/wwwroot", Curpath: wtculpath[0], SelFile: zipfarr, RemoteAddr: remoteaddr[0], RemotePath: remotepath[0], } // 记录日志 afsLog(zipblock) // 从serip 切割出ip 和端口 splitip := strings.Split(serip[0], ":") if len(splitip) != 2 { http.Error(w, "remote server ip is error!", http.StatusInternalServerError) return } srcip := splitip[0] sport := splitip[1] // service := fmt.Sprintf("%v:%v", srcip, sport) client, err := jsonrpc.Dial("tcp", service) if err != nil { // fmt.Fprintf(w, "jsonrpc dial faild %v", err) http.Error(w, "jsonrpc dial faild "+err.Error(), http.StatusInternalServerError) return } // 调用远程方法 var reply string err = client.Call("FileService.Compress", zipblock, &reply) // 执行完成后退出 defer client.Close() if err != nil { // fmt.Fprintf(w, "jsonrpc call faild %v", err) http.Error(w, "jsonrpc call faild "+err.Error(), http.StatusInternalServerError) return } // 输出内容 w.Header().Set("Content-Type", "application/json") // w.Write([]byte(reply)) // 封装json resp := FsResp{ Status: 200, Message: "success", Data: map[string]interface{}{"reply": reply}, } json.NewEncoder(w).Encode(resp) } // 自动升级的日志 func afsLog(zipblock ZipBlock) { // 目录格式 2025/10 logdir := fmt.Sprintf("%d/%02d", time.Now().Year(), time.Now().Month()) logdir = filepath.Join("logs", logdir) // 日志文件 logfile := fmt.Sprintf("%v/aufs.log", logdir) // 检查目录是否存在 if _, err := os.Stat(logdir); os.IsNotExist(err) { // 不存在就创建 os.MkdirAll(logdir, 0755) } // 检查日志文件是否存在 if _, err := os.Stat(logfile); os.IsNotExist(err) { // 不存在就创建 os.Create(logfile) } // 打开日志文件 f, err := os.OpenFile(logfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Printf("open log file faild %v", err) } defer f.Close() // 写入日志 logfmt := fmt.Sprintf("%v %v %v %v %v\n", time.Now().Format("2006-01-02 15:04:05"), zipblock.Basepath, zipblock.Curpath, zipblock.SelFile, zipblock.RemoteAddr, zipblock.RemotePath) f.WriteString(logfmt) }