package main
import (
"crypto/md5"
"fmt"
"io"
"log"
"net/http"
"os"
"path/filepath"
"strconv"
"strings"
"time"
"path"
"bufio"
)
const (
TYPE_json = 1
TYPE_text = 2
)
const tpl = `<html>
<head>
<title>上传文件</title>
</head>
<body>
<form enctype="multipart/form-data" action="/upload" method="post">
<table width="70%" border="1" cellspacing="0" cellpadding="0">
<tr>
<td> <input type="file" name="uploadfile" /></td>
</tr>
<tr>
<td>
<input type="hidden" name="token" value=""/>
<input type="submit" value="upload" />
</td>
</tr>
<tr>
<td><a href=files>文件访目录</a></td>
</tr>
</table>
</form>
</body>
</html`
/*获取当前时间*/
func gettime() string {
Year := time.Now().Year() //年[:3]
Month := time.Now().Month() //月
Day := time.Now().Day() //日
Hour := time.Now().Hour() //小时
Minute := time.Now().Minute() //分钟
Second := time.Now().Second() //秒
//Nanosecond:=time.Now().Nanosecond()//纳秒
var timestr string
timestr = fmt.Sprintf("%04d-%02d-%02d %02d:%02d:%02d", Year, Month, Day, Hour, Minute, Second)
return timestr
}
/*获取系统当前时间戳*/
func gettimecuo() string {
t := time.Now()
timestamp := strconv.FormatInt(t.UnixNano(), 10)
timestamp = timestamp[0:13]
//fmt.Println(timestamp)
//fmt.Println(t.Unix())
return timestamp
}
// 判断所给路径文件/文件夹是否存在
func Exists(path string) bool {
_, err := os.Stat(path) //os.Stat获取文件信息
if err != nil {
if os.IsExist(err) {
return true
}
return false
}
return true
}
// 处理/upload 逻辑
func upload(w http.ResponseWriter, r *http.Request) {
//fmt.Println("method:", r.Method) //获取请求的方法
fmt.Println(gettime(), "method:", r.Method)
if r.Method == "GET" {
crutime := time.Now().Unix()
h := md5.New()
io.WriteString(h, strconv.FormatInt(crutime, 10))
DocumentWrite(w, tpl, TYPE_text)
} else {
r.ParseMultipartForm(32 << 20)
file, handler, err := r.FormFile("uploadfile")
if err != nil {
fmt.Println(err)
return
}
defer file.Close()
//fmt.Fprintf(w, "%v", handler.Header)
//filepath := "./upload/" + handler.Filename
ext := strings.Split(handler.Filename, ".")
filepath := gettimecuo() + "." + ext[1]
tab := `<div align="center">
<table width="70%" border="1" cellspacing="0" cellpadding="0">
<tr>
<td>文件名</td>
<td>` + "<a href=./files/" + filepath + ">" + filepath + "</a>" + ` </td>
</tr>
<tr>
<td>路径</td>
<td><input type=text value=` + "./files/" + filepath + ` style="width:100%;"> </td>
</tr>
</table>
</div>`
//DocumentWrite(w, "<a href=./files/"+filepath+">文件"+filepath+"已经上传,右击复制链接地址即可</a>", TYPE_text)
DocumentWrite(w, tab, TYPE_text)
fmt.Println(filepath)
f, err := os.OpenFile("./upload/"+filepath, os.O_WRONLY|os.O_CREATE, 0666) // 此处假设当前目录下已存在upload目录
if err != nil {
fmt.Println(err)
return
}
defer f.Close()
io.Copy(f, file)
}
}
func upfile(w http.ResponseWriter, req *http.Request) {
surl :=req.FormValue("url")
fmt.Println(gettime(), req.Method, surl)
if(len(surl) == 0){
DocumentWrite(w, "获取的URL:"+surl, TYPE_text)
}else{
i ,r := down_resource(surl,"youxiz.net")
if(i ==0 ){
DocumentWrite(w, `{"state":"0", "msg":"本地化URL成功", "url":"`+r+`"}`, TYPE_json)
}else{
DocumentWrite(w, `{"state":"1", "msg":"本地化URL失败"}`, TYPE_json)
}
}
}
/*获取当前路径
"path/filepath"
"strings" //需要引入2个库
*/
func getCurrentDir(file string) string {
dir, err := filepath.Abs(filepath.Dir(os.Args[0]))
if err != nil {
log.Fatal(err)
}
ret := strings.Replace(dir, "\\", "/", -1)
ret += "/" + file
return ret
}
/* 判断文件是否存在 存在返回 true 不存在返回false*/
func File_Exists(filename string) bool {
var exist = true
if _, err := os.Stat(filename); os.IsNotExist(err) {
exist = false
}
return exist
}
/*保存文件(优化版)*/
func SaveLog(m_FilePath string, val string) {
var dir, filename string
filename = filepath.Base(m_FilePath)
if len(m_FilePath) > 1 && string([]byte(m_FilePath)[1:2]) == ":" {
filename = filepath.Base(m_FilePath)
dir = strings.TrimSuffix(m_FilePath, filename)
//print("abspath:filename:" + filename + "\n" + "dir:" + dir + "\n")
} else {
dir, _ = filepath.Abs(filepath.Dir(os.Args[0]))
dir = dir + "/" + m_FilePath
filename = filepath.Base(m_FilePath)
dir = strings.TrimSuffix(dir, filename)
//print("noptabspath:filename:" + filename + "\n" + "dir:" + dir + "\n")
}
p := dir + "/" + filename
p = strings.Replace(p, "\\", "/", -1)
p = strings.Replace(p, "//", "/", -1)
//print("fullpath" + p + "\n")
_, err := os.Stat(dir)
if err != nil {
if !os.IsExist(err) {
os.MkdirAll(dir, os.ModePerm)
}
}
fl, err := os.OpenFile(p, os.O_APPEND|os.O_CREATE, 0644)
defer fl.Close()
if err != nil {
fmt.Println("SaveLog:error")
} else {
io.WriteString(fl, val)
}
}
//文档返回值写出
func DocumentWrite(res http.ResponseWriter, val string, mtype int) {
//写出返回格式
if mtype == TYPE_json {
res.Header().Set("Content-Type", "application/json;charset=utf-8")
} else if mtype == TYPE_text {
res.Header().Set("Content-Type", "text/html;charset=utf-8")
} else {
res.Header().Set("Content-Type", "text/html;charset=utf-8")
}
//写出网页响应码
res.WriteHeader(200)
//写出结果
res.Write([]byte(val))
//服务控制台输出
//fmt.Println(val)
}
//文档跳转值
func DocumentRedirect(res http.ResponseWriter, req *http.Request, url string) {
http.Redirect(res, req, url, http.StatusFound)
}
func homepage(res http.ResponseWriter, req *http.Request) { //HOME
DocumentWrite(res, tpl, TYPE_text)
}
func DownFile(imgPath string,localPath string) (ret int) {
fileName := path.Base(localPath)
res,err := http.Get(imgPath)
if(nil != err){
fmt.Println("A error occurred!")
return 1
}
defer res.Body.Close()
//获得get请求响应的reader对象
//reader := bufio.NewReaderSize(res.Body, 32 * 1024)
file, err := os.Create(fileName)
if err != nil {
panic(err)
return 1
}
writer := bufio.NewWriter(file)
written, copy_err := io.Copy(writer, res.Body)
if copy_err != nil {
fmt.Println("????????????????", copy_err)
return 1
}
file.Close()
fmt.Printf("Total length: %d", written)
return 0
}
//下载资源
func down_resource(url string, destDir string)(ret int, outPath string) {
if strings.HasPrefix(url, "http") || strings.HasPrefix(url, "https") {
//下载图片资源
resp, err := http.Get(url)
if err != nil {
fmt.Println(err)
return 1,""
}
//判断文件是否存在
ext := url[ len(url) - 4 : ]
outPath := "./upload/" + destDir + ext
outPath2 := destDir + ext
if( File_Exists(outPath) ){
c := gettimecuo()
outPath = "./upload/" +destDir + "-" + c + ext
outPath2 = destDir + "-" + c + ext
}
fmt.Println(outPath2)
//只处理jpg图片
out, create_err := os.Create(outPath)
if create_err != nil {
fmt.Println(create_err)
return 1,""
}
defer out.Close()
defer resp.Body.Close()
_, copy_err := io.Copy(out, resp.Body)
if copy_err != nil {
fmt.Println("????????????????", copy_err)
return 1,""
}
out.Close()
return 0,outPath2
}else{
return 1,""
}
}
func main() {
//i := DownFile("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1201719684,3757858959&fm=26&gp=0.jpg", "0.jpg")
//i := down_resource("https://ss1.bdstatic.com/70cFuXSh_Q1YnxGkpoWK1HF6hhy/it/u=1201719684,3757858959&fm=26&gp=0.jpg", "1.jpg")
// i,s := down_resource("https://www.80host.com/cloud.html", "1.html")
//fmt.Println("下载结果:", i, s)
wd, err := os.Getwd()
if err != nil {
log.Fatal(err)
}
port := "80"
args := os.Args
if len(args) > 1 {
port = args[1]
}
wd = wd + "/upload"
os.Mkdir(wd, os.ModePerm)
fmt.Println(wd)
fs := http.FileServer(http.Dir(wd))
mux := http.NewServeMux()
mux.Handle("/files/", http.StripPrefix("/files", fs))
mux.HandleFunc("/upload", upload)
mux.HandleFunc("/upfile", upfile)
mux.HandleFunc("/", homepage)
//设置访问的路由
fmt.Println(gettime(), "服务器"+port+"开始服务。。。")
err = http.ListenAndServe(":"+port, mux) //设置监听的端口
if err != nil {
log.Fatal("ListenAndServe: ", err)
}
}
使用方法:
启动方法:
./http 8080
运行:
curl “http://127.0.0.1/upfile”
curl “http://127.0.0.1/upload”
curl “http://127.0.0.1/files”