56 lines
2.5 KiB
Markdown
56 lines
2.5 KiB
Markdown
---
|
|
name: ws_upgrader
|
|
kind: function
|
|
lang: go
|
|
domain: infra
|
|
version: "1.0.0"
|
|
purity: impure
|
|
signature: "func WSUpgrader(w http.ResponseWriter, r *http.Request, origins []string) (*websocket.Conn, error)"
|
|
description: "Hace el upgrade de una conexion HTTP a WebSocket usando nhooyr.io/websocket. Si origins contiene `*` se acepta cualquier origen (InsecureSkipVerify=true), en caso contrario OriginPatterns valida el header Origin del cliente con filepath.Match. Retorna el *websocket.Conn listo para Read/Write o un error si el handshake falla."
|
|
tags: [websocket, upgrade, http, server, infra, realtime]
|
|
uses_functions: []
|
|
uses_types: []
|
|
returns: []
|
|
returns_optional: false
|
|
error_type: "error_go_core"
|
|
imports: [fmt, net/http, "nhooyr.io/websocket"]
|
|
params:
|
|
- name: w
|
|
desc: "http.ResponseWriter del request entrante. Debe soportar hijack (no envuelto en middlewares que rompan Hijacker)."
|
|
- name: r
|
|
desc: "*http.Request del cliente que pide el upgrade. Debe contener los headers Connection: Upgrade y Upgrade: websocket."
|
|
- name: origins
|
|
desc: "lista de patrones de origen permitidos (filepath.Match). Si contiene `*` se aceptan todos los origenes (modo inseguro, solo dev). Para produccion: lista explicita de hosts (ej: [`example.com`, `app.example.com`])."
|
|
output: "*websocket.Conn listo para Read/Write y error. Si el handshake falla (origen no autorizado, headers invalidos), el writer ya tiene la respuesta de error escrita."
|
|
tested: true
|
|
tests: ["upgradea conexion valida con origen permitido", "rechaza origen no permitido", "acepta cualquier origen con `*`"]
|
|
test_file_path: "functions/infra/ws_test.go"
|
|
file_path: "functions/infra/ws_upgrader.go"
|
|
---
|
|
|
|
## Ejemplo
|
|
|
|
```go
|
|
http.HandleFunc("/ws", func(w http.ResponseWriter, r *http.Request) {
|
|
conn, err := WSUpgrader(w, r, []string{"example.com", "app.example.com"})
|
|
if err != nil {
|
|
return // error ya escrito al writer
|
|
}
|
|
defer conn.Close(websocket.StatusNormalClosure, "")
|
|
|
|
for {
|
|
_, data, err := conn.Read(r.Context())
|
|
if err != nil {
|
|
return
|
|
}
|
|
conn.Write(r.Context(), websocket.MessageText, data) // echo
|
|
}
|
|
})
|
|
```
|
|
|
|
## Notas
|
|
|
|
`nhooyr.io/websocket` exige un patron de origen explicito o `InsecureSkipVerify=true` — no admite `*` como pattern. Esta funcion traduce `["*"]` a InsecureSkipVerify para mantener una API uniforme con CORS.
|
|
|
|
Para produccion: nunca usar `["*"]`, listar hosts explicitos. La validacion protege contra cross-origin WebSocket hijacking (un sitio malicioso abriendo WS al servidor desde el browser de la victima).
|