github.com/yandex/pandora@v0.5.32/components/providers/scenario/http/templater/templater_html.go (about) 1 package templater 2 3 import ( 4 "fmt" 5 "html/template" 6 "strings" 7 "sync" 8 9 gun "github.com/yandex/pandora/components/guns/http_scenario" 10 "github.com/yandex/pandora/components/providers/scenario/templater" 11 ) 12 13 func NewHTMLTemplater() Templater { 14 return &HTMLTemplater{} 15 } 16 17 type HTMLTemplater struct { 18 templatesCache sync.Map 19 } 20 21 func (t *HTMLTemplater) Apply(parts *gun.RequestParts, vs map[string]any, scenarioName, stepName string) error { 22 const op = "scenario/TextTemplater.Apply" 23 tmpl, err := t.getTemplate(parts.URL, scenarioName, stepName, "url") 24 if err != nil { 25 return fmt.Errorf("%s, template.New, %w", op, err) 26 } 27 28 strBuilder := &strings.Builder{} 29 err = tmpl.Execute(strBuilder, vs) 30 if err != nil { 31 return fmt.Errorf("%s, template.Execute url, %w", op, err) 32 } 33 parts.URL = strBuilder.String() 34 strBuilder.Reset() 35 36 for k, v := range parts.Headers { 37 tmpl, err = t.getTemplate(v, scenarioName, stepName, k) 38 if err != nil { 39 return fmt.Errorf("%s, template.Execute Header %s, %w", op, k, err) 40 } 41 err = tmpl.Execute(strBuilder, vs) 42 if err != nil { 43 return fmt.Errorf("%s, template.Execute Header %s, %w", op, k, err) 44 } 45 parts.Headers[k] = strBuilder.String() 46 strBuilder.Reset() 47 } 48 if parts.Body != nil { 49 tmpl, err = t.getTemplate(string(parts.Body), scenarioName, stepName, "body") 50 if err != nil { 51 return fmt.Errorf("%s, template.Execute body, %w", op, err) 52 } 53 err = tmpl.Execute(strBuilder, vs) 54 if err != nil { 55 return fmt.Errorf("%s, template.Execute body, %w", op, err) 56 } 57 parts.Body = []byte(strBuilder.String()) 58 strBuilder.Reset() 59 } 60 return nil 61 } 62 63 func (t *HTMLTemplater) getTemplate(tmplBody, scenarioName, stepName, key string) (*template.Template, error) { 64 urlKey := fmt.Sprintf("%s_%s_%s", scenarioName, stepName, key) 65 tmpl, ok := t.templatesCache.Load(urlKey) 66 if !ok { 67 var err error 68 tmpl, err = template.New(urlKey).Funcs(templater.GetFuncs()).Parse(tmplBody) 69 if err != nil { 70 return nil, fmt.Errorf("scenario/TextTemplater.Apply, template.New, %w", err) 71 } 72 t.templatesCache.Store(urlKey, tmpl) 73 } 74 return tmpl.(*template.Template), nil 75 }