1// Copyright 2014 Manu Martinez-Almeida. All rights reserved. 2// Use of this source code is governed by a MIT style 3// license that can be found in the LICENSE file. 4 5package render 6 7import ( 8 "bytes" 9 "fmt" 10 "html/template" 11 "net/http" 12 13 "github.com/gin-gonic/gin/json" 14) 15 16type JSON struct { 17 Data interface{} 18} 19 20type IndentedJSON struct { 21 Data interface{} 22} 23 24type SecureJSON struct { 25 Prefix string 26 Data interface{} 27} 28 29type JsonpJSON struct { 30 Callback string 31 Data interface{} 32} 33 34type AsciiJSON struct { 35 Data interface{} 36} 37 38type SecureJSONPrefix string 39 40var jsonContentType = []string{"application/json; charset=utf-8"} 41var jsonpContentType = []string{"application/javascript; charset=utf-8"} 42var jsonAsciiContentType = []string{"application/json"} 43 44func (r JSON) Render(w http.ResponseWriter) (err error) { 45 if err = WriteJSON(w, r.Data); err != nil { 46 panic(err) 47 } 48 return 49} 50 51func (r JSON) WriteContentType(w http.ResponseWriter) { 52 writeContentType(w, jsonContentType) 53} 54 55func WriteJSON(w http.ResponseWriter, obj interface{}) error { 56 writeContentType(w, jsonContentType) 57 jsonBytes, err := json.Marshal(obj) 58 if err != nil { 59 return err 60 } 61 w.Write(jsonBytes) 62 return nil 63} 64 65func (r IndentedJSON) Render(w http.ResponseWriter) error { 66 r.WriteContentType(w) 67 jsonBytes, err := json.MarshalIndent(r.Data, "", " ") 68 if err != nil { 69 return err 70 } 71 w.Write(jsonBytes) 72 return nil 73} 74 75func (r IndentedJSON) WriteContentType(w http.ResponseWriter) { 76 writeContentType(w, jsonContentType) 77} 78 79func (r SecureJSON) Render(w http.ResponseWriter) error { 80 r.WriteContentType(w) 81 jsonBytes, err := json.Marshal(r.Data) 82 if err != nil { 83 return err 84 } 85 // if the jsonBytes is array values 86 if bytes.HasPrefix(jsonBytes, []byte("[")) && bytes.HasSuffix(jsonBytes, []byte("]")) { 87 w.Write([]byte(r.Prefix)) 88 } 89 w.Write(jsonBytes) 90 return nil 91} 92 93func (r SecureJSON) WriteContentType(w http.ResponseWriter) { 94 writeContentType(w, jsonContentType) 95} 96 97func (r JsonpJSON) Render(w http.ResponseWriter) (err error) { 98 r.WriteContentType(w) 99 ret, err := json.Marshal(r.Data) 100 if err != nil { 101 return err 102 } 103 104 if r.Callback == "" { 105 w.Write(ret) 106 return nil 107 } 108 109 callback := template.JSEscapeString(r.Callback) 110 w.Write([]byte(callback)) 111 w.Write([]byte("(")) 112 w.Write(ret) 113 w.Write([]byte(")")) 114 115 return nil 116} 117 118func (r JsonpJSON) WriteContentType(w http.ResponseWriter) { 119 writeContentType(w, jsonpContentType) 120} 121 122func (r AsciiJSON) Render(w http.ResponseWriter) (err error) { 123 r.WriteContentType(w) 124 ret, err := json.Marshal(r.Data) 125 if err != nil { 126 return err 127 } 128 129 var buffer bytes.Buffer 130 for _, r := range string(ret) { 131 cvt := "" 132 if r < 128 { 133 cvt = string(r) 134 } else { 135 cvt = fmt.Sprintf("\\u%04x", int64(r)) 136 } 137 buffer.WriteString(cvt) 138 } 139 140 w.Write(buffer.Bytes()) 141 return nil 142} 143 144func (r AsciiJSON) WriteContentType(w http.ResponseWriter) { 145 writeContentType(w, jsonAsciiContentType) 146} 147