github.com/alejandroesc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy3/frames/window_update.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  	"errors"
    10  	"fmt"
    11  	"io"
    12  
    13  	"github.com/SlyMarbo/spdy/common"
    14  )
    15  
    16  type WINDOW_UPDATE struct {
    17  	StreamID        common.StreamID
    18  	DeltaWindowSize uint32
    19  	subversion      int
    20  }
    21  
    22  func (frame *WINDOW_UPDATE) Compress(comp common.Compressor) error {
    23  	return nil
    24  }
    25  
    26  func (frame *WINDOW_UPDATE) Decompress(decomp common.Decompressor) error {
    27  	return nil
    28  }
    29  
    30  func (frame *WINDOW_UPDATE) Name() string {
    31  	return "WINDOW_UPDATE"
    32  }
    33  
    34  func (frame *WINDOW_UPDATE) ReadFrom(reader io.Reader) (int64, error) {
    35  	c := common.ReadCounter{R: reader}
    36  	data, err := common.ReadExactly(&c, 16)
    37  	if err != nil {
    38  		return c.N, err
    39  	}
    40  
    41  	err = controlFrameCommonProcessing(data[:5], _WINDOW_UPDATE, 0)
    42  	if err != nil {
    43  		return c.N, err
    44  	}
    45  
    46  	// Get and check length.
    47  	length := int(common.BytesToUint24(data[5:8]))
    48  	if length != 8 {
    49  		return c.N, common.IncorrectDataLength(length, 8)
    50  	}
    51  
    52  	frame.StreamID = common.StreamID(common.BytesToUint32(data[8:12]))
    53  	frame.DeltaWindowSize = common.BytesToUint32(data[12:16])
    54  
    55  	if !frame.StreamID.Valid() {
    56  		return c.N, common.StreamIdTooLarge
    57  	}
    58  	if frame.StreamID.Zero() && frame.subversion == 0 {
    59  		return c.N, common.StreamIdIsZero
    60  	}
    61  	if frame.DeltaWindowSize > common.MAX_DELTA_WINDOW_SIZE {
    62  		return c.N, errors.New("Error: Delta Window Size too large.")
    63  	}
    64  
    65  	return c.N, nil
    66  }
    67  
    68  func (frame *WINDOW_UPDATE) String() string {
    69  	buf := new(bytes.Buffer)
    70  
    71  	buf.WriteString("WINDOW_UPDATE {\n\t")
    72  	buf.WriteString(fmt.Sprintf("Version:              3\n\t"))
    73  	buf.WriteString(fmt.Sprintf("Stream ID:            %d\n\t", frame.StreamID))
    74  	buf.WriteString(fmt.Sprintf("Delta window size:    %d\n}\n", frame.DeltaWindowSize))
    75  
    76  	return buf.String()
    77  }
    78  
    79  func (frame *WINDOW_UPDATE) WriteTo(writer io.Writer) (int64, error) {
    80  	c := common.WriteCounter{W: writer}
    81  	out := make([]byte, 16)
    82  
    83  	out[0] = 128                                     // Control bit and Version
    84  	out[1] = 3                                       // Version
    85  	out[2] = 0                                       // Type
    86  	out[3] = 9                                       // Type
    87  	out[4] = 0                                       // Flags
    88  	out[5] = 0                                       // Length
    89  	out[6] = 0                                       // Length
    90  	out[7] = 8                                       // Length
    91  	out[8] = frame.StreamID.B1()                     // Stream ID
    92  	out[9] = frame.StreamID.B2()                     // Stream ID
    93  	out[10] = frame.StreamID.B3()                    // Stream ID
    94  	out[11] = frame.StreamID.B4()                    // Stream ID
    95  	out[12] = byte(frame.DeltaWindowSize>>24) & 0x7f // Delta Window Size
    96  	out[13] = byte(frame.DeltaWindowSize >> 16)      // Delta Window Size
    97  	out[14] = byte(frame.DeltaWindowSize >> 8)       // Delta Window Size
    98  	out[15] = byte(frame.DeltaWindowSize)            // Delta Window Size
    99  
   100  	err := common.WriteExactly(&c, out)
   101  	if err != nil {
   102  		return c.N, err
   103  	}
   104  
   105  	return c.N, nil
   106  }