@@ -2,149 +2,8 @@ package runtime
22
33import (
44 "io"
5- "net/http"
65)
76
8- const mimeWildcard = "*"
9-
10- var (
11- inboundDefaultMarshaler = new (JSONBuiltin )
12- outboundDefaultMarshaler = new (JSONBuiltin )
13-
14- contentTypeHeader = http .CanonicalHeaderKey ("Content-Type" )
15- )
16-
17- // MarshalerForRequest returns the inbound/outbound marshalers for this request.
18- // It checks the registry on the ServeMux for the MIME type set by the Content-Type header.
19- // If it isn't set (or the request Content-Type is empty), checks for "*".
20- // If that isn't set, uses the ServerMux's InboundMarshaler/OutboundMarshaler.
21- // If there are multiple Content-Type headers set, choose the first one that it can
22- // exactly match in the registry.
23- // Otherwise, it follows the above logic for "*"/InboundMarshaler/OutboundMarshaler.
24- func MarshalerForRequest (mux * ServeMux , r * http.Request ) (inbound Marshaler , outbound Marshaler ) {
25- headerVals := append (append ([]string (nil ), r .Header [contentTypeHeader ]... ), "*" )
26-
27- for _ , val := range headerVals {
28- m := mux .MIMERegistry .lookup (val )
29- if m != nil {
30- if inbound == nil {
31- inbound = m .inbound
32- }
33- if outbound == nil {
34- outbound = m .outbound
35- }
36- }
37- if inbound != nil && outbound != nil {
38- // Got them both, return
39- return inbound , outbound
40- }
41- }
42-
43- if inbound == nil {
44- inbound = mux .InboundMarshaler
45- }
46- if inbound == nil {
47- inbound = inboundDefaultMarshaler
48- }
49-
50- if outbound == nil {
51- outbound = mux .OutboundMarshaler
52- }
53- if outbound == nil {
54- outbound = outboundDefaultMarshaler
55- }
56-
57- return inbound , outbound
58-
59- }
60-
61- // MarshalerMIMERegistry keeps a mapping from MIME types to mimeMarshalers.
62- type MarshalerMIMERegistry struct {
63- mimeMap map [string ]* mimeMarshaler
64- }
65-
66- type mimeMarshaler struct {
67- inbound Marshaler
68- outbound Marshaler
69- }
70-
71- // AddMarshaler adds an inbound and outbund marshaler for a case-sensitive MIME type string ("*" to match any MIME type).
72- // Inbound is the marshaler that is used when marshaling inbound requests from the client.
73- // Outbound is the marshaler that is used when marshaling outbound responses to the client.
74- func (m * MarshalerMIMERegistry ) AddMarshaler (mime string , inbound , outbound Marshaler ) {
75-
76- if len (mime ) == 0 {
77- panic ("Mime can't be an empty string" )
78- }
79-
80- m .mimeMap [mime ] = & mimeMarshaler {
81- inbound : inbound ,
82- outbound : outbound ,
83- }
84-
85- }
86-
87- // AddInboundMarshaler adds an inbound marshaler for a case-sensitive MIME type string ("*" to match any MIME type).
88- // Inbound is the marshaler that is used when marshaling inbound requests from the client.
89- func (m * MarshalerMIMERegistry ) AddInboundMarshaler (mime string , inbound Marshaler ) {
90-
91- if len (mime ) == 0 {
92- panic ("Mime can't be an empty string" )
93- }
94-
95- if _ , ok := m .mimeMap [mime ]; ok {
96- //Already have this mime, just change inbound
97- m .mimeMap [mime ].inbound = inbound
98- } else {
99- m .mimeMap [mime ] = & mimeMarshaler {
100- inbound : inbound ,
101- outbound : nil ,
102- }
103- }
104-
105- }
106-
107- // AddOutboundMarshaler adds an outbund marshaler for a case-sensitive MIME type string ("*" to match any MIME type).
108- // Outbound is the marshaler that is used when marshaling outbound responses to the client.
109- func (m * MarshalerMIMERegistry ) AddOutboundMarshaler (mime string , outbound Marshaler ) {
110- mime = http .CanonicalHeaderKey (mime )
111- if len (mime ) == 0 {
112- panic ("Mime can't be an empty string" )
113- }
114-
115- if _ , ok := m .mimeMap [mime ]; ok {
116- //Already have this mime, just change outbound
117- m .mimeMap [mime ].outbound = outbound
118- } else {
119- m .mimeMap [mime ] = & mimeMarshaler {
120- inbound : nil ,
121- outbound : outbound ,
122- }
123- }
124-
125- }
126-
127- func (m * MarshalerMIMERegistry ) lookup (mime string ) * mimeMarshaler {
128- if m == nil {
129- return nil
130- }
131- return m .mimeMap [mime ]
132- }
133-
134- // NewMarshalerMIMERegistry returns a new registry of marshalers.
135- // It allows for a mapping of case-sensitive Content-Type MIME type string to runtime.Marshaler interfaces.
136- //
137- // For example, you could allow the client to specify the use of the runtime.JSONPb marshaler
138- // with a "applicaton/jsonpb" Content-Type and the use of the runtime.JSONBuiltin marshaler
139- // with a "application/json" Content-Type.
140- // "*" can be used to match any Content-Type.
141- // This can be attached to a ServerMux with the MIMERegistry option.
142- func NewMarshalerMIMERegistry () * MarshalerMIMERegistry {
143- return & MarshalerMIMERegistry {
144- mimeMap : make (map [string ]* mimeMarshaler ),
145- }
146- }
147-
1487// Marshaler defines a conversion between byte sequence and gRPC payloads / fields.
1498type Marshaler interface {
1509 // Marshal marshals "v" into byte sequence.
0 commit comments