Преглед изворни кода

Completed path travel and single file download in folder sharae

TC pushbot 5 пре 4 година
родитељ
комит
72736af9a4
2 измењених фајлова са 38 додато и 13 уклоњено
  1. 35 11
      mod/share/share.go
  2. 3 2
      system/share/downloadPageFolder.html

+ 35 - 11
mod/share/share.go

@@ -246,7 +246,30 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
 			if directDownload == true {
 				if relpath != "" {
 					//User specified a specific file within the directory. Escape the relpath
-					log.Println(shareOption.FileRealPath, relpath)
+					targetFilepath := filepath.Join(shareOption.FileRealPath, relpath)
+
+					//Check if file exists
+					if !fileExists(targetFilepath) {
+						http.NotFound(w, r)
+						return
+					}
+
+					//Validate the absolute path to prevent path escape
+					absroot, _ := filepath.Abs(shareOption.FileRealPath)
+					abstarget, _ := filepath.Abs(targetFilepath)
+
+					if len(abstarget) <= len(absroot) || abstarget[:len(absroot)] != absroot {
+						//Directory escape detected
+						w.WriteHeader(http.StatusBadRequest)
+						w.Write([]byte("400 - Bad Request: Invalid relative path"))
+						return
+					}
+
+					//Serve the target file
+					w.Header().Set("Content-Disposition", "attachment; filename*=UTF-8''"+strings.ReplaceAll(url.QueryEscape(filepath.Base(targetFilepath)), "+", "%20"))
+					w.Header().Set("Content-Type", r.Header.Get("Content-Type"))
+					http.ServeFile(w, r, targetFilepath)
+
 					sendOK(w)
 				} else {
 					//Download this folder as zip
@@ -329,16 +352,17 @@ func (s *Manager) HandleShareAccess(w http.ResponseWriter, r *http.Request) {
 
 				t := fasttemplate.New(string(content), "{{", "}}")
 				s := t.ExecuteString(map[string]interface{}{
-					"hostname":    s.options.HostName,
-					"reqid":       id,
-					"mime":        "application/x-directory",
-					"size":        filesystem.GetFileDisplaySize(fsize, 2),
-					"filecount":   strconv.Itoa(fcount),
-					"modtime":     timeString,
-					"downloadurl": "/share?id=" + id + "&download=true",
-					"filename":    filepath.Base(shareOption.FileRealPath),
-					"reqtime":     strconv.Itoa(int(time.Now().Unix())),
-					"treelist":    tl,
+					"hostname":     s.options.HostName,
+					"reqid":        id,
+					"mime":         "application/x-directory",
+					"size":         filesystem.GetFileDisplaySize(fsize, 2),
+					"filecount":    strconv.Itoa(fcount),
+					"modtime":      timeString,
+					"downloadurl":  "./share?id=" + id + "&download=true",
+					"filename":     filepath.Base(shareOption.FileRealPath),
+					"reqtime":      strconv.Itoa(int(time.Now().Unix())),
+					"treelist":     tl,
+					"downloaduuid": id,
 				})
 
 				w.Write([]byte(s))

+ 3 - 2
system/share/downloadPageFolder.html

@@ -84,7 +84,7 @@
                           </tr>
                         </tbody>
                       </table>
-                    <a href="{{downloadurl}}"><button class="button-primary">Download</button></a>
+                    <a href="{{downloadurl}}"><button class="button-primary">Download All</button></a>
                     <p style="font-size: 80%;"><b>Depending on folder size, zipping might take a while to complete.</b></p>
                     <br>
                     <p>Request File ID: {{reqid}}</p>
@@ -114,6 +114,7 @@
         </div>
     <script>
       var treeFileList = {{treelist}};
+      var downloadUUID = `{{downloaduuid}}`;
       var currentViewingRoot = ".";
       var selectedFile = null;
       renderFileList(treeFileList["."]);
@@ -191,7 +192,7 @@
           
         }else{
           //File. Download it
-          
+          window.open("./share?id=" + downloadUUID + "&download=true&rel=" + targetRelPath)
         }
       }