mirror of https://github.com/grpc/grpc-go.git
				
				
				
			
		
			
				
	
	
		
			110 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			2.7 KiB
		
	
	
	
		
			Go
		
	
	
	
/*
 | 
						|
 * Copyright 2022 gRPC authors.
 | 
						|
 *
 | 
						|
 * Licensed under the Apache License, Version 2.0 (the "License");
 | 
						|
 * you may not use this file except in compliance with the License.
 | 
						|
 * You may obtain a copy of the License at
 | 
						|
 *
 | 
						|
 *     http://www.apache.org/licenses/LICENSE-2.0
 | 
						|
 *
 | 
						|
 * Unless required by applicable law or agreed to in writing, software
 | 
						|
 * distributed under the License is distributed on an "AS IS" BASIS,
 | 
						|
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 | 
						|
 * See the License for the specific language governing permissions and
 | 
						|
 * limitations under the License.
 | 
						|
 */
 | 
						|
 | 
						|
package test
 | 
						|
 | 
						|
import (
 | 
						|
	"bytes"
 | 
						|
	"io"
 | 
						|
	"net"
 | 
						|
	"testing"
 | 
						|
 | 
						|
	"golang.org/x/net/http2"
 | 
						|
)
 | 
						|
 | 
						|
var (
 | 
						|
	clientPreface = []byte(http2.ClientPreface)
 | 
						|
)
 | 
						|
 | 
						|
func newClientTester(t *testing.T, conn net.Conn) *clientTester {
 | 
						|
	ct := &clientTester{
 | 
						|
		t:    t,
 | 
						|
		conn: conn,
 | 
						|
	}
 | 
						|
	ct.fr = http2.NewFramer(conn, conn)
 | 
						|
	ct.greet()
 | 
						|
	return ct
 | 
						|
}
 | 
						|
 | 
						|
type clientTester struct {
 | 
						|
	t    *testing.T
 | 
						|
	conn net.Conn
 | 
						|
	fr   *http2.Framer
 | 
						|
}
 | 
						|
 | 
						|
// greet() performs the necessary steps for http2 connection establishment on
 | 
						|
// the server side.
 | 
						|
func (ct *clientTester) greet() {
 | 
						|
	ct.wantClientPreface()
 | 
						|
	ct.wantSettingsFrame()
 | 
						|
	ct.writeSettingsFrame()
 | 
						|
	ct.writeSettingsAck()
 | 
						|
 | 
						|
	for {
 | 
						|
		f, err := ct.fr.ReadFrame()
 | 
						|
		if err != nil {
 | 
						|
			ct.t.Errorf("error reading frame from client side: %v", err)
 | 
						|
		}
 | 
						|
		switch f := f.(type) {
 | 
						|
		case *http2.SettingsFrame:
 | 
						|
			if f.IsAck() { // HTTP/2 handshake completed.
 | 
						|
				return
 | 
						|
			}
 | 
						|
		default:
 | 
						|
			ct.t.Errorf("during greet, unexpected frame type %T", f)
 | 
						|
		}
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (ct *clientTester) wantClientPreface() {
 | 
						|
	preface := make([]byte, len(clientPreface))
 | 
						|
	if _, err := io.ReadFull(ct.conn, preface); err != nil {
 | 
						|
		ct.t.Errorf("Error at server-side while reading preface from client. Err: %v", err)
 | 
						|
	}
 | 
						|
	if !bytes.Equal(preface, clientPreface) {
 | 
						|
		ct.t.Errorf("received bogus greeting from client %q", preface)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (ct *clientTester) wantSettingsFrame() {
 | 
						|
	frame, err := ct.fr.ReadFrame()
 | 
						|
	if err != nil {
 | 
						|
		ct.t.Errorf("error reading initial settings frame from client: %v", err)
 | 
						|
	}
 | 
						|
	_, ok := frame.(*http2.SettingsFrame)
 | 
						|
	if !ok {
 | 
						|
		ct.t.Errorf("initial frame sent from client is not a settings frame, type %T", frame)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (ct *clientTester) writeSettingsFrame() {
 | 
						|
	if err := ct.fr.WriteSettings(); err != nil {
 | 
						|
		ct.t.Fatalf("Error writing initial SETTINGS frame from client to server: %v", err)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (ct *clientTester) writeSettingsAck() {
 | 
						|
	if err := ct.fr.WriteSettingsAck(); err != nil {
 | 
						|
		ct.t.Fatalf("Error writing ACK of client's SETTINGS: %v", err)
 | 
						|
	}
 | 
						|
}
 | 
						|
 | 
						|
func (ct *clientTester) writeGoAway(maxStreamID uint32, code http2.ErrCode, debugData []byte) {
 | 
						|
	if err := ct.fr.WriteGoAway(maxStreamID, code, debugData); err != nil {
 | 
						|
		ct.t.Fatalf("Error writing GOAWAY: %v", err)
 | 
						|
	}
 | 
						|
}
 |