github.com/alejandroesc/spdy@v0.0.0-20200317064415-01a02f0eb389/spdy2/frames/settings.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  	"sort"
    13  
    14  	"github.com/SlyMarbo/spdy/common"
    15  )
    16  
    17  type SETTINGS struct {
    18  	Flags    common.Flags
    19  	Settings common.Settings
    20  }
    21  
    22  func (frame *SETTINGS) Add(Flags common.Flags, id uint32, value uint32) {
    23  	frame.Settings[id] = &common.Setting{Flags, id, value}
    24  }
    25  
    26  func (frame *SETTINGS) Compress(comp common.Compressor) error {
    27  	return nil
    28  }
    29  
    30  func (frame *SETTINGS) Decompress(decomp common.Decompressor) error {
    31  	return nil
    32  }
    33  
    34  func (frame *SETTINGS) Name() string {
    35  	return "SETTINGS"
    36  }
    37  
    38  func (frame *SETTINGS) ReadFrom(reader io.Reader) (int64, error) {
    39  	c := common.ReadCounter{R: reader}
    40  	data, err := common.ReadExactly(&c, 12)
    41  	if err != nil {
    42  		return c.N, err
    43  	}
    44  
    45  	err = controlFrameCommonProcessing(data[:5], _SETTINGS, common.FLAG_SETTINGS_CLEAR_SETTINGS)
    46  	if err != nil {
    47  		return c.N, err
    48  	}
    49  
    50  	// Get and check length.
    51  	length := int(common.BytesToUint24(data[5:8]))
    52  	if length < 4 {
    53  		return c.N, common.IncorrectDataLength(length, 8)
    54  	} else if length > common.MAX_FRAME_SIZE-8 {
    55  		return c.N, common.FrameTooLarge
    56  	}
    57  
    58  	// Check size.
    59  	numSettings := int(common.BytesToUint32(data[8:12]))
    60  	if length != 4+(8*numSettings) {
    61  		return c.N, common.IncorrectDataLength(length, 4+(8*numSettings))
    62  	}
    63  
    64  	// Read in data.
    65  	settings, err := common.ReadExactly(&c, 8*numSettings)
    66  	if err != nil {
    67  		return c.N, err
    68  	}
    69  
    70  	frame.Flags = common.Flags(data[4])
    71  	frame.Settings = make(common.Settings)
    72  	for i := 0; i < numSettings; i++ {
    73  		j := i * 8
    74  		setting := decodeSetting(settings[j:])
    75  		if setting == nil {
    76  			return c.N, errors.New("Error: Failed to parse settings.")
    77  		}
    78  		frame.Settings[setting.ID] = setting
    79  	}
    80  
    81  	return c.N, nil
    82  }
    83  
    84  func (frame *SETTINGS) String() string {
    85  	buf := new(bytes.Buffer)
    86  	flags := ""
    87  	if frame.Flags.CLEAR_SETTINGS() {
    88  		flags += " FLAG_SETTINGS_CLEAR_SETTINGS"
    89  	}
    90  	if flags == "" {
    91  		flags = "[NONE]"
    92  	} else {
    93  		flags = flags[1:]
    94  	}
    95  
    96  	buf.WriteString("SETTINGS {\n\t")
    97  	buf.WriteString(fmt.Sprintf("Version:              2\n\t"))
    98  	buf.WriteString(fmt.Sprintf("Flags:                %s\n\t", flags))
    99  	buf.WriteString(fmt.Sprintf("Settings:\n"))
   100  	settings := frame.Settings.Settings()
   101  	for _, setting := range settings {
   102  		buf.WriteString("\t\t" + setting.String() + "\n")
   103  	}
   104  	buf.WriteString("}\n")
   105  
   106  	return buf.String()
   107  }
   108  
   109  func (frame *SETTINGS) WriteTo(writer io.Writer) (int64, error) {
   110  	c := common.WriteCounter{W: writer}
   111  	settings := encodeSettings(frame.Settings)
   112  	numSettings := uint32(len(frame.Settings))
   113  	length := 4 + len(settings)
   114  	out := make([]byte, 12)
   115  
   116  	out[0] = 128                     // Control bit and Version
   117  	out[1] = 2                       // Version
   118  	out[2] = 0                       // Type
   119  	out[3] = 4                       // Type
   120  	out[4] = byte(frame.Flags)       // Flags
   121  	out[5] = byte(length >> 16)      // Length
   122  	out[6] = byte(length >> 8)       // Length
   123  	out[7] = byte(length)            // Length
   124  	out[8] = byte(numSettings >> 24) // Number of Entries
   125  	out[9] = byte(numSettings >> 16) // Number of Entries
   126  	out[10] = byte(numSettings >> 8) // Number of Entries
   127  	out[11] = byte(numSettings)      // Number of Entries
   128  
   129  	err := common.WriteExactly(&c, out)
   130  	if err != nil {
   131  		return c.N, err
   132  	}
   133  
   134  	err = common.WriteExactly(&c, settings)
   135  	if err != nil {
   136  		return c.N, err
   137  	}
   138  
   139  	return c.N, nil
   140  }
   141  
   142  func decodeSetting(data []byte) *common.Setting {
   143  	if len(data) < 8 {
   144  		return nil
   145  	}
   146  
   147  	setting := new(common.Setting)
   148  	setting.ID = common.BytesToUint24Reverse(data[0:]) // Might need to reverse this.
   149  	setting.Flags = common.Flags(data[3])
   150  	setting.Value = common.BytesToUint32(data[4:])
   151  
   152  	return setting
   153  }
   154  
   155  func encodeSettings(s common.Settings) []byte {
   156  	if len(s) == 0 {
   157  		return []byte{}
   158  	}
   159  
   160  	ids := make([]int, 0, len(s))
   161  	for id := range s {
   162  		ids = append(ids, int(id))
   163  	}
   164  
   165  	sort.Sort(sort.IntSlice(ids))
   166  
   167  	out := make([]byte, 8*len(s))
   168  
   169  	offset := 0
   170  	for _, id := range ids {
   171  		setting := s[uint32(id)]
   172  		out[offset] = byte(setting.ID)         // Might need to reverse this.
   173  		out[offset+1] = byte(setting.ID >> 8)  // Might need to reverse this.
   174  		out[offset+2] = byte(setting.ID >> 16) // Might need to reverse this.
   175  		out[offset+3] = byte(setting.Flags)
   176  		out[offset+4] = byte(setting.Value >> 24)
   177  		out[offset+5] = byte(setting.Value >> 16)
   178  		out[offset+6] = byte(setting.Value >> 8)
   179  		out[offset+7] = byte(setting.Value)
   180  		offset += 8
   181  	}
   182  
   183  	return out
   184  }