Example #1
0
func (s *Stream) resetWith(errorCode frame.ErrorCode, resetErr error) {
	// only ever send one reset
	if !atomic.CompareAndSwapUint32(&s.sentRst, 0, 1) {
		return
	}

	// close the stream
	s.closeWithAndRemoveLater(resetErr)

	// make the reset frame
	rst := frame.NewWStreamRst()
	if err := rst.Set(s.id, errorCode); err != nil {
		s.die(frame.InternalError, err)
	}

	// need write lock to make sure no data frames get sent after we send the reset
	s.writer.Lock()

	// send it
	if err := s.session.writeFrame(rst, zeroTime); err != nil {
		s.writer.Unlock()
		s.die(frame.InternalError, err)
	}

	s.writer.Unlock()
}
Example #2
0
func TestDataAfterRst(t *testing.T) {
	local, remote := newFakeConnPair()

	_ = NewSession(local, NewStream, false, []Extension{})
	trans := frame.NewBasicTransport(remote)

	// make sure that we get an RST STREAM_CLOSED
	done := make(chan int)
	go func() {
		defer func() { done <- 1 }()

		f, err := trans.ReadFrame()
		if err != nil {
			t.Errorf("Failed to read frame sent from session: %v", err)
			return
		}

		fr, ok := f.(*frame.RStreamRst)
		if !ok {
			t.Errorf("Frame is not STREAM_RST: %v", f)
			return
		}

		if fr.ErrorCode() != frame.StreamClosed {
			t.Errorf("Error code on STREAM_RST is not STREAM_CLOSED. Got %d, expected %d", fr.ErrorCode(), frame.StreamClosed)
			return
		}
	}()

	fSyn := frame.NewWStreamSyn()
	if err := fSyn.Set(301, 0, 0, false); err != nil {
		t.Fatalf("Failed to make syn frame: %v", err)
	}

	if err := trans.WriteFrame(fSyn); err != nil {
		t.Fatalf("Failed to send syn: %v", err)
	}

	fRst := frame.NewWStreamRst()
	if err := fRst.Set(301, frame.Cancel); err != nil {
		t.Fatal("Failed to make rst frame: %v", err)
	}

	if err := trans.WriteFrame(fRst); err != nil {
		t.Fatalf("Failed to write rst frame: %v", err)
	}

	fData := frame.NewWStreamData()
	if err := fData.Set(301, []byte{0xa, 0xFF}, false); err != nil {
		t.Fatalf("Failed to set data frame")
	}

	trans.WriteFrame(fData)

	<-done
}