forked from wheelcomplex/kmg
/
command.go
109 lines (105 loc) · 2.78 KB
/
command.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
package kmgHttp
import (
"errors"
"flag"
"fmt"
"github.com/bronze1man/kmg/kmgCache"
"github.com/bronze1man/kmg/kmgConsole"
"github.com/bronze1man/kmg/kmgCrypto"
"github.com/bronze1man/kmg/kmgErr"
"github.com/bronze1man/kmg/kmgFile"
"github.com/bronze1man/kmg/kmgStrings"
"net/http"
"os"
"path/filepath"
"sync"
)
func AddCommandList() {
kmgConsole.AddAction(kmgConsole.Command{
Name: "FileHttpServer",
Runner: runFileHttpServer,
})
kmgConsole.AddCommandWithName("HttpGet", func() {
requestUrl := ""
key := ""
flag.StringVar(&requestUrl, "url", "", "")
flag.StringVar(&key, "key", "", "crypto key use to decrypt respond")
flag.Parse()
if requestUrl == "" {
kmgConsole.ExitOnErr(errors.New("Usage: kmg HttpGet -url http://xxx"))
}
b := MustUrlGetContent(requestUrl)
var err error
if key != "" {
b, err = kmgCrypto.CompressAndEncryptBytesDecodeV2(kmgCrypto.Get32PskFromString(key), b)
if err != nil {
panic(err)
}
}
fmt.Print(string(b))
})
}
var lock *sync.Mutex = &sync.Mutex{}
var cacheFilePathSlice []string = []string{}
var cacheFilePathEncryptMap map[string][]byte = map[string][]byte{}
func runFileHttpServer() {
listenAddr := ""
path := ""
key := ""
flag.StringVar(&listenAddr, "l", ":80", "listen address")
flag.StringVar(&path, "path", "", "root path of the file server")
flag.StringVar(&key, "key", "", "crypto key use to encrypt all request of this server")
flag.Parse()
var err error
if path == "" {
path, err = os.Getwd()
if err != nil {
fmt.Printf("os.Getwd() fail %s", err)
return
}
} else {
kmgErr.PanicIfError(os.Chdir(path))
}
if key == "" {
http.Handle("/", http.FileServer(http.Dir(path)))
}
if key != "" {
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
realPath := filepath.Join(path, r.URL.Path)
if !kmgFile.MustFileExist(realPath) {
w.Write([]byte("File Not Exist"))
return
}
if !kmgStrings.IsInSlice(cacheFilePathSlice, realPath) {
cacheFilePathSlice = append(cacheFilePathSlice, realPath)
}
updateCache := func() {
cacheFilePathEncryptMap[realPath] = kmgCrypto.CompressAndEncryptBytesEncodeV2(
kmgCrypto.Get32PskFromString(key),
kmgFile.MustReadFile(realPath),
)
}
checkCache := func() {
lock.Lock()
defer lock.Unlock()
kmgCache.MustMd5FileChangeCache(realPath, []string{realPath}, func() {
updateCache()
})
}
checkCache()
//进程重启后,内存中的缓存掉了,但是文件系统的缓存还在
_, exist := cacheFilePathEncryptMap[realPath]
if !exist {
updateCache()
}
w.Write(cacheFilePathEncryptMap[realPath])
})
}
fmt.Println("start server at", listenAddr)
err = http.ListenAndServe(listenAddr, nil)
if err != nil {
fmt.Printf("http.ListenAndServe() fail %s", err)
return
}
return
}