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