package main
import (
"crypto/sha1"
"encoding/hex"
"fmt"
"io"
"io/ioutil"
"net/http"
"os"
"strconv"
)
//加载首页的页面
func indexHandler(w http.ResponseWriter, r *http.Request) {
data, err := ioutil.ReadFile("./static/index.html")
if err != nil {
io.WriteString(w, "internel server error")
return
}
io.WriteString(w, string(data))
}
//加载首页的第二种方式(页面跳转)
func homeHandler(w http.ResponseWriter, r *http.Request) {
http.Redirect(w, r, "/static/index.html", http.StatusFound)
return
}
//接收表单参数
func userHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //解析参数,默认是不会解析的
if r.Method == "GET" { //GET请求的方法
username := r.Form.Get("username") //必须使用双引号, 注意: 这里的Get 不是指只接收GET请求的参数, 而是获取参数
password := r.Form.Get("password")
// limitCnt, _ := strconv.Atoi(r.Form.Get("limit")) //字符串转整数的接收方法
//io.WriteString(w, username+":"+password)
w.Write([]byte(username + ":" + password))
} else if r.Method == "POST" { //POST请求的方法
username := r.Form.Get("username") //必须使用双引号, 注意: POST请求, 也是用Get方法来接收
password := r.Form.Get("password")
//io.WriteString(w, username+":"+password)
w.Write([]byte(username + ":" + password))
}
}
//文件上传
func uploadHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm() //解析参数,默认是不会解析的
if r.Method == "GET" { //GET请求的方法
data, err := ioutil.ReadFile("./static/upload.html")
if err != nil {
io.WriteString(w, "internel server error")
return
}
io.WriteString(w, string(data))
} else if r.Method == "POST" { //POST请求的方法
// 接收文件流及存储到本地目录
file, head, err := r.FormFile("image") //接收文件域的方法
if err != nil {
fmt.Printf("Failed to get data, err:%s\n", err.Error())
return
}
defer file.Close()
newFile, err := os.Create("C:/tmp/" + head.Filename) //创建文件
if err != nil {
fmt.Printf("Failed to create file, err:%s\n", err.Error())
return
}
defer newFile.Close()
FileSize, err := io.Copy(newFile, file) //拷贝文件
if err != nil {
fmt.Printf("Failed to save data into file, err:%s\n", err.Error())
//http.Redirect(w, r, "/static/index.html", http.StatusFound) //重定向的方法
return
}
//文件的sha1的值
io.WriteString(w, "上传成功"+"\r\n文件的大小:"+strconv.FormatInt(FileSize, 10)+"\r\n文件的sha1:"+fileSha1(newFile)) //int64转换成string
}
}
// downloadHandler : 文件下载接口
func downloadHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
filename := r.Form.Get("filename")
f, err := os.Open("C:/tmp/" + filename)
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
defer f.Close()
data, err := ioutil.ReadAll(f) //ReadAll从r读取数据直到EOF或遇到error
if err != nil {
w.WriteHeader(http.StatusInternalServerError)
return
}
w.Header().Set("Content-Type", "application/octect-stream")
w.Header().Set("content-disposition", "attachment; filename=\""+filename+"\"")
w.Write(data)
}
//获取文件的sha1值
func fileSha1(file *os.File) string {
_sha1 := sha1.New() //返回一个新的使用SHA1校验的hash.Hash接口
io.Copy(_sha1, file) //将src的数据拷贝到dst,直到在src上到达EOF或发生错误。返回拷贝的字节数和遇到的第一个错误。
return hex.EncodeToString(_sha1.Sum(nil)) //nil 等同于 []byte("")
}
func main() {
// 静态资源处理
http.Handle("/static/",
http.StripPrefix("/static/",
http.FileServer(http.Dir("./static"))))
// 动态接口路由设置
http.HandleFunc("/index", indexHandler)
http.HandleFunc("/home", homeHandler)
http.HandleFunc("/user", userHandler)
http.HandleFunc("/upload", uploadHandler)
http.HandleFunc("/download", downloadHandler)
// 监听端口
fmt.Println("上传服务正在启动, 监听端口:8080...")
err := http.ListenAndServe(":8080", nil)
if err != nil {
fmt.Printf("Failed to start server, err:%s", err.Error())
}
}
static/upload.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<form action="/upload" method="POST" enctype="multipart/form-data">
<input type="file" name="image" value="upload" />
<input type="submit" value="上传"/>
</form>
</body>
</html>
static/index.html
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<title></title>
</head>
<body>
<p>这是首页的内容</p>
</body>
</html>
D:\work\src>go run main.go
上传服务正在启动, 监听端口:8080...
http://localhost:8080/download?filename=redis.png