...
1
2
3
4
5 package render
6
7 import (
8 "bytes"
9 "fmt"
10 "html/template"
11 "net/http"
12
13 "github.com/gin-gonic/gin/internal/bytesconv"
14 "github.com/gin-gonic/gin/internal/json"
15 )
16
17
18 type JSON struct {
19 Data any
20 }
21
22
23 type IndentedJSON struct {
24 Data any
25 }
26
27
28 type SecureJSON struct {
29 Prefix string
30 Data any
31 }
32
33
34 type JsonpJSON struct {
35 Callback string
36 Data any
37 }
38
39
40 type AsciiJSON struct {
41 Data any
42 }
43
44
45 type PureJSON struct {
46 Data any
47 }
48
49 var (
50 jsonContentType = []string{"application/json; charset=utf-8"}
51 jsonpContentType = []string{"application/javascript; charset=utf-8"}
52 jsonASCIIContentType = []string{"application/json"}
53 )
54
55
56 func (r JSON) Render(w http.ResponseWriter) error {
57 return WriteJSON(w, r.Data)
58 }
59
60
61 func (r JSON) WriteContentType(w http.ResponseWriter) {
62 writeContentType(w, jsonContentType)
63 }
64
65
66 func WriteJSON(w http.ResponseWriter, obj any) error {
67 writeContentType(w, jsonContentType)
68 jsonBytes, err := json.Marshal(obj)
69 if err != nil {
70 return err
71 }
72 _, err = w.Write(jsonBytes)
73 return err
74 }
75
76
77 func (r IndentedJSON) Render(w http.ResponseWriter) error {
78 r.WriteContentType(w)
79 jsonBytes, err := json.MarshalIndent(r.Data, "", " ")
80 if err != nil {
81 return err
82 }
83 _, err = w.Write(jsonBytes)
84 return err
85 }
86
87
88 func (r IndentedJSON) WriteContentType(w http.ResponseWriter) {
89 writeContentType(w, jsonContentType)
90 }
91
92
93 func (r SecureJSON) Render(w http.ResponseWriter) error {
94 r.WriteContentType(w)
95 jsonBytes, err := json.Marshal(r.Data)
96 if err != nil {
97 return err
98 }
99
100 if bytes.HasPrefix(jsonBytes, bytesconv.StringToBytes("[")) && bytes.HasSuffix(jsonBytes,
101 bytesconv.StringToBytes("]")) {
102 if _, err = w.Write(bytesconv.StringToBytes(r.Prefix)); err != nil {
103 return err
104 }
105 }
106 _, err = w.Write(jsonBytes)
107 return err
108 }
109
110
111 func (r SecureJSON) WriteContentType(w http.ResponseWriter) {
112 writeContentType(w, jsonContentType)
113 }
114
115
116 func (r JsonpJSON) Render(w http.ResponseWriter) (err error) {
117 r.WriteContentType(w)
118 ret, err := json.Marshal(r.Data)
119 if err != nil {
120 return err
121 }
122
123 if r.Callback == "" {
124 _, err = w.Write(ret)
125 return err
126 }
127
128 callback := template.JSEscapeString(r.Callback)
129 if _, err = w.Write(bytesconv.StringToBytes(callback)); err != nil {
130 return err
131 }
132
133 if _, err = w.Write(bytesconv.StringToBytes("(")); err != nil {
134 return err
135 }
136
137 if _, err = w.Write(ret); err != nil {
138 return err
139 }
140
141 if _, err = w.Write(bytesconv.StringToBytes(");")); err != nil {
142 return err
143 }
144
145 return nil
146 }
147
148
149 func (r JsonpJSON) WriteContentType(w http.ResponseWriter) {
150 writeContentType(w, jsonpContentType)
151 }
152
153
154 func (r AsciiJSON) Render(w http.ResponseWriter) (err error) {
155 r.WriteContentType(w)
156 ret, err := json.Marshal(r.Data)
157 if err != nil {
158 return err
159 }
160
161 var buffer bytes.Buffer
162 for _, r := range bytesconv.BytesToString(ret) {
163 cvt := string(r)
164 if r >= 128 {
165 cvt = fmt.Sprintf("\\u%04x", int64(r))
166 }
167 buffer.WriteString(cvt)
168 }
169
170 _, err = w.Write(buffer.Bytes())
171 return err
172 }
173
174
175 func (r AsciiJSON) WriteContentType(w http.ResponseWriter) {
176 writeContentType(w, jsonASCIIContentType)
177 }
178
179
180 func (r PureJSON) Render(w http.ResponseWriter) error {
181 r.WriteContentType(w)
182 encoder := json.NewEncoder(w)
183 encoder.SetEscapeHTML(false)
184 return encoder.Encode(r.Data)
185 }
186
187
188 func (r PureJSON) WriteContentType(w http.ResponseWriter) {
189 writeContentType(w, jsonContentType)
190 }
191
View as plain text