func main() { flag.Parse() if *rebuild { fmt.Println("\nClearing files...") if err := deletePath(thirdPartyDir); err != nil { fmt.Printf("Failed to delete %s directory: %v\n", thirdPartyDir, err) return } if err := deletePath(compiledDir); err != nil { fmt.Printf("Failed to delete %s directory: %v\n", compiledDir, err) return } } os.Mkdir(thirdPartyDir, 0777) os.Mkdir(compiledDir, 0777) wd, err := os.Getwd() if err != nil { fmt.Printf("Unable to get working directory: %v\n", err) return } closureLibraryDir := path.Join(wd, thirdPartyDir, "closure-library") closureCompilerDir := path.Join(wd, thirdPartyDir, "closure-compiler") axisDir := path.Join(thirdPartyDir, "flot-axislabels") if _, err := os.Stat(closureLibraryDir); os.IsNotExist(err) { fmt.Println("\nDownloading Closure library...") runCommand("git", "clone", "https://github.com/google/closure-library", closureLibraryDir) } _, errD := os.Stat(closureCompilerDir) _, errF := os.Stat(path.Join(closureCompilerDir, closureCompilerZip)) if os.IsNotExist(errD) || os.IsNotExist(errF) { fmt.Println("\nDownloading Closure compiler...") // Current compiler, if any, is not current. Remove old files. if err := deletePath(closureCompilerDir); err != nil { fmt.Printf("Failed to clear compiler directory: %v\n", err) } // Download desired file. os.Mkdir(closureCompilerDir, 0777) resp, err := http.Get(closureCompilerURL) if err != nil { fmt.Printf("Failed to download Closure compiler: %v\n", err) fmt.Printf("\nIf this persists, please manually download the compiler from %s into the %s directory, unzip it into the %s diretory, and rerun this script.\n\n", closureCompilerURL, closureCompilerDir, closureCompilerDir) return } defer resp.Body.Close() contents, err := ioutil.ReadAll(resp.Body) if err != nil { fmt.Printf("Couldn't get zip contents: %v\n", err) return } if err := saveFile(path.Join(closureCompilerDir, closureCompilerZip), contents); err != nil { fmt.Printf("Couldn't save Closure zip file: %v\n", err) return } files, err := bugreportutils.Contents("", contents) if err != nil { fmt.Printf("Couldn't get Closure zip contents: %v\n", err) return } for n, c := range files { name := n[1:] if err := saveFile(path.Join(closureCompilerDir, name), c); err != nil { fmt.Printf("Couldn't save Closure content file: %v\n", err) return } } } if _, err := os.Stat(axisDir); os.IsNotExist(err) { fmt.Println("\nDownloading 3rd-party JS files...") runCommand("git", "clone", "https://github.com/xuanluo/flot-axislabels.git", axisDir) } fmt.Println("\nGenerating JS runfiles...") out, err := historianutils.RunCommand("python", path.Join(closureLibraryDir, "closure/bin/build/depswriter.py"), fmt.Sprintf(`--root=%s`, path.Join(closureLibraryDir, "closure", "goog")), `--root_with_prefix=js ../../../../js`) if err != nil { fmt.Printf("Couldn't generate runfile: %v\n", err) return } if err = saveFile(path.Join(wd, compiledDir, "historian_deps-runfiles.js"), []byte(out)); err != nil { fmt.Printf("Couldn't save runfiles file: %v\n", err) return } fmt.Println("\nGenerating optimized JS runfiles...") runCommand("java", "-jar", path.Join(closureCompilerDir, "compiler.jar"), "--closure_entry_point", "historian.upload", "--js", "js/*.js", "--js", path.Join(closureLibraryDir, "closure/goog/base.js"), "--js", path.Join(closureLibraryDir, "closure/goog/**/*.js"), "--only_closure_dependencies", "--generate_exports", "--js_output_file", path.Join(wd, compiledDir, "historian-optimized.js"), "--output_manifest", path.Join(wd, compiledDir, "manifest.MF"), "--compilation_level", "SIMPLE_OPTIMIZATIONS", ) }
// HTTPAnalyzeHandler processes the bugreport package uploaded via an http request's multipart body. func HTTPAnalyzeHandler(w http.ResponseWriter, r *http.Request) { // Do not accept files that are greater than 50 MBs if r.ContentLength > maxFileSize { closeConnection(w, "File too large (>50MB).") return } r.Body = http.MaxBytesReader(w, r.Body, maxFileSize) log.Printf("Trace starting reading uploaded file. %d bytes", r.ContentLength) defer log.Printf("Trace ended analyzing file.") var refCount int //get the multipart reader for the request. reader, err := r.MultipartReader() if err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return } var fs []UploadedFile //copy each part to destination. for { part, err := reader.NextPart() if err == io.EOF { break } // If part.FileName() is empty, skip this iteration. if part.FileName() == "" { continue } b, err := ioutil.ReadAll(part) if err != nil { http.Error(w, "Failed to read file. Please try again.", http.StatusInternalServerError) return } if len(b) == 0 { continue } files, err := bugreportutils.Contents(part.FileName(), b) if err != nil { http.Error(w, fmt.Sprintf("failed to read file contents: %v", err), http.StatusInternalServerError) return } var contents []byte valid := false fname := "" contentLoop: for n, f := range files { switch part.FormName() { case "bugreport", "bugreport2": if bugreportutils.IsBugReport(f) { // TODO: handle the case of additional kernel and powermonitor files within a single uploaded file valid = true contents = f fname = n break contentLoop } case "kernel": if kernel.IsTrace(f) { valid = true contents = f fname = n break contentLoop } case "powermonitor": if powermonitor.IsValid(f) { valid = true contents = f fname = n break contentLoop } default: valid = true contents = f fname = n break contentLoop } } if !valid { http.Error(w, fmt.Sprintf("%s does not contain a valid %s file", part.FileName(), part.FormName()), http.StatusInternalServerError) return } fs = append(fs, UploadedFile{part.FormName(), fname, contents}) } AnalyzeAndResponse(w, fs, refCount) }