...

Source file src/github.com/moby/spdystream/spdy/read.go

Documentation: github.com/moby/spdystream/spdy

     1  /*
     2     Copyright 2014-2021 Docker Inc.
     3  
     4     Licensed under the Apache License, Version 2.0 (the "License");
     5     you may not use this file except in compliance with the License.
     6     You may obtain a copy of the License at
     7  
     8         http://www.apache.org/licenses/LICENSE-2.0
     9  
    10     Unless required by applicable law or agreed to in writing, software
    11     distributed under the License is distributed on an "AS IS" BASIS,
    12     WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13     See the License for the specific language governing permissions and
    14     limitations under the License.
    15  */
    16  
    17  // Copyright 2011 The Go Authors. All rights reserved.
    18  // Use of this source code is governed by a BSD-style
    19  // license that can be found in the LICENSE file.
    20  
    21  package spdy
    22  
    23  import (
    24  	"compress/zlib"
    25  	"encoding/binary"
    26  	"io"
    27  	"net/http"
    28  	"strings"
    29  )
    30  
    31  func (frame *SynStreamFrame) read(h ControlFrameHeader, f *Framer) error {
    32  	return f.readSynStreamFrame(h, frame)
    33  }
    34  
    35  func (frame *SynReplyFrame) read(h ControlFrameHeader, f *Framer) error {
    36  	return f.readSynReplyFrame(h, frame)
    37  }
    38  
    39  func (frame *RstStreamFrame) read(h ControlFrameHeader, f *Framer) error {
    40  	frame.CFHeader = h
    41  	if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
    42  		return err
    43  	}
    44  	if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
    45  		return err
    46  	}
    47  	if frame.Status == 0 {
    48  		return &Error{InvalidControlFrame, frame.StreamId}
    49  	}
    50  	if frame.StreamId == 0 {
    51  		return &Error{ZeroStreamId, 0}
    52  	}
    53  	return nil
    54  }
    55  
    56  func (frame *SettingsFrame) read(h ControlFrameHeader, f *Framer) error {
    57  	frame.CFHeader = h
    58  	var numSettings uint32
    59  	if err := binary.Read(f.r, binary.BigEndian, &numSettings); err != nil {
    60  		return err
    61  	}
    62  	frame.FlagIdValues = make([]SettingsFlagIdValue, numSettings)
    63  	for i := uint32(0); i < numSettings; i++ {
    64  		if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Id); err != nil {
    65  			return err
    66  		}
    67  		frame.FlagIdValues[i].Flag = SettingsFlag((frame.FlagIdValues[i].Id & 0xff000000) >> 24)
    68  		frame.FlagIdValues[i].Id &= 0xffffff
    69  		if err := binary.Read(f.r, binary.BigEndian, &frame.FlagIdValues[i].Value); err != nil {
    70  			return err
    71  		}
    72  	}
    73  	return nil
    74  }
    75  
    76  func (frame *PingFrame) read(h ControlFrameHeader, f *Framer) error {
    77  	frame.CFHeader = h
    78  	if err := binary.Read(f.r, binary.BigEndian, &frame.Id); err != nil {
    79  		return err
    80  	}
    81  	if frame.Id == 0 {
    82  		return &Error{ZeroStreamId, 0}
    83  	}
    84  	if frame.CFHeader.Flags != 0 {
    85  		return &Error{InvalidControlFrame, StreamId(frame.Id)}
    86  	}
    87  	return nil
    88  }
    89  
    90  func (frame *GoAwayFrame) read(h ControlFrameHeader, f *Framer) error {
    91  	frame.CFHeader = h
    92  	if err := binary.Read(f.r, binary.BigEndian, &frame.LastGoodStreamId); err != nil {
    93  		return err
    94  	}
    95  	if frame.CFHeader.Flags != 0 {
    96  		return &Error{InvalidControlFrame, frame.LastGoodStreamId}
    97  	}
    98  	if frame.CFHeader.length != 8 {
    99  		return &Error{InvalidControlFrame, frame.LastGoodStreamId}
   100  	}
   101  	if err := binary.Read(f.r, binary.BigEndian, &frame.Status); err != nil {
   102  		return err
   103  	}
   104  	return nil
   105  }
   106  
   107  func (frame *HeadersFrame) read(h ControlFrameHeader, f *Framer) error {
   108  	return f.readHeadersFrame(h, frame)
   109  }
   110  
   111  func (frame *WindowUpdateFrame) read(h ControlFrameHeader, f *Framer) error {
   112  	frame.CFHeader = h
   113  	if err := binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
   114  		return err
   115  	}
   116  	if frame.CFHeader.Flags != 0 {
   117  		return &Error{InvalidControlFrame, frame.StreamId}
   118  	}
   119  	if frame.CFHeader.length != 8 {
   120  		return &Error{InvalidControlFrame, frame.StreamId}
   121  	}
   122  	if err := binary.Read(f.r, binary.BigEndian, &frame.DeltaWindowSize); err != nil {
   123  		return err
   124  	}
   125  	return nil
   126  }
   127  
   128  func newControlFrame(frameType ControlFrameType) (controlFrame, error) {
   129  	ctor, ok := cframeCtor[frameType]
   130  	if !ok {
   131  		return nil, &Error{Err: InvalidControlFrame}
   132  	}
   133  	return ctor(), nil
   134  }
   135  
   136  var cframeCtor = map[ControlFrameType]func() controlFrame{
   137  	TypeSynStream:    func() controlFrame { return new(SynStreamFrame) },
   138  	TypeSynReply:     func() controlFrame { return new(SynReplyFrame) },
   139  	TypeRstStream:    func() controlFrame { return new(RstStreamFrame) },
   140  	TypeSettings:     func() controlFrame { return new(SettingsFrame) },
   141  	TypePing:         func() controlFrame { return new(PingFrame) },
   142  	TypeGoAway:       func() controlFrame { return new(GoAwayFrame) },
   143  	TypeHeaders:      func() controlFrame { return new(HeadersFrame) },
   144  	TypeWindowUpdate: func() controlFrame { return new(WindowUpdateFrame) },
   145  }
   146  
   147  func (f *Framer) uncorkHeaderDecompressor(payloadSize int64) error {
   148  	if f.headerDecompressor != nil {
   149  		f.headerReader.N = payloadSize
   150  		return nil
   151  	}
   152  	f.headerReader = io.LimitedReader{R: f.r, N: payloadSize}
   153  	decompressor, err := zlib.NewReaderDict(&f.headerReader, []byte(headerDictionary))
   154  	if err != nil {
   155  		return err
   156  	}
   157  	f.headerDecompressor = decompressor
   158  	return nil
   159  }
   160  
   161  // ReadFrame reads SPDY encoded data and returns a decompressed Frame.
   162  func (f *Framer) ReadFrame() (Frame, error) {
   163  	var firstWord uint32
   164  	if err := binary.Read(f.r, binary.BigEndian, &firstWord); err != nil {
   165  		return nil, err
   166  	}
   167  	if firstWord&0x80000000 != 0 {
   168  		frameType := ControlFrameType(firstWord & 0xffff)
   169  		version := uint16(firstWord >> 16 & 0x7fff)
   170  		return f.parseControlFrame(version, frameType)
   171  	}
   172  	return f.parseDataFrame(StreamId(firstWord & 0x7fffffff))
   173  }
   174  
   175  func (f *Framer) parseControlFrame(version uint16, frameType ControlFrameType) (Frame, error) {
   176  	var length uint32
   177  	if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
   178  		return nil, err
   179  	}
   180  	flags := ControlFlags((length & 0xff000000) >> 24)
   181  	length &= 0xffffff
   182  	header := ControlFrameHeader{version, frameType, flags, length}
   183  	cframe, err := newControlFrame(frameType)
   184  	if err != nil {
   185  		return nil, err
   186  	}
   187  	if err = cframe.read(header, f); err != nil {
   188  		return nil, err
   189  	}
   190  	return cframe, nil
   191  }
   192  
   193  func parseHeaderValueBlock(r io.Reader, streamId StreamId) (http.Header, error) {
   194  	var numHeaders uint32
   195  	if err := binary.Read(r, binary.BigEndian, &numHeaders); err != nil {
   196  		return nil, err
   197  	}
   198  	var e error
   199  	h := make(http.Header, int(numHeaders))
   200  	for i := 0; i < int(numHeaders); i++ {
   201  		var length uint32
   202  		if err := binary.Read(r, binary.BigEndian, &length); err != nil {
   203  			return nil, err
   204  		}
   205  		nameBytes := make([]byte, length)
   206  		if _, err := io.ReadFull(r, nameBytes); err != nil {
   207  			return nil, err
   208  		}
   209  		name := string(nameBytes)
   210  		if name != strings.ToLower(name) {
   211  			e = &Error{UnlowercasedHeaderName, streamId}
   212  			name = strings.ToLower(name)
   213  		}
   214  		if h[name] != nil {
   215  			e = &Error{DuplicateHeaders, streamId}
   216  		}
   217  		if err := binary.Read(r, binary.BigEndian, &length); err != nil {
   218  			return nil, err
   219  		}
   220  		value := make([]byte, length)
   221  		if _, err := io.ReadFull(r, value); err != nil {
   222  			return nil, err
   223  		}
   224  		valueList := strings.Split(string(value), headerValueSeparator)
   225  		for _, v := range valueList {
   226  			h.Add(name, v)
   227  		}
   228  	}
   229  	if e != nil {
   230  		return h, e
   231  	}
   232  	return h, nil
   233  }
   234  
   235  func (f *Framer) readSynStreamFrame(h ControlFrameHeader, frame *SynStreamFrame) error {
   236  	frame.CFHeader = h
   237  	var err error
   238  	if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
   239  		return err
   240  	}
   241  	if err = binary.Read(f.r, binary.BigEndian, &frame.AssociatedToStreamId); err != nil {
   242  		return err
   243  	}
   244  	if err = binary.Read(f.r, binary.BigEndian, &frame.Priority); err != nil {
   245  		return err
   246  	}
   247  	frame.Priority >>= 5
   248  	if err = binary.Read(f.r, binary.BigEndian, &frame.Slot); err != nil {
   249  		return err
   250  	}
   251  	reader := f.r
   252  	if !f.headerCompressionDisabled {
   253  		err := f.uncorkHeaderDecompressor(int64(h.length - 10))
   254  		if err != nil {
   255  			return err
   256  		}
   257  		reader = f.headerDecompressor
   258  	}
   259  	frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
   260  	if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {
   261  		err = &Error{WrongCompressedPayloadSize, 0}
   262  	}
   263  	if err != nil {
   264  		return err
   265  	}
   266  	for h := range frame.Headers {
   267  		if invalidReqHeaders[h] {
   268  			return &Error{InvalidHeaderPresent, frame.StreamId}
   269  		}
   270  	}
   271  	if frame.StreamId == 0 {
   272  		return &Error{ZeroStreamId, 0}
   273  	}
   274  	return nil
   275  }
   276  
   277  func (f *Framer) readSynReplyFrame(h ControlFrameHeader, frame *SynReplyFrame) error {
   278  	frame.CFHeader = h
   279  	var err error
   280  	if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
   281  		return err
   282  	}
   283  	reader := f.r
   284  	if !f.headerCompressionDisabled {
   285  		err := f.uncorkHeaderDecompressor(int64(h.length - 4))
   286  		if err != nil {
   287  			return err
   288  		}
   289  		reader = f.headerDecompressor
   290  	}
   291  	frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
   292  	if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {
   293  		err = &Error{WrongCompressedPayloadSize, 0}
   294  	}
   295  	if err != nil {
   296  		return err
   297  	}
   298  	for h := range frame.Headers {
   299  		if invalidRespHeaders[h] {
   300  			return &Error{InvalidHeaderPresent, frame.StreamId}
   301  		}
   302  	}
   303  	if frame.StreamId == 0 {
   304  		return &Error{ZeroStreamId, 0}
   305  	}
   306  	return nil
   307  }
   308  
   309  func (f *Framer) readHeadersFrame(h ControlFrameHeader, frame *HeadersFrame) error {
   310  	frame.CFHeader = h
   311  	var err error
   312  	if err = binary.Read(f.r, binary.BigEndian, &frame.StreamId); err != nil {
   313  		return err
   314  	}
   315  	reader := f.r
   316  	if !f.headerCompressionDisabled {
   317  		err := f.uncorkHeaderDecompressor(int64(h.length - 4))
   318  		if err != nil {
   319  			return err
   320  		}
   321  		reader = f.headerDecompressor
   322  	}
   323  	frame.Headers, err = parseHeaderValueBlock(reader, frame.StreamId)
   324  	if !f.headerCompressionDisabled && (err == io.EOF && f.headerReader.N == 0 || f.headerReader.N != 0) {
   325  		err = &Error{WrongCompressedPayloadSize, 0}
   326  	}
   327  	if err != nil {
   328  		return err
   329  	}
   330  	var invalidHeaders map[string]bool
   331  	if frame.StreamId%2 == 0 {
   332  		invalidHeaders = invalidReqHeaders
   333  	} else {
   334  		invalidHeaders = invalidRespHeaders
   335  	}
   336  	for h := range frame.Headers {
   337  		if invalidHeaders[h] {
   338  			return &Error{InvalidHeaderPresent, frame.StreamId}
   339  		}
   340  	}
   341  	if frame.StreamId == 0 {
   342  		return &Error{ZeroStreamId, 0}
   343  	}
   344  	return nil
   345  }
   346  
   347  func (f *Framer) parseDataFrame(streamId StreamId) (*DataFrame, error) {
   348  	var length uint32
   349  	if err := binary.Read(f.r, binary.BigEndian, &length); err != nil {
   350  		return nil, err
   351  	}
   352  	var frame DataFrame
   353  	frame.StreamId = streamId
   354  	frame.Flags = DataFlags(length >> 24)
   355  	length &= 0xffffff
   356  	frame.Data = make([]byte, length)
   357  	if _, err := io.ReadFull(f.r, frame.Data); err != nil {
   358  		return nil, err
   359  	}
   360  	if frame.StreamId == 0 {
   361  		return nil, &Error{ZeroStreamId, 0}
   362  	}
   363  	return &frame, nil
   364  }
   365  

View as plain text