golang开发的http服务器,这个是终极版了!

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”

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值