github.com/ethersphere/bee/v2@v2.2.0/pkg/p2p/libp2p/stream.go (about) 1 // Copyright 2020 The Swarm Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style 3 // license that can be found in the LICENSE file. 4 5 package libp2p 6 7 import ( 8 "errors" 9 "io" 10 "time" 11 12 "github.com/ethersphere/bee/v2/pkg/p2p" 13 "github.com/libp2p/go-libp2p/core/network" 14 ) 15 16 var ( 17 closeDeadline = 30 * time.Second 18 errExpectedEof = errors.New("read: expected eof") 19 ) 20 var _ p2p.Stream = (*stream)(nil) 21 22 type stream struct { 23 network.Stream 24 headers map[string][]byte 25 responseHeaders map[string][]byte 26 metrics metrics 27 } 28 29 func newStream(s network.Stream, metrics metrics) *stream { 30 return &stream{Stream: s, metrics: metrics} 31 } 32 func (s *stream) Headers() p2p.Headers { 33 return s.headers 34 } 35 36 func (s *stream) ResponseHeaders() p2p.Headers { 37 return s.responseHeaders 38 } 39 40 func (s *stream) Reset() error { 41 defer s.metrics.StreamResetCount.Inc() 42 return s.Stream.Reset() 43 } 44 45 func (s *stream) FullClose() error { 46 defer s.metrics.ClosedStreamCount.Inc() 47 // close the stream to make sure it is gc'd 48 defer s.Close() 49 50 if err := s.CloseWrite(); err != nil { 51 _ = s.Stream.Reset() 52 return err 53 } 54 55 // So we don't wait forever 56 _ = s.SetDeadline(time.Now().Add(closeDeadline)) 57 58 // We *have* to observe the EOF. Otherwise, we leak the stream. 59 // Now, technically, we should do this *before* 60 // returning from SendMessage as the message 61 // hasn't really been sent yet until we see the 62 // EOF but we don't actually *know* what 63 // protocol the other side is speaking. 64 n, err := s.Read([]byte{0}) 65 if n > 0 || err == nil { 66 _ = s.Stream.Reset() 67 return errExpectedEof 68 } 69 if !errors.Is(err, io.EOF) { 70 _ = s.Stream.Reset() 71 return err 72 } 73 return nil 74 }