access server directory by phone
open static folder -> press file name -> press download icon
file starts downloading to phone browser, progress is shown
download complete, file is saved in phone download folder
//main.gopackage main
import (
"encoding/json"
"fmt"
"io"
"log"
"net/http"
"os"
"path"
"path/filepath"
"runtime"
"sort"
"strconv"
"strings"
"github.com/gorilla/mux"
)
type fileStruct struct {
Name string
IsDir bool
Size int64
}
var projectPath = rootDir() + "\\golang12\\"
func indexGetHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("index get")
dir := viewDirectory(projectPath)
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)
json.NewEncoder(w).Encode(dir)
}
func indexPostHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("index post")
w.Header().Set("Content-Type", "application/json")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)
r.ParseForm()
path := r.PostForm.Get("dir")
dir := viewDirectory(path)
json.NewEncoder(w).Encode(dir)
}
func downloadPostHandler(w http.ResponseWriter, r *http.Request) {
fmt.Println("download post")
w.Header().Set("Content-Type", "application/octet-stream")
w.Header().Set("Access-Control-Allow-Origin", "*")
w.WriteHeader(http.StatusCreated)
r.ParseForm()
dir := r.PostForm.Get("dir")
dirSlash := strings.Replace(dir, "\\", "/", -1)
_, filename := path.Split(dirSlash)
fmt.Println(dir,)
w.Header().Set("Content-Disposition", "attachment; filename="+strconv.Quote(filename))
file, err := os.Open(dir)
if err != nil {
log.Fatal(err)
}
defer file.Close()
fi, err := file.Stat()
if err != nil {
log.Fatal(err)
}
w.Header().Set("Content-Length", strconv.FormatInt(fi.Size(), 10))
io.Copy(w, file)
}
func rootDir() string {
_, b, _, _ := runtime.Caller(0)
d := path.Join(path.Dir(b))
return filepath.Dir(d)
}
func viewDirectory(dirname string) []fileStruct {
f, err := os.Open(dirname)
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}
files, err := f.Readdir(-1)
f.Close()
if err != nil {
//log.Fatal(err)
return []fileStruct{}
}
var dir = []fileStruct{}
for _, file := range files {
name := dirname + file.Name()
var size int64 = 10000000
if !file.IsDir() {
size = file.Size()
}
dir = append(dir, fileStruct{
Name: name,
IsDir: file.IsDir(),
Size: size,
})
}
sort.SliceStable(dir, func(i, j int) bool {
return dir[i].Name < dir[j].Name
})
return dir
}
func main() {
r := mux.NewRouter()
r.HandleFunc("/", indexGetHandler).Methods("GET")
r.HandleFunc("/", indexPostHandler).Methods("POST", "OPTIONS")
r.HandleFunc("/download/", downloadPostHandler).Methods("POST", "OPTIONS")
fs := http.FileServer(http.Dir("./static/"))
r.PathPrefix("/static/").Handler(http.StripPrefix("/static/", fs))
http.Handle("/", r)
http.ListenAndServe(":8000", nil)
}
-----------------------------------
//folderDisplay.js
import React, { useState } from 'react';
import { folder, folderOpenOutline, documentOutline, cloudUploadOutline, cloudDownloadOutline } from 'ionicons/icons';
import { IonIcon } from '@ionic/react';
import axios from 'axios'
import '../pages/Home.css'
import saveAs from 'file-saver';
const qs = require('querystring')
export default function FolderDisplay(props) {
const [open, setOpen] = useState(false)
const [subDir, setSubDir] = useState([])
const [showLoad, setShowLoad] = useState(false)
const [downlaodProgress, setDownloadProgress] = useState(0)
function post_dir(d) {
axios({
method: 'post',
url: 'http://192.168.0.18:8000/',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: qs.stringify({ dir: d })
})
.then(response => {
setSubDir(response.data)
})
.catch(function (error) {
alert(error);
});
}
function download_dir(d, name) {
axios({
method: 'post',
url: 'http://192.168.0.18:8000/download/',
headers: {
'Content-Type': 'application/x-www-form-urlencoded'
},
data: qs.stringify({ dir: d }),
responseType: 'blob', // important
onDownloadProgress: progressEvent => {
const p = parseInt(progressEvent.loaded / props.size * 100);
setDownloadProgress(p)
},
})
.then(response => {
console.log(response)
saveAs(response.data, name);
})
.catch(function (error) {
alert(error);
});
}
function clickEvent() {
setShowLoad(!showLoad)
if (!props.isDir) { return }
if (!open) {
post_dir(props.dir)
}
setOpen(!open)
}
function downloadEvent() {
download_dir(props.dir, props.name)
}
const folder_icon = open ? <IonIcon icon={folderOpenOutline} /> : <IonIcon icon={folder} />
const sub_folder_list = subDir.map((item, index) => {
const dir_split = item.Name.split("\\")
const folder_name = dir_split[dir_split.length - 1].replace(props.name, '')
const dir_name = item.Name.replace(folder_name, '') + '\\' + folder_name
return <li>
<FolderDisplay name={folder_name} dir={dir_name} isDir={item.IsDir} size={item.Size} />
</li>
})
return (
<li >
<span onClick={() => clickEvent()}>
{props.isDir ? folder_icon : <IonIcon icon={documentOutline} />}{' '}
{props.name}{' '}
{showLoad && props.isDir ? <IonIcon icon={cloudUploadOutline} /> : null}{' '}
{showLoad && !props.isDir ? <IonIcon icon={cloudDownloadOutline} onClick={() => downloadEvent()} /> : null}{' '}
{downlaodProgress != 0 ? downlaodProgress + '%' : null}
</span>
{open ? <ul class="no-bullets">
{sub_folder_list}
</ul> : null}
</li>
);
};
reference:
go serve file
go file transfer
axios file-save
No comments:
Post a Comment