()
| 859 | } |
| 860 | |
| 861 | func (w *websocket) proxy() ([]*tracer.WebsocketMessage, error) { |
| 862 | defer w.cleanup() |
| 863 | |
| 864 | ctx, cancel := context.WithTimeout(context.Background(), websocketTimeLimit) |
| 865 | defer cancel() |
| 866 | errs := make(chan error, 2) |
| 867 | |
| 868 | readLoop := func(isClient bool) { |
| 869 | var payload []byte |
| 870 | var op byte |
| 871 | var t time.Time |
| 872 | var compressed bool |
| 873 | first := true |
| 874 | |
| 875 | type frameResult struct { |
| 876 | frame *websocketFrame |
| 877 | err error |
| 878 | } |
| 879 | for { |
| 880 | ch := make(chan frameResult, 1) |
| 881 | go func() { |
| 882 | frame, err := w.readFrame(isClient) |
| 883 | select { |
| 884 | case <-ctx.Done(): |
| 885 | case ch <- frameResult{frame, err}: |
| 886 | } |
| 887 | }() |
| 888 | |
| 889 | var frame *websocketFrame |
| 890 | select { |
| 891 | case <-ctx.Done(): |
| 892 | return |
| 893 | case result := <-ch: |
| 894 | if result.err != nil { |
| 895 | errs <- fmt.Errorf("read frame (isClient=%t): %w", isClient, result.err) |
| 896 | return |
| 897 | } |
| 898 | frame = result.frame |
| 899 | } |
| 900 | |
| 901 | switch frame.op { |
| 902 | case wsOpcodeContinuation: |
| 903 | if first { |
| 904 | errs <- fmt.Errorf("unexpected continuation frame (isClient=%t)", isClient) |
| 905 | return |
| 906 | } |
| 907 | payload = append(payload, frame.payload...) |
| 908 | if frame.fin { |
| 909 | if compressed { |
| 910 | var err error |
| 911 | payload, err = w.decompress(payload, isClient) |
| 912 | if err != nil { |
| 913 | errs <- fmt.Errorf("decompress: %w", err) |
| 914 | return |
| 915 | } |
| 916 | } |
| 917 | w.addMessage(op, payload, isClient, t) |
| 918 | payload = nil |
no test coverage detected