diff --git a/README.md b/README.md index 42d8378..16af0ec 100644 --- a/README.md +++ b/README.md @@ -397,7 +397,7 @@ export interface Hook { } /** - * The DOM management interace. This allows external JS libraries to + * The DOM management interface. This allows external JS libraries to * interop with Live. */ export interface DOM { diff --git a/engine.go b/engine.go index 2d209f0..b5269af 100644 --- a/engine.go +++ b/engine.go @@ -83,8 +83,9 @@ type BaseEngine struct { } // NewBaseEngine creates a new base engine. -func NewBaseEngine(h Handler, configs ...EngineConfig) *BaseEngine { - e := &BaseEngine{ +func NewBaseEngine(h Handler) *BaseEngine { + const maxUploadSize = 100 * 1024 * 1024 + return &BaseEngine{ broadcastLimiter: rate.NewLimiter(rate.Every(time.Millisecond*100), 8), broadcastHandler: func(ctx context.Context, h Engine, msg Event) { h.self(ctx, nil, msg) @@ -94,12 +95,6 @@ func NewBaseEngine(h Handler, configs ...EngineConfig) *BaseEngine { MaxUploadSize: 100 * 1024 * 1024, handler: h, } - for _, conf := range configs { - if err := conf(e); err != nil { - log.Println("warning:", fmt.Errorf("could not apply config to engine: %w", err)) - } - } - return e } func (e *BaseEngine) Handler(hand Handler) { diff --git a/http.go b/http.go index bcca4ca..005d9d1 100644 --- a/http.go +++ b/http.go @@ -12,6 +12,7 @@ import ( "net/http" "os" "path/filepath" + "strings" "time" "github.com/gorilla/sessions" @@ -35,16 +36,33 @@ type HttpSessionStore interface { // HttpEngine serves live for net/http. type HttpEngine struct { - sessionStore HttpSessionStore + acceptOptions *websocket.AcceptOptions + sessionStore HttpSessionStore *BaseEngine } +// WithWebsocketAcceptOptions apply websocket accept options to the HTTP engine. +func WithWebsocketAcceptOptions(options *websocket.AcceptOptions) EngineConfig { + return func(e Engine) error { + if httpEngine, ok := e.(*HttpEngine); ok { + httpEngine.acceptOptions = options + } + return nil + } +} + // NewHttpHandler returns the net/http handler for live. func NewHttpHandler(store HttpSessionStore, handler Handler, configs ...EngineConfig) *HttpEngine { - return &HttpEngine{ + e := &HttpEngine{ sessionStore: store, - BaseEngine: NewBaseEngine(handler, configs...), + BaseEngine: NewBaseEngine(handler), } + for _, conf := range configs { + if err := conf(e); err != nil { + log.Println("warning:", fmt.Errorf("could not apply config to engine: %w", err)) + } + } + return e } // ServeHTTP serves this handler. @@ -267,7 +285,16 @@ func (h *HttpEngine) serveWS(ctx context.Context, w http.ResponseWriter, r *http return } - c, err := websocket.Accept(w, r, nil) + // https://github.com/nhooyr/websocket/issues/218 + // https://github.com/gorilla/websocket/issues/731 + if strings.Contains(r.UserAgent(), "Safari") { + if h.acceptOptions == nil { + h.acceptOptions = &websocket.AcceptOptions{} + } + h.acceptOptions.CompressionMode = websocket.CompressionDisabled + } + + c, err := websocket.Accept(w, r, h.acceptOptions) if err != nil { h.Error()(ctx, err) return