11//go:build ignore
22
3- // Usage: go run parse_eventstream.go <file.resp.bin>
3+ // Usage:
44//
5- // Decodes an AWS EventStream binary file and prints each frame's
6- // decoded JSON body. Use this to inspect captured Bedrock responses
7- // and verify fixture contents.
5+ // go run parse_eventstream.go [dir]
6+ //
7+ // Finds all .resp.bin files in dir (default: current directory) and
8+ // generates a corresponding .resp.decoded file for each one. Existing
9+ // .resp.decoded files are overwritten.
10+ //
11+ // To decode a single file:
12+ //
13+ // go run parse_eventstream.go path/to/file.resp.bin
814package main
915
1016import (
@@ -13,23 +19,64 @@ import (
1319 "encoding/json"
1420 "fmt"
1521 "os"
22+ "path/filepath"
23+ "strings"
1624
1725 "github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream"
1826 "github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream/eventstreamapi"
1927)
2028
2129func main () {
22- if len (os .Args ) < 2 {
23- fmt .Fprintf (os .Stderr , "usage: go run parse_eventstream.go <file.resp.bin>\n " )
30+ arg := "."
31+ if len (os .Args ) > 1 {
32+ arg = os .Args [1 ]
33+ }
34+
35+ info , err := os .Stat (arg )
36+ if err != nil {
37+ fmt .Fprintf (os .Stderr , "stat %s: %v\n " , arg , err )
2438 os .Exit (1 )
2539 }
2640
27- data , err := os .ReadFile (os .Args [1 ])
41+ if ! info .IsDir () {
42+ if err := decodeFile (arg , os .Stdout ); err != nil {
43+ fmt .Fprintf (os .Stderr , "%v\n " , err )
44+ os .Exit (1 )
45+ }
46+ return
47+ }
48+
49+ files , err := filepath .Glob (filepath .Join (arg , "*.resp.bin" ))
2850 if err != nil {
29- fmt .Fprintf (os .Stderr , "read file: %v\n " , err )
51+ fmt .Fprintf (os .Stderr , "glob: %v\n " , err )
52+ os .Exit (1 )
53+ }
54+ if len (files ) == 0 {
55+ fmt .Fprintf (os .Stderr , "no .resp.bin files found in %s\n " , arg )
3056 os .Exit (1 )
3157 }
3258
59+ for _ , binFile := range files {
60+ outFile := strings .TrimSuffix (binFile , ".resp.bin" ) + ".resp.decoded"
61+ f , err := os .Create (outFile )
62+ if err != nil {
63+ fmt .Fprintf (os .Stderr , "create %s: %v\n " , outFile , err )
64+ continue
65+ }
66+ if err := decodeFile (binFile , f ); err != nil {
67+ fmt .Fprintf (os .Stderr , "decode %s: %v\n " , binFile , err )
68+ }
69+ f .Close ()
70+ fmt .Printf ("%s -> %s\n " , filepath .Base (binFile ), filepath .Base (outFile ))
71+ }
72+ }
73+
74+ func decodeFile (path string , w * os.File ) error {
75+ data , err := os .ReadFile (path )
76+ if err != nil {
77+ return fmt .Errorf ("read %s: %w" , path , err )
78+ }
79+
3380 decoder := eventstream .NewDecoder ()
3481 reader := bytes .NewReader (data )
3582 frameNum := 0
@@ -44,40 +91,41 @@ func main() {
4491 messageType := msg .Headers .Get (eventstreamapi .MessageTypeHeader )
4592 eventType := msg .Headers .Get (eventstreamapi .EventTypeHeader )
4693
47- fmt .Printf ( "=== Frame %d ===\n " , frameNum )
48- fmt .Printf ( " message-type: %s\n " , headerStr (messageType ))
49- fmt .Printf ( " event-type: %s\n " , headerStr (eventType ))
94+ fmt .Fprintf ( w , "=== Frame %d ===\n " , frameNum )
95+ fmt .Fprintf ( w , " message-type: %s\n " , headerStr (messageType ))
96+ fmt .Fprintf ( w , " event-type: %s\n " , headerStr (eventType ))
5097
5198 if headerStr (eventType ) != "chunk" {
52- fmt .Printf ( " payload: %s\n \n " , string (msg .Payload ))
99+ fmt .Fprintf ( w , " payload: %s\n \n " , string (msg .Payload ))
53100 continue
54101 }
55102
56103 var chunk struct {
57104 Bytes string `json:"bytes"`
58105 }
59106 if err := json .Unmarshal (msg .Payload , & chunk ); err != nil {
60- fmt .Printf ( " unmarshal error: %v\n \n " , err )
107+ fmt .Fprintf ( w , " unmarshal error: %v\n \n " , err )
61108 continue
62109 }
63110
64111 decoded , err := base64 .StdEncoding .DecodeString (chunk .Bytes )
65112 if err != nil {
66- fmt .Printf ( " base64 decode error: %v\n \n " , err )
113+ fmt .Fprintf ( w , " base64 decode error: %v\n \n " , err )
67114 continue
68115 }
69116
70117 var pretty json.RawMessage
71118 if err := json .Unmarshal (decoded , & pretty ); err != nil {
72- fmt .Printf ( " json: %s\n \n " , string (decoded ))
119+ fmt .Fprintf ( w , " json: %s\n \n " , string (decoded ))
73120 continue
74121 }
75122
76123 indented , _ := json .MarshalIndent (pretty , " " , " " )
77- fmt .Printf ( " body:\n %s\n \n " , string (indented ))
124+ fmt .Fprintf ( w , " body:\n %s\n \n " , string (indented ))
78125 }
79126
80- fmt .Printf ("Total frames: %d\n " , frameNum )
127+ fmt .Fprintf (w , "Total frames: %d\n " , frameNum )
128+ return nil
81129}
82130
83131func headerStr (h eventstream.Value ) string {
0 commit comments