package main import ( "encoding/base64" "encoding/json" "fmt" "io" "os" "path/filepath" "strings" ) func extractHar(src io.Reader, outdir string) error { bs, err := io.ReadAll(src) if err != nil { return err } var har struct { Log struct { Entries []struct { Request struct { URL string `json:"url"` } Response struct { Content struct { MIMEType string `json:"mimeType"` Encoding string `json:"encoding"` Text string `json:"text"` } `json:"content"` } `json:"response"` } `json:"entries"` } `json:"log"` } if err := json.Unmarshal(bs, &har); err != nil { return err } for _, entry := range har.Log.Entries { outfile := filepath.Join(outdir, strings.Split(strings.ReplaceAll(strings.TrimPrefix(entry.Request.URL, "https://"), "%20", "-"), "?")[0]) if entry.Response.Content.MIMEType == "text/html" && !strings.HasSuffix(outfile, ".html") { outfile = filepath.Join(outfile, "index.html") } if err := os.MkdirAll(filepath.Dir(outfile), 0777); err != nil { return err } var content []byte switch entry.Response.Content.Encoding { case "": content = []byte(entry.Response.Content.Text) case "base64": content, err = base64.StdEncoding.DecodeString(entry.Response.Content.Text) default: return fmt.Errorf("unknown encoding for %q: %q", entry.Request.URL, entry.Response.Content.Encoding) } if err := os.WriteFile(outfile, content, 0666); err != nil { return err } } return nil } func main() { if err := extractHar(os.Stdin, os.Args[1]); err != nil { fmt.Fprintf(os.Stderr, "%s: error: %v\n", os.Args[0], err) os.Exit(1) } }