web/unhar.go

69 lines
1.6 KiB
Go

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)
}
}