generated from sv-tools/go-repo-template
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathconfig.go
98 lines (88 loc) · 2.56 KB
/
config.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
package main
import (
"bytes"
"fmt"
"net/http"
"os"
"text/template"
"golang.org/x/exp/slog"
)
type Config struct {
RequestIDHeader string `json:"request_id_header,omitempty" yaml:"request_id_header,omitempty"`
Routes []Route `json:"routes" yaml:"routes"`
Port int `json:"port,omitempty" yaml:"port,omitempty"`
}
type Route struct {
Pattern string `json:"pattern,omitempty" yaml:"pattern,omitempty"`
Responses []Response `json:"responses" yaml:"responses"`
}
type Response struct {
Headers http.Header `json:"headers,omitempty" yaml:"headers,omitempty"`
Repeat *int `json:"repeat,omitempty" yaml:"repeat,omitempty"`
Body string `json:"body,omitempty" yaml:"body,omitempty"`
File string `json:"file,omitempty" yaml:"file,omitempty"`
Code int `json:"code,omitempty" yaml:"code,omitempty"`
IsJSON bool `json:"is_json,omitempty" yaml:"is_json,omitempty"`
}
func responsesWriter(responses []Response, log *slog.Logger) http.HandlerFunc {
var i int
return func(writer http.ResponseWriter, request *http.Request) {
for {
if i > len(responses)-1 {
http.NotFound(writer, request)
return
}
response := responses[i]
if response.Repeat != nil {
if *response.Repeat <= 0 {
i++
continue
}
*response.Repeat--
}
var data []byte
if response.File != "" {
var err error
data, err = os.ReadFile(response.File)
if err != nil {
http.Error(writer, err.Error(), http.StatusInternalServerError)
return
}
} else if body := response.Body; body != "" {
var err error
data, err = executeTemplate(body, request)
if err != nil {
panic(err)
}
}
for name, header := range response.Headers {
for _, value := range header {
writer.Header().Add(name, value)
}
}
if response.IsJSON {
if writer.Header().Get("Content-Type") == "" {
writer.Header().Set("Content-Type", "application/json")
}
}
writer.WriteHeader(response.Code)
if len(data) > 0 {
if _, err := writer.Write(data); err != nil {
log.ErrorContext(request.Context(), "sending response failed", slog.String("error", err.Error()))
}
}
return
}
}
}
func executeTemplate(body string, request *http.Request) ([]byte, error) {
tmpl, err := template.New("response").Parse(body)
if err != nil {
return nil, fmt.Errorf("parse template failed: %w", err)
}
buf := bytes.NewBuffer(nil)
if err := tmpl.Execute(buf, request); err != nil {
return nil, fmt.Errorf("execute template failed: %w", err)
}
return buf.Bytes(), nil
}