Files
IRC-kosmi-relay/cmd/parse-har/main.go

146 lines
3.1 KiB
Go
Raw Normal View History

2025-11-01 21:00:16 -04:00
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"os"
"strings"
)
type HAR struct {
Log struct {
Entries []struct {
Request struct {
Method string `json:"method"`
URL string `json:"url"`
} `json:"request"`
WebSocketMessages []struct {
Type string `json:"type"`
Data string `json:"data"`
Time float64 `json:"time"`
} `json:"_webSocketMessages"`
} `json:"entries"`
} `json:"log"`
}
type WSMessage struct {
ID string `json:"id"`
Type string `json:"type"`
Payload map[string]interface{} `json:"payload"`
}
func main() {
if len(os.Args) < 2 {
log.Fatal("Usage: parse-har <har-file>")
}
data, err := ioutil.ReadFile(os.Args[1])
if err != nil {
log.Fatal(err)
}
var har HAR
if err := json.Unmarshal(data, &har); err != nil {
log.Fatal(err)
}
// First pass: collect all responses
responses := make(map[string]bool) // ID -> has data
for _, entry := range har.Log.Entries {
for _, wsMsg := range entry.WebSocketMessages {
if wsMsg.Type != "receive" {
continue
}
var msg WSMessage
if err := json.Unmarshal([]byte(wsMsg.Data), &msg); err != nil {
continue
}
if msg.Type == "next" {
// Check if payload has data
if data, ok := msg.Payload["data"].(map[string]interface{}); ok && len(data) > 0 {
responses[msg.ID] = true
}
}
}
}
fmt.Println("=== WebSocket Operations (in order) ===\n")
msgCount := 0
for _, entry := range har.Log.Entries {
for _, wsMsg := range entry.WebSocketMessages {
if wsMsg.Type != "send" {
continue
}
var msg WSMessage
if err := json.Unmarshal([]byte(wsMsg.Data), &msg); err != nil {
continue
}
if msg.Type == "connection_init" {
fmt.Printf("[%d] connection_init\n", msgCount)
msgCount++
continue
}
if msg.Type == "subscribe" {
opName := ""
query := ""
variables := map[string]interface{}{}
extensions := map[string]interface{}{}
if payload, ok := msg.Payload["operationName"].(string); ok {
opName = payload
}
if q, ok := msg.Payload["query"].(string); ok {
query = q
}
if v, ok := msg.Payload["variables"].(map[string]interface{}); ok {
variables = v
}
if e, ok := msg.Payload["extensions"].(map[string]interface{}); ok {
extensions = e
}
hasResponse := ""
if responses[msg.ID] {
hasResponse = " ✅ GOT DATA"
} else {
hasResponse = " ❌ NO DATA"
}
fmt.Printf("[%d] %s (ID: %s)%s\n", msgCount, opName, msg.ID, hasResponse)
// Show query type
if strings.Contains(query, "mutation") {
fmt.Printf(" Type: MUTATION\n")
} else if strings.Contains(query, "subscription") {
fmt.Printf(" Type: SUBSCRIPTION\n")
} else if strings.Contains(query, "query") {
fmt.Printf(" Type: QUERY\n")
}
// Show variables
if len(variables) > 0 {
fmt.Printf(" Variables: %v\n", variables)
}
// Show extensions
if len(extensions) > 0 {
fmt.Printf(" Extensions: %v\n", extensions)
}
fmt.Println()
msgCount++
}
}
}
fmt.Printf("\nTotal operations: %d\n", msgCount)
}