Ver Fonte

Add PureJSON renderer (#694)

Closes #693
Filip Figiel há 7 anos atrás
pai
commit
c6110f970c
8 ficheiros alterados com 133 adições e 4 exclusões
  1. 28 0
      README.md
  2. 17 0
      context_17.go
  3. 27 0
      context_17_test.go
  4. 3 2
      context_test.go
  5. 1 0
      json/json.go
  6. 28 0
      render/json_17.go
  7. 26 0
      render/render_17_test.go
  8. 3 2
      render/render_test.go

+ 28 - 0
README.md

@@ -991,6 +991,34 @@ func main() {
 }
 ```
 
+#### PureJSON
+
+Normally, JSON replaces special HTML characters with their unicode entities, e.g. `<` becomes  `\u003c`. If you want to encode such characters literally, you can use PureJSON instead.
+This feature is unavailable in Go 1.6 and lower.
+
+```go
+func main() {
+	r := gin.Default()
+	
+	// Serves unicode entities
+	r.GET("/json", func(c *gin.Context) {
+		c.JSON(200, gin.H{
+			"html": "<b>Hello, world!</b>",
+		})
+	})
+	
+	// Serves literal characters
+	r.GET("/purejson", func(c *gin.Context) {
+		c.PureJSON(200, gin.H{
+			"html": "<b>Hello, world!</b>",
+		})
+	})
+	
+	// listen and serve on 0.0.0.0:8080
+	r.Run(":8080)
+}
+```
+
 ### Serving static files
 
 ```go

+ 17 - 0
context_17.go

@@ -0,0 +1,17 @@
+// Copyright 2018 Gin Core Team.  All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package gin
+
+import (
+	"github.com/gin-gonic/gin/render"
+)
+
+// PureJSON serializes the given struct as JSON into the response body.
+// PureJSON, unlike JSON, does not replace special html characters with their unicode entities.
+func (c *Context) PureJSON(code int, obj interface{}) {
+	c.Render(code, render.PureJSON{Data: obj})
+}

+ 27 - 0
context_17_test.go

@@ -0,0 +1,27 @@
+// Copyright 2018 Gin Core Team.  All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package gin
+
+import (
+	"net/http"
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+// Tests that the response is serialized as JSON
+// and Content-Type is set to application/json
+// and special HTML characters are preserved
+func TestContextRenderPureJSON(t *testing.T) {
+	w := httptest.NewRecorder()
+	c, _ := CreateTestContext(w)
+	c.PureJSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"})
+	assert.Equal(t, http.StatusCreated, w.Code)
+	assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"<b>\"}\n", w.Body.String())
+	assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
+}

+ 3 - 2
context_test.go

@@ -619,14 +619,15 @@ func TestContextRenderPanicIfErr(t *testing.T) {
 
 // Tests that the response is serialized as JSON
 // and Content-Type is set to application/json
+// and special HTML characters are escaped
 func TestContextRenderJSON(t *testing.T) {
 	w := httptest.NewRecorder()
 	c, _ := CreateTestContext(w)
 
-	c.JSON(http.StatusCreated, H{"foo": "bar"})
+	c.JSON(http.StatusCreated, H{"foo": "bar", "html": "<b>"})
 
 	assert.Equal(t, http.StatusCreated, w.Code)
-	assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
+	assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"\\u003cb\\u003e\"}", w.Body.String())
 	assert.Equal(t, "application/json; charset=utf-8", w.HeaderMap.Get("Content-Type"))
 }
 

+ 1 - 0
json/json.go

@@ -12,4 +12,5 @@ var (
 	Marshal       = json.Marshal
 	MarshalIndent = json.MarshalIndent
 	NewDecoder    = json.NewDecoder
+	NewEncoder    = json.NewEncoder
 )

+ 28 - 0
render/json_17.go

@@ -0,0 +1,28 @@
+// Copyright 2018 Gin Core Team.  All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package render
+
+import (
+	"net/http"
+
+	"github.com/gin-gonic/gin/json"
+)
+
+type PureJSON struct {
+	Data interface{}
+}
+
+func (r PureJSON) Render(w http.ResponseWriter) error {
+	r.WriteContentType(w)
+	encoder := json.NewEncoder(w)
+	encoder.SetEscapeHTML(false)
+	return encoder.Encode(r.Data)
+}
+
+func (r PureJSON) WriteContentType(w http.ResponseWriter) {
+	writeContentType(w, jsonContentType)
+}

+ 26 - 0
render/render_17_test.go

@@ -0,0 +1,26 @@
+// Copyright 2018 Gin Core Team.  All rights reserved.
+// Use of this source code is governed by a MIT style
+// license that can be found in the LICENSE file.
+
+// +build go1.7
+
+package render
+
+import (
+	"net/http/httptest"
+	"testing"
+
+	"github.com/stretchr/testify/assert"
+)
+
+func TestRenderPureJSON(t *testing.T) {
+	w := httptest.NewRecorder()
+	data := map[string]interface{}{
+		"foo":  "bar",
+		"html": "<b>",
+	}
+	err := (PureJSON{data}).Render(w)
+	assert.NoError(t, err)
+	assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"<b>\"}\n", w.Body.String())
+	assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
+}

+ 3 - 2
render/render_test.go

@@ -52,7 +52,8 @@ func TestRenderMsgPack(t *testing.T) {
 func TestRenderJSON(t *testing.T) {
 	w := httptest.NewRecorder()
 	data := map[string]interface{}{
-		"foo": "bar",
+		"foo":  "bar",
+		"html": "<b>",
 	}
 
 	(JSON{data}).WriteContentType(w)
@@ -61,7 +62,7 @@ func TestRenderJSON(t *testing.T) {
 	err := (JSON{data}).Render(w)
 
 	assert.NoError(t, err)
-	assert.Equal(t, "{\"foo\":\"bar\"}", w.Body.String())
+	assert.Equal(t, "{\"foo\":\"bar\",\"html\":\"\\u003cb\\u003e\"}", w.Body.String())
 	assert.Equal(t, "application/json; charset=utf-8", w.Header().Get("Content-Type"))
 }