mirror of
https://github.com/gin-gonic/gin.git
synced 2026-01-07 23:03:11 +08:00
Merge 4a1434ad5e5d05845e6331caa25a240f45c04e9f into d5b353c5d5a560322e6d96121c814115562501f7
This commit is contained in:
commit
9fbe44d98f
40
context.go
40
context.go
@ -422,47 +422,43 @@ func (c *Context) Cookie(name string) (string, error) {
|
||||
return val, nil
|
||||
}
|
||||
|
||||
func (c *Context) Render(code int, r render.Render) {
|
||||
func (c *Context) Render(code int, r render.Render) error {
|
||||
c.Status(code)
|
||||
if err := r.Render(c.Writer); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return r.Render(c.Writer)
|
||||
}
|
||||
|
||||
// HTML renders the HTTP template specified by its file name.
|
||||
// It also updates the HTTP code and sets the Content-Type as "text/html".
|
||||
// See http://golang.org/doc/articles/wiki/
|
||||
func (c *Context) HTML(code int, name string, obj interface{}) {
|
||||
func (c *Context) HTML(code int, name string, obj interface{}) error {
|
||||
instance := c.engine.HTMLRender.Instance(name, obj)
|
||||
c.Render(code, instance)
|
||||
return c.Render(code, instance)
|
||||
}
|
||||
|
||||
// IndentedJSON serializes the given struct as pretty JSON (indented + endlines) into the response body.
|
||||
// It also sets the Content-Type as "application/json".
|
||||
// WARNING: we recommend to use this only for development propuses since printing pretty JSON is
|
||||
// more CPU and bandwidth consuming. Use Context.JSON() instead.
|
||||
func (c *Context) IndentedJSON(code int, obj interface{}) {
|
||||
c.Render(code, render.IndentedJSON{Data: obj})
|
||||
func (c *Context) IndentedJSON(code int, obj interface{}) error {
|
||||
return c.Render(code, render.IndentedJSON{Data: obj})
|
||||
}
|
||||
|
||||
// JSON serializes the given struct as JSON into the response body.
|
||||
// It also sets the Content-Type as "application/json".
|
||||
func (c *Context) JSON(code int, obj interface{}) {
|
||||
func (c *Context) JSON(code int, obj interface{}) error {
|
||||
c.Status(code)
|
||||
if err := render.WriteJSON(c.Writer, obj); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
return render.WriteJSON(c.Writer, obj)
|
||||
}
|
||||
|
||||
// XML serializes the given struct as XML into the response body.
|
||||
// It also sets the Content-Type as "application/xml".
|
||||
func (c *Context) XML(code int, obj interface{}) {
|
||||
c.Render(code, render.XML{Data: obj})
|
||||
func (c *Context) XML(code int, obj interface{}) error {
|
||||
return c.Render(code, render.XML{Data: obj})
|
||||
}
|
||||
|
||||
// YAML serializes the given struct as YAML into the response body.
|
||||
func (c *Context) YAML(code int, obj interface{}) {
|
||||
c.Render(code, render.YAML{Data: obj})
|
||||
func (c *Context) YAML(code int, obj interface{}) error {
|
||||
return c.Render(code, render.YAML{Data: obj})
|
||||
}
|
||||
|
||||
// String writes the given string into the response body.
|
||||
@ -472,8 +468,8 @@ func (c *Context) String(code int, format string, values ...interface{}) {
|
||||
}
|
||||
|
||||
// Redirect returns a HTTP redirect to the specific location.
|
||||
func (c *Context) Redirect(code int, location string) {
|
||||
c.Render(-1, render.Redirect{
|
||||
func (c *Context) Redirect(code int, location string) error {
|
||||
return c.Render(-1, render.Redirect{
|
||||
Code: code,
|
||||
Location: location,
|
||||
Request: c.Request,
|
||||
@ -481,8 +477,8 @@ func (c *Context) Redirect(code int, location string) {
|
||||
}
|
||||
|
||||
// Data writes some data into the body stream and updates the HTTP code.
|
||||
func (c *Context) Data(code int, contentType string, data []byte) {
|
||||
c.Render(code, render.Data{
|
||||
func (c *Context) Data(code int, contentType string, data []byte) error {
|
||||
return c.Render(code, render.Data{
|
||||
ContentType: contentType,
|
||||
Data: data,
|
||||
})
|
||||
@ -494,8 +490,8 @@ func (c *Context) File(filepath string) {
|
||||
}
|
||||
|
||||
// SSEvent writes a Server-Sent Event into the body stream.
|
||||
func (c *Context) SSEvent(name string, message interface{}) {
|
||||
c.Render(-1, sse.Event{
|
||||
func (c *Context) SSEvent(name string, message interface{}) error {
|
||||
return c.Render(-1, sse.Event{
|
||||
Event: name,
|
||||
Data: message,
|
||||
})
|
||||
|
||||
@ -351,8 +351,9 @@ func TestContextGetCookie(t *testing.T) {
|
||||
// and Content-Type is set to application/json
|
||||
func TestContextRenderJSON(t *testing.T) {
|
||||
c, w, _ := CreateTestContext()
|
||||
c.JSON(201, H{"foo": "bar"})
|
||||
e := c.JSON(201, H{"foo": "bar"})
|
||||
|
||||
assert.NoError(t, e)
|
||||
assert.Equal(t, w.Code, 201)
|
||||
assert.Equal(t, w.Body.String(), "{\"foo\":\"bar\"}\n")
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "application/json; charset=utf-8")
|
||||
@ -363,8 +364,9 @@ func TestContextRenderJSON(t *testing.T) {
|
||||
func TestContextRenderAPIJSON(t *testing.T) {
|
||||
c, w, _ := CreateTestContext()
|
||||
c.Header("Content-Type", "application/vnd.api+json")
|
||||
c.JSON(201, H{"foo": "bar"})
|
||||
e := c.JSON(201, H{"foo": "bar"})
|
||||
|
||||
assert.NoError(t, e)
|
||||
assert.Equal(t, w.Code, 201)
|
||||
assert.Equal(t, w.Body.String(), "{\"foo\":\"bar\"}\n")
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "application/vnd.api+json")
|
||||
@ -374,8 +376,9 @@ func TestContextRenderAPIJSON(t *testing.T) {
|
||||
// and Content-Type is set to application/json
|
||||
func TestContextRenderIndentedJSON(t *testing.T) {
|
||||
c, w, _ := CreateTestContext()
|
||||
c.IndentedJSON(201, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
||||
err := c.IndentedJSON(201, H{"foo": "bar", "bar": "foo", "nested": H{"foo": "bar"}})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, w.Code, 201)
|
||||
assert.Equal(t, w.Body.String(), "{\n \"bar\": \"foo\",\n \"foo\": \"bar\",\n \"nested\": {\n \"foo\": \"bar\"\n }\n}")
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "application/json; charset=utf-8")
|
||||
@ -388,8 +391,9 @@ func TestContextRenderHTML(t *testing.T) {
|
||||
templ := template.Must(template.New("t").Parse(`Hello {{.name}}`))
|
||||
router.SetHTMLTemplate(templ)
|
||||
|
||||
c.HTML(201, "t", H{"name": "alexandernyquist"})
|
||||
err := c.HTML(201, "t", H{"name": "alexandernyquist"})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, w.Code, 201)
|
||||
assert.Equal(t, w.Body.String(), "Hello alexandernyquist")
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "text/html; charset=utf-8")
|
||||
@ -399,8 +403,9 @@ func TestContextRenderHTML(t *testing.T) {
|
||||
// and Content-Type is set to application/xml
|
||||
func TestContextRenderXML(t *testing.T) {
|
||||
c, w, _ := CreateTestContext()
|
||||
c.XML(201, H{"foo": "bar"})
|
||||
err := c.XML(201, H{"foo": "bar"})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, w.Code, 201)
|
||||
assert.Equal(t, w.Body.String(), "<map><foo>bar</foo></map>")
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "application/xml; charset=utf-8")
|
||||
@ -433,8 +438,9 @@ func TestContextRenderHTMLString(t *testing.T) {
|
||||
// with specified MIME type
|
||||
func TestContextRenderData(t *testing.T) {
|
||||
c, w, _ := CreateTestContext()
|
||||
c.Data(201, "text/csv", []byte(`foo,bar`))
|
||||
err := c.Data(201, "text/csv", []byte(`foo,bar`))
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, w.Code, 201)
|
||||
assert.Equal(t, w.Body.String(), "foo,bar")
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "text/csv")
|
||||
@ -469,8 +475,9 @@ func TestContextRenderFile(t *testing.T) {
|
||||
// and Content-Type is set to application/x-yaml
|
||||
func TestContextRenderYAML(t *testing.T) {
|
||||
c, w, _ := CreateTestContext()
|
||||
c.YAML(201, H{"foo": "bar"})
|
||||
err := c.YAML(201, H{"foo": "bar"})
|
||||
|
||||
assert.NoError(t, err)
|
||||
assert.Equal(t, w.Code, 201)
|
||||
assert.Equal(t, w.Body.String(), "foo: bar\n")
|
||||
assert.Equal(t, w.HeaderMap.Get("Content-Type"), "application/x-yaml; charset=utf-8")
|
||||
@ -496,10 +503,12 @@ func TestContextHeaders(t *testing.T) {
|
||||
func TestContextRenderRedirectWithRelativePath(t *testing.T) {
|
||||
c, w, _ := CreateTestContext()
|
||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||
assert.Panics(t, func() { c.Redirect(299, "/new_path") })
|
||||
assert.Panics(t, func() { c.Redirect(309, "/new_path") })
|
||||
assert.Error(t, c.Redirect(299, "/new_path"))
|
||||
assert.Error(t, c.Redirect(309, "/new_path"))
|
||||
|
||||
err := c.Redirect(301, "/path")
|
||||
assert.NoError(t, err)
|
||||
|
||||
c.Redirect(301, "/path")
|
||||
c.Writer.WriteHeaderNow()
|
||||
assert.Equal(t, w.Code, 301)
|
||||
assert.Equal(t, w.Header().Get("Location"), "/path")
|
||||
@ -528,12 +537,12 @@ func TestContextRenderRedirectWith201(t *testing.T) {
|
||||
func TestContextRenderRedirectAll(t *testing.T) {
|
||||
c, _, _ := CreateTestContext()
|
||||
c.Request, _ = http.NewRequest("POST", "http://example.com", nil)
|
||||
assert.Panics(t, func() { c.Redirect(200, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(202, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(299, "/resource") })
|
||||
assert.Panics(t, func() { c.Redirect(309, "/resource") })
|
||||
assert.NotPanics(t, func() { c.Redirect(300, "/resource") })
|
||||
assert.NotPanics(t, func() { c.Redirect(308, "/resource") })
|
||||
assert.Error(t, c.Redirect(200, "/resource"))
|
||||
assert.Error(t, c.Redirect(202, "/resource"))
|
||||
assert.Error(t, c.Redirect(299, "/resource"))
|
||||
assert.Error(t, c.Redirect(309, "/resource"))
|
||||
assert.NoError(t, c.Redirect(300, "/resource"))
|
||||
assert.NoError(t, c.Redirect(308, "/resource"))
|
||||
}
|
||||
|
||||
func TestContextNegotiationFormat(t *testing.T) {
|
||||
|
||||
@ -5,6 +5,7 @@
|
||||
package render
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"net/http"
|
||||
)
|
||||
@ -17,7 +18,7 @@ type Redirect struct {
|
||||
|
||||
func (r Redirect) Render(w http.ResponseWriter) error {
|
||||
if (r.Code < 300 || r.Code > 308) && r.Code != 201 {
|
||||
panic(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
|
||||
return errors.New(fmt.Sprintf("Cannot redirect with status code %d", r.Code))
|
||||
}
|
||||
http.Redirect(w, r.Request, r.Location, r.Code)
|
||||
return nil
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user