• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1package main
2
3//遇到报错请在当前目录下执行这个命令: go mod download golang.org/x/text
4import (
5    "bufio"
6    "crypto/rand"
7    "crypto/rsa"
8    "crypto/x509"
9    "crypto/x509/pkix"
10    "encoding/pem"
11    "math/big"
12    "net"
13    "bytes"
14    "fmt"
15    "io"
16    "io/ioutil"
17    "log"
18    "mime"
19    "net/http"
20    "os"
21    "os/exec"
22    "path"
23    "path/filepath"
24    "runtime"
25    "strings"
26    "time"
27)
28
29const HttpPort = 9001
30
31var exPath string
32
33// CGO_ENABLED=0 GOOS=windows GOARCH=amd64 go build main.go
34// CGO_ENABLED=0 GOOS=darwin GOARCH=amd64 go build main.go
35func cors(fs http.Handler, version string) http.HandlerFunc {
36    return func(w http.ResponseWriter, r *http.Request) {
37		// return if you do not want the FileServer handle a specific request
38        r.Header.Add("Cross-Origin-Opener-Policy", "same-origin")
39        r.Header.Add("Cross-Origin-Embedder-Policy", "require-corp")
40        w.Header().Add("Cross-Origin-Opener-Policy", "same-origin")
41        w.Header().Add("Cross-Origin-Embedder-Policy", "require-corp")
42        w.Header().Set("Access-Control-Allow-Origin", "*")
43        w.Header().Set("Access-Control-Allow-Credentials", "true")
44        w.Header().Set("Access-Control-Allow-Headers", "x-requested-with, authorization, blade-auth") //*
45        w.Header().Set("Access-Control-Allow-Methods", "*")                                           //*
46        w.Header().Set("Access-Control-Max-Age", "3600")
47        w.Header().Set("data-version", version)
48        fs.ServeHTTP(w, r)
49    }
50}
51
52func exist(path string) bool {
53    _, err := os.Stat(path)
54    if err != nil {
55        if os.IsExist(err) {
56            return true
57        }
58        return false
59    }
60    return true
61}
62func genSSL() {
63    if exist("cert/keyFile.key") || exist("cert/certFile.pem") {
64        fmt.Println("keyFile.key exists")
65        return
66    }
67    max := new(big.Int).Lsh(big.NewInt(1), 128)
68    serialNumber, _ := rand.Int(rand.Reader, max)
69    subject := pkix.Name{
70        Organization:       []string{"www.smartperf.com"},
71        OrganizationalUnit: []string{"ITs"},
72        CommonName:         "www.smartperf.com",
73	}
74    certificate509 := x509.Certificate{
75        SerialNumber: serialNumber,
76        Subject:      subject,
77        NotBefore:    time.Now(),
78        NotAfter:     time.Now().AddDate(10, 0, 0),
79        KeyUsage:     x509.KeyUsageKeyEncipherment | x509.KeyUsageDigitalSignature,
80        ExtKeyUsage:  []x509.ExtKeyUsage{x509.ExtKeyUsageServerAuth},
81        IPAddresses:  []net.IP{net.ParseIP("127.0.0.1")},
82    }
83    chekDir("cert")
84    pk, _ := rsa.GenerateKey(rand.Reader, 1024)
85    derBytes, _ := x509.CreateCertificate(rand.Reader, &certificate509, &certificate509, &pk.PublicKey, pk)
86    certOut, _ := os.Create("cert/certFile.pem")
87    pem.Encode(certOut, &pem.Block{Type: "CERTIFICATE", Bytes: derBytes})
88    certOut.Close()
89    keyOut, _ := os.Create("cert/keyFile.key")
90    pem.Encode(keyOut, &pem.Block{Type: "RSA PRIVATE KEY", Bytes: x509.MarshalPKCS1PrivateKey(pk)})
91    keyOut.Close()
92}
93func main() {
94    genSSL()
95    exPath = getCurrentAbPath()
96    fmt.Println(exPath)
97    go func() {
98        version := ""
99        readVersion, versionErr := ioutil.ReadFile(exPath + "/version.txt")
100        if versionErr != nil {
101            version = ""
102        } else {
103            version = string(readVersion)
104        }
105        mux := http.NewServeMux()
106        mime.TypeByExtension(".js")
107        mime.AddExtensionType(".js", "application/javascript")
108        log.Println(mime.TypeByExtension(".js"))
109        mux.HandleFunc("/upload", uploadHandler)
110        mux.Handle("/upload/", http.StripPrefix("/upload/", http.FileServer(http.Dir(exPath+"/upload"))))
111        fs := http.FileServer(http.Dir(exPath + "/"))
112        mux.Handle("/application/", http.StripPrefix("/application/", cors(fs, version)))
113        ser := &http.Server{
114            Addr:    fmt.Sprintf(":%d", HttpPort),
115            Handler: mux,
116        }
117        log.Println(fmt.Sprintf("HTTP[%d]服务启动", HttpPort))
118        open(fmt.Sprintf("https://localhost:%d/application", HttpPort))
119        err := ser.ListenAndServeTLS("cert/certFile.pem", "cert/keyFile.key")
120        CheckErr(err)
121    }()
122    select {}
123}
124
125func uploadHandler(w http.ResponseWriter, r *http.Request) {
126    defer func() {
127        var err = recover()
128        fmt.Println(err)
129    }()
130    chekDir(exPath + "/upload")
131    contentType := r.Header["Content-Type"]
132    if len(contentType) > 0 {
133        contentTypeName := contentType[0]
134        if strings.HasPrefix(contentTypeName, "multipart/form-data") {
135            err := r.ParseMultipartForm(32 << 20)
136            CheckErr(err)
137            file, header, err := r.FormFile("file")
138            CheckErr(err)
139            filename := header.Filename
140            index := strings.LastIndex(filename, ".")
141            distFileName := fmt.Sprintf("%d", time.Now().Unix())
142            distFileSuffix := filename[index:]
143            path := fmt.Sprintf("/upload/%s%s", distFileName, distFileSuffix)
144            dst, err := os.OpenFile(exPath+path, os.O_WRONLY|os.O_CREATE, 0666)
145            CheckErr(err)
146            defer dst.Close()
147            if _, err := io.Copy(dst, file); err != nil {
148                http.Error(w, err.Error(), http.StatusInternalServerError)
149                return
150            }
151            databaseUrl := transformDatabase(distFileName, distFileSuffix)
152            if databaseUrl != "" {
153                ohosTsPath := fmt.Sprintf("./upload/%s.ohos.ts", databaseUrl)
154                result, _ := PathExists(ohosTsPath)
155                if result {
156                    readFile, readErr := ioutil.ReadFile(ohosTsPath)
157                    if readErr == nil {
158                        fmt.Println(string(readFile))
159                        split := SplitLines(string(readFile))
160                        fmt.Println(split)
161                        if len(split) > 1 {
162                            if strings.HasSuffix(split[0], ":0") {
163                                fmt.Fprintf(w, fmt.Sprintf("/upload/%s", databaseUrl))
164                                return
165                            }
166                        }
167                    }
168                }
169            }
170            http.Error(w, "文件生成失败", http.StatusNotFound)
171            return
172        }
173    }
174}
175func SplitLines(s string) []string {
176    var lines []string
177    sc := bufio.NewScanner(strings.NewReader(s))
178    for sc.Scan() {
179        lines = append(lines, sc.Text())
180    }
181    return lines
182}
183
184func readFileFirstLine(path string) string {
185    file, err := os.Open(path)
186    if err != nil {
187        return ""
188    }
189    defer file.Close()
190
191    readFile := bufio.NewReader(file)
192    line, readErr := readFile.ReadString('\n')
193    if readErr != nil || io.EOF == err {
194        return ""
195    }
196    return line
197}
198
199func PathExists(path string) (bool, error) {
200    _, err := os.Stat(path)
201    if err == nil {
202        return true, nil
203    }
204    if os.IsNotExist(err) {
205        return false, nil
206    }
207    return false, err
208}
209
210func chekDir(path string) {
211    _, err := os.Stat(path)
212    if err != nil {
213        err := os.Mkdir(path, os.ModePerm)
214        if err != nil {
215            fmt.Printf("mkdir failed![%v]\n", err)
216        } else {
217            fmt.Printf("mkdir success!\n")
218        }
219    }
220}
221func CheckErr(err error) {
222    if err != nil {
223        log.Panicln(err)
224    }
225}
226
227func open(url string) error {
228    if isWindows() {
229        return openUrlWindows(url)
230    } else if isDarwin() {
231        return openUrlDarwin(url)
232    } else {
233        return openUrlOther(url)
234    }
235}
236
237func openUrlWindows(url string) error {
238    cmd := "cmd"
239    args := []string{"/c", "start", url}
240    return exec.Command(cmd, args...).Start()
241}
242func openUrlDarwin(url string) error {
243    var cmd = "open"
244    var args = []string{url}
245    return exec.Command(cmd, args...).Start()
246}
247func openUrlOther(url string) error {
248    var cmd = "xdg-open"
249    var args = []string{url}
250    return exec.Command(cmd, args...).Start()
251}
252
253func isWindows() bool {
254    return runtime.GOOS == "windows"
255}
256func isDarwin() bool {
257    return runtime.GOOS == "darwin"
258}
259
260func transformDatabase(name string, suffix string) string {
261    if isWindows() {
262        cmd := exec.Command(
263            "cmd",
264            "/c",
265            `.\bin\trace_streamer_windows.exe`,
266            fmt.Sprintf(`.\upload\%s%s`, name, suffix),
267            "-e",
268            fmt.Sprintf(`.\upload\%s.db`, name),
269        )
270        var stdout, stderr bytes.Buffer
271        cmd.Stdout = &stdout // 标准输出
272        cmd.Stderr = &stderr // 标准错误
273        err := cmd.Run()
274        if err != nil {
275            return ""
276        }
277        return fmt.Sprintf("%s.db", name)
278    } else if isDarwin() {
279        cmd := exec.Command(
280            "/bin/bash",
281            "-c",
282            fmt.Sprintf("%s/bin/trace_streamer_mac %s/upload/%s%s -e %s/upload/%s.db", exPath, exPath, name, suffix, exPath, name),
283        )
284        var stdout, stderr bytes.Buffer
285        cmd.Stdout = &stdout // 标准输出
286        cmd.Stderr = &stderr // 标准错误
287        err := cmd.Run()
288        outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
289        fmt.Printf("out:\n%s\n :\n%s\n", outStr, errStr)
290        if err != nil {
291            return ""
292        }
293        return fmt.Sprintf("%s.db", name)
294    } else {
295        cmd := exec.Command(
296            "/bin/bash",
297            "-c",
298            fmt.Sprintf("%s/bin/trace_streamer_linux %s/upload/%s%s -e %s/upload/%s.db", exPath, exPath, name, suffix, exPath, name),
299        )
300        var stdout, stderr bytes.Buffer
301        cmd.Stdout = &stdout // 标准输出
302        cmd.Stderr = &stderr // 标准错误
303        err := cmd.Run()
304        outStr, errStr := string(stdout.Bytes()), string(stderr.Bytes())
305        fmt.Printf("out:\n%s\n :\n%s\n", outStr, errStr)
306        if err != nil {
307            return ""
308        }
309        return fmt.Sprintf("%s.db", name)
310    }
311    return ""
312}
313func getCurrentAbPath() string {
314    dir := getCurrentAbPathByExecutable()
315    tmpDir, _ := filepath.EvalSymlinks(os.TempDir())
316    if strings.Contains(dir, tmpDir) {
317        return getCurrentAbPathByCaller()
318    }
319    return dir
320}
321
322func getCurrentAbPathByCaller() string {
323    var abPath string
324    _, filename, _, ok := runtime.Caller(0)
325    if ok {
326        abPath = path.Dir(filename)
327    }
328    return abPath
329}
330func getCurrentAbPathByExecutable() string {
331    exePath, err := os.Executable()
332    if err != nil {
333        log.Fatal(err)
334    }
335    res, _ := filepath.EvalSymlinks(filepath.Dir(exePath))
336    return res
337}
338