Upgrade upgrades the HTTP server connection to the WebSocket protocol. The responseHeader is included in the response to the client's upgrade request. Use the responseHeader to specify cookies (Set-Cookie). To specify subprotocols supported by the server, set Upgrader.Subprotocols directly. If the
(w http.ResponseWriter, r *http.Request, responseHeader http.Header)
| 123 | // If the upgrade fails, then Upgrade replies to the client with an HTTP error |
| 124 | // response. |
| 125 | func (u *Upgrader) Upgrade(w http.ResponseWriter, r *http.Request, responseHeader http.Header) (*Conn, error) { |
| 126 | const badHandshake = "websocket: the client is not using the websocket protocol: " |
| 127 | |
| 128 | if !tokenListContainsValue(r.Header, "Connection", "upgrade") { |
| 129 | return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'upgrade' token not found in 'Connection' header") |
| 130 | } |
| 131 | |
| 132 | if !tokenListContainsValue(r.Header, "Upgrade", "websocket") { |
| 133 | return u.returnError(w, r, http.StatusBadRequest, badHandshake+"'websocket' token not found in 'Upgrade' header") |
| 134 | } |
| 135 | |
| 136 | if r.Method != http.MethodGet { |
| 137 | return u.returnError(w, r, http.StatusMethodNotAllowed, badHandshake+"request method is not GET") |
| 138 | } |
| 139 | |
| 140 | if !tokenListContainsValue(r.Header, "Sec-Websocket-Version", "13") { |
| 141 | return u.returnError(w, r, http.StatusBadRequest, "websocket: unsupported version: 13 not found in 'Sec-Websocket-Version' header") |
| 142 | } |
| 143 | |
| 144 | if _, ok := responseHeader["Sec-Websocket-Extensions"]; ok { |
| 145 | return u.returnError(w, r, http.StatusInternalServerError, "websocket: application specific 'Sec-WebSocket-Extensions' headers are unsupported") |
| 146 | } |
| 147 | |
| 148 | checkOrigin := u.CheckOrigin |
| 149 | if checkOrigin == nil { |
| 150 | checkOrigin = checkSameOrigin |
| 151 | } |
| 152 | if !checkOrigin(r) { |
| 153 | return u.returnError(w, r, http.StatusForbidden, "websocket: request origin not allowed by Upgrader.CheckOrigin") |
| 154 | } |
| 155 | |
| 156 | challengeKey := r.Header.Get("Sec-Websocket-Key") |
| 157 | if !isValidChallengeKey(challengeKey) { |
| 158 | return u.returnError(w, r, http.StatusBadRequest, "websocket: not a websocket handshake: 'Sec-WebSocket-Key' header must be Base64 encoded value of 16-byte in length") |
| 159 | } |
| 160 | |
| 161 | subprotocol := u.selectSubprotocol(r, responseHeader) |
| 162 | |
| 163 | // Negotiate PMCE |
| 164 | var compress bool |
| 165 | if u.EnableCompression { |
| 166 | for _, ext := range parseExtensions(r.Header) { |
| 167 | if ext[""] != "permessage-deflate" { |
| 168 | continue |
| 169 | } |
| 170 | compress = true |
| 171 | break |
| 172 | } |
| 173 | } |
| 174 | |
| 175 | h, ok := w.(http.Hijacker) |
| 176 | if !ok { |
| 177 | return u.returnError(w, r, http.StatusInternalServerError, "websocket: response does not implement http.Hijacker") |
| 178 | } |
| 179 | var brw *bufio.ReadWriter |
| 180 | netConn, brw, err := h.Hijack() |
| 181 | if err != nil { |
| 182 | return u.returnError(w, r, http.StatusInternalServerError, err.Error()) |