...
  
  
     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