forked from emicklei/go-restful
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathresponse.go
121 lines (110 loc) · 3.63 KB
/
response.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
package restful
import (
"encoding/json"
"encoding/xml"
"io"
"net/http"
"strings"
)
// If Accept header matching fails, fall back to this type, otherwise
// a "406: Not Acceptable" response is returned.
// Valid values are restful.MIME_JSON and restful.MIME_XML
// Example:
// restful.DefaultResponseMimeType = restful.MIME_JSON
var DefaultResponseMimeType string
// Response is a wrapper on the actual http ResponseWriter
// It provides several convenience methods to prepare and write response content.
type Response struct {
http.ResponseWriter
accept string // content-types what the Http Request says it want to receive
produces []string // content-types what the Route says it can produce
}
// DEPRECATED, use r.WriteHeader(http.StatusInternalServerError)
func (r Response) InternalServerError() Response {
r.WriteHeader(http.StatusInternalServerError)
return r
}
// AddHeader is a shortcut for .Header().Add(header,value)
func (r Response) AddHeader(header string, value string) Response {
r.Header().Add(header, value)
return r
}
// WriteEntity marshals the value using the representation denoted by the Accept Header (XML or JSON)
// If no Accept header is specified (or */*) then return the Content-Type as specified by the first in the Route.Produces.
// If an Accept header is specified then return the Content-Type as specified by the first in the Route.Produces that is matched with the Accept header.
// Current implementation ignores any q-parameters in the Accept Header.
func (r Response) WriteEntity(value interface{}) Response {
if "" == r.accept || "*/*" == r.accept {
for _, each := range r.produces {
if MIME_JSON == each {
r.WriteAsJson(value)
return r
}
if MIME_XML == each {
r.WriteAsXml(value)
return r
}
}
} else { // Accept header specified ; scan for each element in Route.Produces
for _, each := range r.produces {
if strings.Index(r.accept, each) != -1 {
if MIME_JSON == each {
r.WriteAsJson(value)
return r
}
if MIME_XML == each {
r.WriteAsXml(value)
return r
}
}
}
}
if DefaultResponseMimeType == MIME_JSON {
r.WriteAsJson(value)
} else if DefaultResponseMimeType == MIME_XML {
r.WriteAsXml(value)
} else {
r.WriteHeader(http.StatusNotAcceptable)
io.WriteString(r, "406: Not Acceptable")
}
return r
}
// WriteAsXml is a convenience method for writing a value in xml (requires Xml tags on the value)
func (r Response) WriteAsXml(value interface{}) Response {
output, err := xml.MarshalIndent(value, " ", " ")
if err != nil {
r.WriteError(http.StatusInternalServerError, err)
} else {
r.Header().Set(HEADER_ContentType, MIME_XML)
io.WriteString(r, xml.Header)
r.Write(output)
}
return r
}
// WriteAsJson is a convenience method for writing a value in json
func (r Response) WriteAsJson(value interface{}) Response {
output, err := json.MarshalIndent(value, " ", " ")
if err != nil {
r.WriteError(http.StatusInternalServerError, err)
} else {
r.Header().Set(HEADER_ContentType, MIME_JSON)
r.Write(output)
}
return r
}
// DEPRECATED; use WriteErrorString(status,reason)
func (r Response) WriteError(httpStatus int, err error) Response {
return r.WriteErrorString(httpStatus, err.Error())
}
// WriteServiceError is a convenience method for a responding with a ServiceError and a status
func (r Response) WriteServiceError(httpStatus int, err ServiceError) Response {
r.WriteHeader(httpStatus)
r.WriteEntity(err)
return r
}
// WriteErrorString is a convenience method for an error status with the actual error
func (r Response) WriteErrorString(status int, err string) Response {
r.WriteHeader(status)
io.WriteString(r, err)
return r
}