61 lines
1.3 KiB
Go
61 lines
1.3 KiB
Go
|
package response
|
||
|
|
||
|
import (
|
||
|
"fmt"
|
||
|
"io"
|
||
|
"encoding/base64"
|
||
|
"crypto/sha1"
|
||
|
)
|
||
|
|
||
|
|
||
|
|
||
|
// SetStatusCode sets the status code
|
||
|
func (r *T) SetStatusCode(sc StatusCode) {
|
||
|
r.code = sc
|
||
|
}
|
||
|
|
||
|
// SetProtocols sets the protocols
|
||
|
func (r *T) SetProtocol(p []byte) {
|
||
|
r.protocol = p
|
||
|
}
|
||
|
|
||
|
// ProcessKey processes the accept token according
|
||
|
// to the rfc from the Sec-WebSocket-Key
|
||
|
func (r *T) ProcessKey(k []byte) {
|
||
|
|
||
|
/* (1) Concat with constant salt */
|
||
|
mix := append(k, WSSalt...)
|
||
|
|
||
|
/* (2) Hash with sha1 algorithm */
|
||
|
digest := sha1.Sum(mix)
|
||
|
|
||
|
/* (3) Base64 encode it */
|
||
|
r.accept = []byte( base64.StdEncoding.EncodeToString( digest[:sha1.Size] ) )
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
// Send sends the response through an io.Writer
|
||
|
// typically a socket
|
||
|
func (r T) Send(w io.Writer) (int, error) {
|
||
|
|
||
|
/* (1) Build response line */
|
||
|
responseLine := fmt.Sprintf("HTTP/%s %d %s\r\n", HttpVersion, r.code, r.code.Explicit())
|
||
|
|
||
|
/* (2) Build headers */
|
||
|
optionalProtocol := ""
|
||
|
if len(r.protocol) > 0 {
|
||
|
optionalProtocol = fmt.Sprintf("Sec-WebSocket-Protocol: %s\r\n", r.protocol)
|
||
|
}
|
||
|
|
||
|
headers := fmt.Sprintf("Upgrade: websocket\t\nConnection: Upgrade\r\nSec-WebSocket-Accept: %s\r\nSec-WebSocket-Version: %d\r\n%s", r.accept, WSVersion, optionalProtocol)
|
||
|
|
||
|
/* (3) Build all */
|
||
|
raw := []byte(fmt.Sprintf("%s%s\r\n", responseLine, headers))
|
||
|
|
||
|
/* (4) Write */
|
||
|
written, err := w.Write(raw)
|
||
|
|
||
|
return written, err
|
||
|
|
||
|
}
|