Zip server
上传zip文件,解压出静态目录
zip 出现中文乱码使用
unzip -O GBK xx.zip
main.go
package main
import (
"archive/zip"
"errors"
"fmt"
"io"
"io/ioutil"
"log"
"os"
"path/filepath"
"regexp"
"strings"
"unicode/utf8"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/logger"
"golang.org/x/text/encoding/simplifiedchinese"
)
var index = `
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>Document</title>
</head>
<body>
<form method="post" action="/upload" enctype="multipart/form-data" accept-charset="utf-8">
<input name="document" type="file" accept=".zip," required />
<button type="submit">upload</button>
</form>
<fieldset>
<legend>Index</legend>
<ul>%s</ul>
</fieldset>
</body>
</html>
`
func makeSureFolder(path string) {
if _, err := os.Stat(path); errors.Is(err, os.ErrNotExist) {
err := os.Mkdir(path, os.ModePerm)
if err != nil {
log.Fatal(err)
}
}
}
// https://golang.cafe/blog/golang-unzip-file-example.html
func unZip(dst, src string) (err error) {
archive, err := zip.OpenReader(src)
if err != nil {
return err
}
defer archive.Close()
for _, f := range archive.File {
fmt.Println(utf8.Valid([]byte(f.Name)))
fname := f.Name
// 转GBK
if utf8.Valid([]byte(fname)) != true {
fname, _ = simplifiedchinese.GBK.NewDecoder().String(f.Name)
//fname, _, _ := transform.String(simplifiedchinese.GBK.NewDecoder(), f.Name)
}
filePath := filepath.Join(dst, fname)
fmt.Println("unzipping file ", filePath)
if !strings.HasPrefix(filePath, filepath.Clean(dst)+string(os.PathSeparator)) {
fmt.Println("invalid file path")
return
}
if f.FileInfo().IsDir() {
fmt.Println("creating directory...")
os.MkdirAll(filePath, os.ModePerm)
continue
}
if err := os.MkdirAll(filepath.Dir(filePath), os.ModePerm); err != nil {
return err
}
dstFile, err := os.OpenFile(filePath, os.O_WRONLY|os.O_CREATE|os.O_TRUNC, f.Mode())
if err != nil {
return err
}
fileInArchive, err := f.Open()
if err != nil {
return err
}
if _, err := io.Copy(dstFile, fileInArchive); err != nil {
return err
}
dstFile.Close()
fileInArchive.Close()
}
return nil
}
func main() {
makeSureFolder("public")
app := fiber.New(fiber.Config{
BodyLimit: 10 * 1024 * 1024,
})
app.Use(logger.New())
app.Static("/", "./public")
app.Get("/", func(c *fiber.Ctx) error {
c.Set(fiber.HeaderContentType, fiber.MIMETextHTMLCharsetUTF8)
var fileitem string
files, err := ioutil.ReadDir("./public")
if err != nil {
log.Fatal(err)
}
for _, f := range files {
fileitem += fmt.Sprintf("<li><a href='/%s/'>%s</a></li>", f.Name(), f.Name())
}
return c.SendString(fmt.Sprintf(index, fileitem))
})
// Routes
app.Post("/upload", func(c *fiber.Ctx) error {
// Get first file from form field "document":
file, err := c.FormFile("document")
if err != nil {
return err
}
filename := fmt.Sprintf("./public/%s", file.Filename)
ext := filepath.Ext(filename)
matched, err := regexp.Match("^.zip$", []byte(ext))
if err != nil {
return err
}
if matched == false {
return errors.New("only support .zip file.")
}
// Save file to root directory:
err = c.SaveFile(file, filename)
if err != nil {
return err
}
err = unZip("./public", filename)
if err != nil {
return err
}
return c.Redirect("/")
})
// Start server
log.Fatal(app.Listen(":8989"))
}