GO语言开发的http简单服务器,可上传,下载

package main

import (
	"crypto/md5"
	"fmt"
	"io"
	"log"
	"net/http"
	"os"
	"path/filepath"
	"strconv"
	"strings"
	"time"
)

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
}

// 处理/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))
		//token := fmt.Sprintf("%x", h.Sum(nil))

		//t, _ := template.ParseFiles("upload.gtpl")
		//t.Execute(tpl, token)
		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)
	}
}

/*获取当前路径
"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 main() {

	wd, err := os.Getwd()
	if err != nil {
		log.Fatal(err)
	}

 	
	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("/", homepage)

	//设置访问的路由
	fmt.Println(gettime(), "服务器80开始服务。。。")
	err = http.ListenAndServe(":80", mux) //设置监听的端口
	if err != nil {
		log.Fatal("ListenAndServe: ", err)
	}
}

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
gohttp是一个http文件服务器,因为是用go语言写的,所以加了一个go的抬头。之所以用go是因为发布起来是一个二进制文件,不同的平台都可以用,而且没有依赖问题,且稳定性也很好。    这个软件从很久以前就开始写了,第一次提交实在2015年的2月11号,作为组内存放公共文件的一个小软件。一开始的功能只有像 python -mSimpleHTTPServer 那种简单的功能。但是当我看到gotty这个软件的时候 ,意思到一个简单的软件竟然可以做到如此出色。之后这个http文件服务器就不断的被优化着,保持着简单易用的同时,开始赋予了它最强大的功能。    这个软件有很多的技术,隐藏在了其简易朴实的外表之下。请容我简单的介绍下pjax简称页面ajax技术        在gohttp进行目录却换的时候,你会看到地址栏在变,但是页面却是局部刷新的。各种文件的预览功能        所有常见的代码都可以直接在gohttp下预览,如果你用的是chrome浏览器的话,包括pdf,mp4,mp3都可以直接预览。实时的目录zip打包下载        强大的体现在它是实时的,即使你马上在目录下新增了一个文件,点击目录zip下载的时候,这个文件也会出现在里面。二维码的支持        手机下载往往没有电脑下载这么容易,点点鼠标就可以了。但是有了二维码,手机也只用扫一扫就可以下载了。苹果应用的在线安装        iphone应用安装包的扩展名是ipa,但是你还必须有个额外的plist文件才行。以及生成一个itms-services开头的地址,gohttp直接把这些工作都做了,ipa的解析,plist以及下载页面的自动生成。同普通文件一样,只需要点击右侧的生成二维码,然后用iphone手机扫描下,iphone的应用就安装到了你的手机上。PS:坑爹的苹果,就不能像安卓一样简单一点吗README文件的自动显示像github网站上的项目,readme文件都会作为项目的介绍自动显示出来。gohttp也借鉴了一下。如果目录下有readme文件的话,就会自动预览出来。文件上传简单文件上传也有着出色的表现,可以看到上传的进度,以及支持拖拽的方式上传文件。为了更方便的结合自动发布的功能,文件上传也有其相应的API,上传的时候也可是指定软件的版本号,存储结构参考了python,pypi官方的模式。还有很多很多其他的特性    http basic auth认证,不同文件不同的icon,gzip支持,目录的整合显示.... 还有很多功能等待着你去发现和有能力的你去补充。    截图  标签:gohttp
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值