Комментарии 9
Подскажите, а какой прикладной смысл у Sec-WebSocket-Accept и маскировки блока данных?
Все эти сложности связаны с безопасностью. Чтобы злоумышленники не подделывали запросы, не атаковали прокси-сервера ("cross-protocol attacks", "cache poisoning").
Sec-WebSocket-Accept также позволяет убедиться в том, что сервер действительно поддерживает WebSocket протокол (What is Sec-WebSocket-Key for?).
На самом деле, про Sec-WebSocket-Accept мог бы и догадаться. Но вот с маскировкой — все ещё неясно: почему на стороне сервера этот механизм выглядит опциональным (mask bit), и почему mask не проверяется на пустоту? Разве сервер не должен тут увидеть непорядок и закрыть соединение с ошибкой?
Согласно спецификации сервер должен закрыть соединение с ошибкой если получил незамаскированный фрейм. Например, gorilla/websocket строго этому следует, даже если соединение зашифровано (wss://, WebSocket over SSL/TLS).
В нашем случае мы довольно вольно с этим обращаемся.
Нам не нужно проверять наличие маски, если маска отсутствует, то размер данных не будет соответствовать заявленному или следующий фрейм будет "кривым" и тогда сервер закроет соединение.
Шикарная статья! Спасибо! А можете пример реализации Server Sent Events показать ?
func sseHandler(w http.ResponseWriter, r *http.Request) {
f, ok := w.(http.Flusher)
if !ok {
return
}
w.Header().Set("Content-Type", "text/event-stream")
w.Header().Set("Cache-Control", "no-cache")
w.Header().Set("Connection", "keep-alive")
f.Flush()
for {
_, err := fmt.Fprintf(w, "data: Hello, World!\n\n")
if err != nil {
return
}
f.Flush()
time.Sleep(time.Second * 2)
}
}
Оно же к WS отношения не имеет. Там просто стримится текст в определенном формате
Больше таких статей.
Имплементируем WebSocket протокол на Go