github.com/livekit/protocol@v1.16.1-0.20240517185851-47e4c6bba773/utils/interceptors/curl.go (about) 1 package interceptors 2 3 import ( 4 "bytes" 5 "context" 6 "io" 7 "net/http" 8 "sort" 9 10 "github.com/twitchtv/twirp" 11 "google.golang.org/protobuf/encoding/protojson" 12 "google.golang.org/protobuf/proto" 13 ) 14 15 // NewCurlPrinter creates a Twirp interceptor that prints a curl commands for each request made. 16 func NewCurlPrinter(w io.Writer, url string) twirp.Interceptor { 17 return func(next twirp.Method) twirp.Method { 18 return func(ctx context.Context, req any) (any, error) { 19 pkg, ok1 := twirp.PackageName(ctx) 20 svc, ok2 := twirp.ServiceName(ctx) 21 meth, ok3 := twirp.MethodName(ctx) 22 if !ok1 || !ok2 || !ok3 { 23 return next(ctx, req) 24 } 25 m, ok := req.(proto.Message) 26 if !ok { 27 return next(ctx, req) 28 } 29 hdr, _ := twirp.HTTPRequestHeaders(ctx) 30 if err := printCurl(w, url, pkg, svc, meth, hdr, m); err != nil { 31 return nil, err 32 } 33 return next(ctx, req) 34 } 35 } 36 } 37 38 func printCurl(w io.Writer, url, pkg, svc, meth string, hdr http.Header, req proto.Message) error { 39 data, err := protojson.Marshal(req) 40 if err != nil { 41 return err 42 } 43 buf, isBuf := w.(*bytes.Buffer) 44 if !isBuf { 45 buf = new(bytes.Buffer) 46 } 47 buf.WriteString("curl ") 48 buf.WriteString(`-X POST `) 49 buf.WriteString("\\\n\t") 50 hkeys := make([]string, 0, len(hdr)) 51 for k := range hdr { 52 hkeys = append(hkeys, k) 53 } 54 sort.Strings(hkeys) 55 for _, h := range hkeys { 56 switch h { 57 case "Content-Type": 58 continue 59 } 60 for _, v := range hdr[h] { 61 buf.WriteString(`-H '`) 62 buf.WriteString(h) 63 buf.WriteString(`: `) 64 buf.WriteString(v) 65 buf.WriteString(`' `) 66 buf.WriteString("\\\n\t") 67 } 68 } 69 buf.WriteString(`-H 'Content-Type: application/json' `) 70 buf.WriteString("\\\n\t") 71 buf.WriteString(`--data '`) 72 buf.Write(data) 73 buf.WriteString(`' `) 74 buf.WriteString("\\\n\t") 75 buf.WriteString(url) 76 buf.WriteString("/twirp/") 77 buf.WriteString(pkg) 78 buf.WriteString(".") 79 buf.WriteString(svc) 80 buf.WriteString("/") 81 buf.WriteString(meth) 82 buf.WriteString("\n") 83 if isBuf { 84 return nil 85 } 86 _, err = buf.WriteTo(w) 87 return err 88 }