github.com/alejandroesc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy2/frames/goaway.go (about)

     1  // Copyright 2014 Jamie Hall. 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 frames
     6  
     7  import (
     8  	"bytes"
     9  	"fmt"
    10  	"io"
    11  
    12  	"github.com/SlyMarbo/spdy/common"
    13  )
    14  
    15  type GOAWAY struct {
    16  	LastGoodStreamID common.StreamID
    17  }
    18  
    19  func (frame *GOAWAY) Compress(comp common.Compressor) error {
    20  	return nil
    21  }
    22  
    23  func (frame *GOAWAY) Decompress(decomp common.Decompressor) error {
    24  	return nil
    25  }
    26  
    27  func (frame *GOAWAY) Name() string {
    28  	return "GOAWAY"
    29  }
    30  
    31  func (frame *GOAWAY) ReadFrom(reader io.Reader) (int64, error) {
    32  	c := common.ReadCounter{R: reader}
    33  	data, err := common.ReadExactly(&c, 12)
    34  	if err != nil {
    35  		return c.N, err
    36  	}
    37  
    38  	err = controlFrameCommonProcessing(data[:5], _GOAWAY, 0)
    39  	if err != nil {
    40  		return c.N, err
    41  	}
    42  
    43  	// Get and check length.
    44  	length := int(common.BytesToUint24(data[5:8]))
    45  	if length != 4 {
    46  		return c.N, common.IncorrectDataLength(length, 4)
    47  	}
    48  
    49  	frame.LastGoodStreamID = common.StreamID(common.BytesToUint32(data[8:12]))
    50  
    51  	if !frame.LastGoodStreamID.Valid() {
    52  		return c.N, common.StreamIdTooLarge
    53  	}
    54  
    55  	return c.N, nil
    56  }
    57  
    58  func (frame *GOAWAY) String() string {
    59  	buf := new(bytes.Buffer)
    60  
    61  	buf.WriteString("GOAWAY {\n\t")
    62  	buf.WriteString(fmt.Sprintf("Version:              2\n\t"))
    63  	buf.WriteString(fmt.Sprintf("Last good stream ID:  %d\n}\n", frame.LastGoodStreamID))
    64  
    65  	return buf.String()
    66  }
    67  
    68  func (frame *GOAWAY) WriteTo(writer io.Writer) (int64, error) {
    69  	c := common.WriteCounter{W: writer}
    70  	if !frame.LastGoodStreamID.Valid() {
    71  		return c.N, common.StreamIdTooLarge
    72  	}
    73  
    74  	out := make([]byte, 12)
    75  
    76  	out[0] = 128                          // Control bit and Version
    77  	out[1] = 2                            // Version
    78  	out[2] = 0                            // Type
    79  	out[3] = 7                            // Type
    80  	out[4] = 0                            // Flags
    81  	out[5] = 0                            // Length
    82  	out[6] = 0                            // Length
    83  	out[7] = 4                            // Length
    84  	out[8] = frame.LastGoodStreamID.B1()  // Last Good Stream ID
    85  	out[9] = frame.LastGoodStreamID.B2()  // Last Good Stream ID
    86  	out[10] = frame.LastGoodStreamID.B3() // Last Good Stream ID
    87  	out[11] = frame.LastGoodStreamID.B4() // Last Good Stream ID
    88  
    89  	err := common.WriteExactly(&c, out)
    90  	if err != nil {
    91  		return c.N, err
    92  	}
    93  
    94  	return c.N, nil
    95  }