-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathmain.go
More file actions
124 lines (116 loc) · 2.76 KB
/
main.go
File metadata and controls
124 lines (116 loc) · 2.76 KB
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
package main
import (
"bufio"
"fmt"
"log"
"net/http"
"net/url"
"os"
"strings"
"sync"
)
var CACHE_DIR string
var HOST = "127.0.0.1"
var PORT = 9988
var seq = NewSequence()
var notFound = []byte("not found")
func init() {
gopath, _ := os.LookupEnv("GOPATH")
if gopath == "" {
panic("the env GOPATH is empty, please set it and rerun again")
}
log.Printf("Initialization completed, GOPATH is %s\n", gopath)
CACHE_DIR = strings.ReplaceAll(gopath, "\\", "/") + "/pkg/mod/cache/download"
log.Printf("Please set GOPROXY to http://%s:%d\n", HOST, PORT)
}
func main() {
err := http.ListenAndServe(fmt.Sprintf("%s:%d", HOST, PORT),
http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
uri, err := url.PathUnescape(r.RequestURI)
if err != nil {
panic(err)
}
var buffer = bufio.NewWriter(os.Stderr)
defer buffer.Flush()
logger := log.New(buffer, seq.Next()+"-", 1|2)
logger.Printf("<- %s", uri)
var resp = make([]byte, 0)
switch {
case strings.Contains(uri, "/@v"):
if !strings.HasSuffix(uri, "list") && !strings.HasSuffix(uri, "info") &&
!strings.HasSuffix(uri, "mod") && !strings.HasSuffix(uri, "zip") {
w.WriteHeader(http.StatusNotFound)
break
}
var dest = CACHE_DIR + uri
if info, err := os.Stat(dest); err != nil || info == nil {
w.WriteHeader(http.StatusNotFound)
resp = notFound
break
}
resp, err = os.ReadFile(dest)
if err != nil {
panic(err)
}
case strings.HasSuffix(uri, "/@latest"):
var dest = CACHE_DIR + strings.TrimSuffix(uri, "/@latest")
info, err := os.Stat(dest + "/@v/list")
if err != nil || info == nil {
w.WriteHeader(http.StatusNotFound)
resp = notFound
break
}
b, err := os.ReadFile(dest + "/@v/list")
if err != nil {
panic(err)
}
vs := strings.Split(strings.TrimSuffix(string(b), "\n"), "\n")
var ver string
for i := len(vs) - 1; i >= 0; i-- {
info, err := os.Stat(dest + "/@v/" + vs[i] + ".info")
if err == nil && info != nil {
ver = vs[i]
break
}
}
if ver != "" {
w.WriteHeader(http.StatusNotFound)
resp = notFound
break
}
resp, err = os.ReadFile(dest + "/@v/" + ver + ".info")
if err != nil {
panic(err)
}
default:
w.WriteHeader(http.StatusNotFound)
}
w.Write(resp)
if len(resp) > 512 {
logger.Printf("-> %s", "blob")
} else {
logger.Printf("-> %s", strings.ReplaceAll(string(resp), "\n", " "))
}
}),
)
if err != nil {
panic(err)
}
}
type sequence struct {
sync.Mutex
id int64
}
func NewSequence() *sequence {
return &sequence{}
}
func (seq *sequence) Next() string {
seq.Lock()
defer seq.Unlock()
if seq.id < 99999999 {
seq.id++
} else {
seq.id = 1
}
return fmt.Sprintf("%08d", seq.id)
}