| 555 | } |
| 556 | |
| 557 | func newWebsocket(cli, srv io.Reader, resp *http.Response, isOutgoing bool) (*websocket, error) { |
| 558 | w := &websocket{ |
| 559 | cli: cli, |
| 560 | srv: srv, |
| 561 | isOutgoing: isOutgoing, |
| 562 | } |
| 563 | w.n.Store(uint64(tracer.PayloadLimitBytes)) |
| 564 | |
| 565 | h := resp.Header.Get("sec-websocket-extensions") |
| 566 | exts := strings.SplitSeq(h, ",") |
| 567 | for ext := range exts { |
| 568 | ext = strings.TrimSpace(ext) |
| 569 | ext, found := strings.CutPrefix(ext, "permessage-deflate") |
| 570 | if !found { |
| 571 | continue |
| 572 | } |
| 573 | |
| 574 | options := strings.SplitSeq(ext, ";") |
| 575 | for option := range options { |
| 576 | option = strings.TrimSpace(option) |
| 577 | switch { |
| 578 | case option == "client_no_context_takeover": |
| 579 | w.clientNoContextTakeover = true |
| 580 | case option == "server_no_context_takeover": |
| 581 | w.serverNoContextTakeover = true |
| 582 | case strings.HasPrefix(option, "client_max_window_bits="): |
| 583 | val := strings.TrimPrefix(option, "client_max_window_bits=") |
| 584 | n, err := strconv.Atoi(val) |
| 585 | if err != nil { |
| 586 | continue |
| 587 | } |
| 588 | w.clientMaxWindowBits = n |
| 589 | case strings.HasPrefix(option, "server_max_window_bits="): |
| 590 | val := strings.TrimPrefix(option, "server_max_window_bits=") |
| 591 | n, err := strconv.Atoi(val) |
| 592 | if err != nil { |
| 593 | continue |
| 594 | } |
| 595 | w.serverMaxWindowBits = n |
| 596 | } |
| 597 | } |
| 598 | } |
| 599 | |
| 600 | // ref: https://datatracker.ietf.org/doc/html/rfc7692#section-7.1.2.1 |
| 601 | // |
| 602 | // "...Absence of this parameter in an extension negotiation offer indicates |
| 603 | // that the client can receive messages compressed using an LZ77 sliding |
| 604 | // window of up to 32,768 bytes." (32768 is 1 << 15) |
| 605 | if w.clientMaxWindowBits == 0 { |
| 606 | w.clientMaxWindowBits = 15 |
| 607 | } |
| 608 | if w.serverMaxWindowBits == 0 { |
| 609 | w.serverMaxWindowBits = 15 |
| 610 | } |
| 611 | |
| 612 | // ref: https://datatracker.ietf.org/doc/html/rfc7692#section-7.1.2.1 |
| 613 | // |
| 614 | // "A client MAY include the "server_max_window_bits" extension parameter |