Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
bitepeng committed Dec 10, 2021
1 parent 99d7c5e commit e764e30
Show file tree
Hide file tree
Showing 22 changed files with 367 additions and 4 deletions.
6 changes: 5 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
# Binaries for programs and plugins
*.exe
*.exe~
*.dll
*.so
Expand All @@ -13,3 +12,8 @@

# Dependency directories (remove the comment below to include it)
# vendor/

.idea
.DS_Store
tmp
*.log
2 changes: 1 addition & 1 deletion LICENSE
Original file line number Diff line number Diff line change
Expand Up @@ -186,7 +186,7 @@
same "printed page" as the copyright notice for easier
identification within third-party archives.

Copyright [yyyy] [name of copyright owner]
Copyright 2021 [email protected] http://www.4bit.cn

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
Expand Down
31 changes: 29 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,29 @@
# easyhttpd
EasyHttpd 超级简便(无任何依赖,一个文件,快速开启)的自建文件服务器
# EasyHttpd
- EasyHttpd 超级简便的自建Http服务器
- 基于Go语言,极少依赖,一个文件,快速开启


## 下载快速开始
- 从bin目录下载对应操作系统的可执行文件
- windows平台,easyhttpd.exe 双击执行


## 命令行参数
```
easyhttpd.exe -r ./ -p :8888
```
- 服务根文件目录
- `-r 根路径`
- 服务端口(可指定IP)
- `-p 0.0.0.0:8888`
- `-p :8888`

## 使用Go语言功能点
- [x] net/http server
- [x] go embed fs
- [x] http template
- [x] http file upload
- [x] run cmd open
- [x] file read and write
- [x] host ip address
- [x] multi platform cross compilation
Binary file added bin/linux/easyhttpd
Binary file not shown.
8 changes: 8 additions & 0 deletions bin/linux/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
#!/bin/bash


#dirname
project_path=$(cd `dirname $0`; pwd)
project_name="${project_path##*/}"
echo $project_path
echo $project_name
Binary file added bin/mac/easyhttpd
Binary file not shown.
12 changes: 12 additions & 0 deletions bin/mac/run.command
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
#!/bin/bash


#dirname
project_path=$(cd `dirname $0`; pwd)
project_name="${project_path##*/}"
echo $project_path
echo $project_name

#runexe
cd $project_path
./$project_name
Binary file added bin/win64/easyhttpd.exe
Binary file not shown.
5 changes: 5 additions & 0 deletions bin/win64/run.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
echo %cd%

easyhttpd.exe -r ./ -p :8888

pause
11 changes: 11 additions & 0 deletions build.bat
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
set GOARCH=amd64
set GOOS=windows
go build -o bin/win64/easyhttpd.exe .\main.go

set GOARCH=amd64
set GOOS=linux
go build -o bin/linux/easyhttpd .\main.go

set GOARCH=amd64
set GOOS=darwin
go build -o bin/mac/easyhttpd .\main.go
39 changes: 39 additions & 0 deletions core/httpd/handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
package httpd

import (
"fmt"
"io"
"net/http"
"os"
)

// fileHandle 文件上传界面
func (s *Server) fileHandle(w http.ResponseWriter, r *http.Request) {
data := map[string]string{"title": "Easyhttpd File Upload"}
s.template.ExecuteTemplate(w, "upload.html", data)

}

// uploadHandle 上传文件操作
func (s *Server) uploadHandle(w http.ResponseWriter, r *http.Request) {
file, head, err := r.FormFile("file")
if err != nil {
fmt.Println(err)
io.WriteString(w, err.Error())
return
}
defer file.Close()
filePath := s.root + head.Filename
fW, err := os.Create(filePath)
if err != nil {
io.WriteString(w, "文件创建失败")
return
}
defer fW.Close()
_, err = io.Copy(fW, file)
if err != nil {
io.WriteString(w, "文件保存失败")
return
}
io.WriteString(w, "save to "+filePath)
}
50 changes: 50 additions & 0 deletions core/httpd/server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package httpd

import (
"log"
"net/http"
"text/template"

"easyhttpd/core/tools"
"easyhttpd/resource"
)

// Server 配置Httpd服务
type Server struct {
root string
port string
template *template.Template
}

// Start 启动Httpd服务器
func (s *Server) Start(root, port string) {

//配置服务
s.root = root
s.port = port
tpl, _ := template.ParseFS(resource.Templates, "templates/*.html")
s.template = tpl

//文件服务器
mux := http.DefaultServeMux
fs := http.FileServer(http.Dir(s.root))
mux.Handle("/", http.StripPrefix("/", fs))

//服务路由
s.router(mux)

//启动服务器
log.Printf("EasyHttpd Server Started! (root=> %s,port=>%s)\n", s.root, s.port)
tools.Open("http://127.0.0.1" + s.port)
log.Fatal(http.ListenAndServe(s.port, nil))

}

// router 服务路由注册
func (s *Server) router(mux *http.ServeMux) {

//上传文件
mux.HandleFunc("/file", s.fileHandle)
mux.HandleFunc("/upload", s.uploadHandle)

}
45 changes: 45 additions & 0 deletions core/tools/embedui.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
package tools

import (
"embed"
"errors"
"io"
"io/fs"
"log"
"net/http"
"path"
"path/filepath"
"strings"
)

// EmbedUI 嵌入静态资源
type EmbedUI struct {
Fs embed.FS // 静态资源
Path string // 设置embed文件到静态资源的相对路径,也就是embed注释里的路径
}

// EmbedUI.Open 静态资源访问
func (w *EmbedUI) Open(name string) (http.File, error) {
log.Println("EmbedUI open: ", name)
if filepath.Separator != '/' && strings.ContainsRune(name, filepath.Separator) {
return nil, errors.New("http: invalid character in file path")
}
fullName := filepath.Join(w.Path, filepath.FromSlash(path.Clean("/"+name)))
file, err := w.Fs.Open(fullName)
wf := &EmbedUIFile{
File: file,
}
log.Println("EmbedUI open err: ", err.Error())
return wf, err
}

// EmbedUIFile 静态资源文件
type EmbedUIFile struct {
io.Seeker
fs.File
}

// EmbedUIFile.Readdir 静态资源目录
func (*EmbedUIFile) Readdir(count int) ([]fs.FileInfo, error) {
return nil, nil
}
35 changes: 35 additions & 0 deletions core/tools/filedo.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
package tools

import (
"fmt"
"io/ioutil"
"os"
"strings"
)

func WriteFile(path string, data []byte) {
// 如果文件夹不存在,预先创建文件夹
if lastSeparator := strings.LastIndex(path, "/"); lastSeparator != -1 {
dirPath := path[:lastSeparator]
if _, err := os.Stat(dirPath); err != nil && os.IsNotExist(err) {
os.MkdirAll(dirPath, os.ModePerm)
}
}

// 已存在的文件,不应该覆盖重写,可能在前端更改了配置文件等
if _, err := os.Stat(path); os.IsNotExist(err) {
if err2 := ioutil.WriteFile(path, data, os.ModePerm); err2 != nil {
fmt.Printf("Write file failed: %s\n", path)
}
} else {
fmt.Printf("File exist, skip: %s\n", path)
}
}

func ReadFile(path string) string {
f, err := os.ReadFile(path)
if err != nil {
fmt.Printf("Read file failed: %s\n", path)
}
return string(f)
}
22 changes: 22 additions & 0 deletions core/tools/hostip.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package tools

import (
"fmt"
"net"
)

func GetIP() {
addrs, err := net.InterfaceAddrs()
if err != nil {
fmt.Println(err)
return
}
for _, address := range addrs {
// 检查ip地址判断是否回环地址
if ipnet, ok := address.(*net.IPNet); ok && !ipnet.IP.IsLoopback() {
if ipnet.IP.To4() != nil {
fmt.Println(ipnet.IP.String())
}
}
}
}
7 changes: 7 additions & 0 deletions core/tools/hostip_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
package tools

import "testing"

func TestGetIP(t *testing.T) {
GetIP()
}
31 changes: 31 additions & 0 deletions core/tools/openit.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
package tools

import (
"fmt"
"os/exec"
"runtime"
"strings"
)

// commands 执行程序
var commands = map[string]string{
"windows": "cmd /c start ",
"darwin": "open ",
"linux": "xdg-open ", //eog -w
}

// Open 打开资源
func Open(uri string) error {
//runtime.GOOS
run, ok := commands[runtime.GOOS]
if !ok {
return fmt.Errorf("don't know how to open things on %s platform", runtime.GOOS)
}
//exec.Command
run = run + uri
cmds := strings.Split(run, " ")
cmd := exec.Command(cmds[0], cmds[1:]...)
//cmd.Start
//fmt.Println("[CommandAs]", cmds)
return cmd.Start()
}
15 changes: 15 additions & 0 deletions core/tools/openit_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
package tools

import "testing"

func TestOpen(t *testing.T) {
if err := Open("http://127.0.0.1:8008"); err != nil {
t.Error(err)
}
}

func TestOpen2(t *testing.T) {
if err := Open("/Users/"); err != nil {
t.Error(err)
}
}
3 changes: 3 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
module easyhttpd

go 1.16
23 changes: 23 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
package main

import (
"flag"

"easyhttpd/core/httpd"
)

var (
RootPath string //根目录
ServerPort string //服务端口
)

func main() {
//命令行参数
flag.StringVar(&RootPath, "r", "./", "-r for HttpServer root path")
flag.StringVar(&ServerPort, "p", ":8008", "-p for HttpServer server port")
flag.Parse()

//http服务器
httpd := httpd.Server{}
httpd.Start(RootPath, ServerPort)
}
9 changes: 9 additions & 0 deletions resource/embed.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
package resource

import (
"embed"
)

//嵌入web模板目录
//go:embed templates
var Templates embed.FS
Loading

0 comments on commit e764e30

Please sign in to comment.