@@ -7,6 +7,7 @@ package websocket
7
7
import (
8
8
"bufio"
9
9
"errors"
10
+ "fmt"
10
11
"io"
11
12
"net/http"
12
13
"net/url"
@@ -44,6 +45,7 @@ type Upgrader struct {
44
45
// WriteBufferSize.
45
46
WriteBufferPool BufferPool
46
47
48
+ // Subprotocols have lower priority than NegotiateSuprotocol.
47
49
// Subprotocols specifies the server's supported protocols in order of
48
50
// preference. If this field is not nil, then the Upgrade method negotiates a
49
51
// subprotocol by selecting the first match in this list with a protocol
@@ -70,6 +72,13 @@ type Upgrader struct {
70
72
// guarantee that compression will be supported. Currently only "no context
71
73
// takeover" modes are supported.
72
74
EnableCompression bool
75
+ // NegotiateSubprotocol has higher priority than Subprotocols.
76
+ // NegotiateSubprotocol returns the negotiated subprotocol for the handshake
77
+ // request. If the returned string is "", then the the Sec-Websocket-Protocol header
78
+ // is not included in the handshake response. If the function returns an error, then
79
+ // Upgrade responds to the client with http.StatusBadRequest.
80
+ // If this function is not nil, then the Upgrader.Subportocols field is ignored.
81
+ NegotiateSubprotocol func (r * http.Request ) (string , error )
73
82
}
74
83
75
84
func (u * Upgrader ) returnError (w http.ResponseWriter , r * http.Request , status int , reason string ) (* Conn , error ) {
@@ -96,7 +105,7 @@ func checkSameOrigin(r *http.Request) bool {
96
105
return equalASCIIFold (u .Host , r .Host )
97
106
}
98
107
99
- func (u * Upgrader ) selectSubprotocol (r * http.Request , responseHeader http. Header ) string {
108
+ func (u * Upgrader ) selectSubprotocol (r * http.Request ) string {
100
109
if u .Subprotocols != nil {
101
110
clientProtocols := Subprotocols (r )
102
111
for _ , serverProtocol := range u .Subprotocols {
@@ -106,20 +115,21 @@ func (u *Upgrader) selectSubprotocol(r *http.Request, responseHeader http.Header
106
115
}
107
116
}
108
117
}
109
- } else if responseHeader != nil {
110
- return responseHeader .Get ("Sec-Websocket-Protocol" )
111
118
}
112
119
return ""
113
120
}
114
121
115
122
// Upgrade upgrades the HTTP server connection to the WebSocket protocol.
116
123
//
117
124
// The responseHeader is included in the response to the client's upgrade
118
- // request. Use the responseHeader to specify cookies (Set-Cookie) and the
119
- // application negotiated subprotocol (Sec-WebSocket-Protocol).
125
+ // request. Use the responseHeader to specify cookies (Set-Cookie).
120
126
//
121
127
// If the upgrade fails, then Upgrade replies to the client with an HTTP error
122
128
// response.
129
+ //
130
+ // The responseHeader does not support negotiated subprotocol(Sec-Websocket-Protocol)
131
+ // IF necessary,please use Upgrader.NegotiateSubprotocol and Upgrader.Subprotocols
132
+ // Use the method to view the Upgrader struct.
123
133
func (u * Upgrader ) Upgrade (w http.ResponseWriter , r * http.Request , responseHeader http.Header ) (* Conn , error ) {
124
134
const badHandshake = "websocket: the client is not using the websocket protocol: "
125
135
@@ -156,7 +166,16 @@ func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeade
156
166
return u .returnError (w , r , http .StatusBadRequest , "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header is missing or blank" )
157
167
}
158
168
159
- subprotocol := u .selectSubprotocol (r , responseHeader )
169
+ subprotocol := ""
170
+ if u .NegotiateSubprotocol != nil {
171
+ str , err := u .NegotiateSubprotocol (r )
172
+ if err != nil {
173
+ return u .returnError (w , r , http .StatusBadRequest , fmt .Sprintf ("websocket:handshake negotiation protocol error:%s" , err ))
174
+ }
175
+ subprotocol = str
176
+ } else {
177
+ subprotocol = u .selectSubprotocol (r )
178
+ }
160
179
161
180
// Negotiate PMCE
162
181
var compress bool
0 commit comments