예제 #1
0
파일: common.go 프로젝트: vonwenm/spdy
// controlFrameCommonProcessing performs checks identical between
// all control frames. This includes the control bit, the version
// number, the type byte (which is checked against the byte
// provided), and the flags (which are checked against the bitwise
// OR of valid flags provided).
func controlFrameCommonProcessing(data []byte, frameType uint16, flags byte) error {
	// Check it's a control frame.
	if data[0] != 128 {
		return common.IncorrectFrame(_DATA_FRAME, int(frameType), 2)
	}

	// Check version.
	version := (uint16(data[0]&0x7f) << 8) + uint16(data[1])
	if version != 2 {
		return common.UnsupportedVersion(version)
	}

	// Check its type.
	realType := common.BytesToUint16(data[2:])
	if realType != frameType {
		return common.IncorrectFrame(int(realType), int(frameType), 2)
	}

	// Check the flags.
	if data[4] & ^flags != 0 {
		return common.InvalidField("flags", int(data[4]), int(flags))
	}

	return nil
}
예제 #2
0
파일: credential.go 프로젝트: vonwenm/spdy
func (frame *CREDENTIAL) ReadFrom(reader io.Reader) (int64, error) {
	c := common.ReadCounter{R: reader}
	data, err := common.ReadExactly(&c, 18)
	if err != nil {
		return c.N, err
	}

	err = controlFrameCommonProcessing(data[:5], _CREDENTIAL, 0)
	if err != nil {
		return c.N, err
	}

	// Get and check length.
	length := int(common.BytesToUint24(data[5:8]))
	if length < 6 {
		return c.N, common.IncorrectDataLength(length, 6)
	} else if length > common.MAX_FRAME_SIZE-8 {
		return c.N, common.FrameTooLarge
	}

	// Read in data.
	certs, err := common.ReadExactly(&c, length-10)
	if err != nil {
		return c.N, err
	}

	frame.Slot = common.BytesToUint16(data[8:10])
	proofLen := int(common.BytesToUint32(data[10:14]))
	if proofLen > 0 {
		frame.Proof = data[14 : 14+proofLen]
	} else {
		frame.Proof = []byte{}
	}

	numCerts := 0
	for offset := 0; offset < length-10; {
		offset += int(common.BytesToUint32(certs[offset:offset+4])) + 4
		numCerts++
	}

	frame.Certificates = make([]*x509.Certificate, numCerts)
	for i, offset := 0, 0; offset < length-10; i++ {
		length := int(common.BytesToUint32(certs[offset : offset+4]))
		rawCert := certs[offset+4 : offset+4+length]
		frame.Certificates[i], err = x509.ParseCertificate(rawCert)
		if err != nil {
			return c.N, err
		}
		offset += length + 4
	}

	return c.N, nil
}
예제 #3
0
파일: common.go 프로젝트: vonwenm/spdy
// ReadFrame reads and parses a frame from reader.
func ReadFrame(reader *bufio.Reader, subversion int) (frame common.Frame, err error) {
	start, err := reader.Peek(4)
	if err != nil {
		return nil, err
	}

	if start[0] != 128 {
		frame = new(DATA)
		_, err = frame.ReadFrom(reader)
		return frame, err
	}

	switch common.BytesToUint16(start[2:4]) {
	case _SYN_STREAM:
		switch subversion {
		case 0:
			frame = new(SYN_STREAM)
		case 1:
			frame = new(SYN_STREAMV3_1)
		default:
			return nil, fmt.Errorf("Error: Given subversion %d is unrecognised.", subversion)
		}
	case _SYN_REPLY:
		frame = new(SYN_REPLY)
	case _RST_STREAM:
		frame = new(RST_STREAM)
	case _SETTINGS:
		frame = new(SETTINGS)
	case _PING:
		frame = new(PING)
	case _GOAWAY:
		frame = new(GOAWAY)
	case _HEADERS:
		frame = new(HEADERS)
	case _WINDOW_UPDATE:
		frame = &WINDOW_UPDATE{subversion: subversion}
	case _CREDENTIAL:
		frame = new(CREDENTIAL)

	default:
		return nil, errors.New("Error Failed to parse frame type.")
	}

	_, err = frame.ReadFrom(reader)
	return frame, err
}
예제 #4
0
파일: common.go 프로젝트: vonwenm/spdy
// ReadFrame reads and parses a frame from reader.
func ReadFrame(reader *bufio.Reader) (frame common.Frame, err error) {
	start, err := reader.Peek(4)
	if err != nil {
		return nil, err
	}

	if start[0] != 128 {
		frame = new(DATA)
		_, err = frame.ReadFrom(reader)
		return frame, err
	}

	switch common.BytesToUint16(start[2:4]) {
	case _SYN_STREAM:
		frame = new(SYN_STREAM)
	case _SYN_REPLY:
		frame = new(SYN_REPLY)
	case _RST_STREAM:
		frame = new(RST_STREAM)
	case _SETTINGS:
		frame = new(SETTINGS)
	case _NOOP:
		frame = new(NOOP)
	case _PING:
		frame = new(PING)
	case _GOAWAY:
		frame = new(GOAWAY)
	case _HEADERS:
		frame = new(HEADERS)
	case _WINDOW_UPDATE:
		frame = new(WINDOW_UPDATE)

	default:
		return nil, errors.New("Error Failed to parse frame type.")
	}

	_, err = frame.ReadFrom(reader)
	return frame, err
}