mirror of https://github.com/grpc/grpc-go.git
				
				
				
			Behavior change: do not strip out gRPC user-agent (#1158)
This commit is contained in:
		
							parent
							
								
									b2fae0cf40
								
							
						
					
					
						commit
						b982c1caa6
					
				|  | @ -93,6 +93,7 @@ var ( | ||||||
| 		"Key": []string{"foo"}, | 		"Key": []string{"foo"}, | ||||||
| 	} | 	} | ||||||
| 	testAppUA = "myApp1/1.0 myApp2/0.9" | 	testAppUA = "myApp1/1.0 myApp2/0.9" | ||||||
|  | 	failAppUA = "fail-this-RPC" | ||||||
| ) | ) | ||||||
| 
 | 
 | ||||||
| var raceMode bool // set by race_test.go in race mode
 | var raceMode bool // set by race_test.go in race mode
 | ||||||
|  | @ -107,10 +108,10 @@ type testServer struct { | ||||||
| 
 | 
 | ||||||
| func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { | func (s *testServer) EmptyCall(ctx context.Context, in *testpb.Empty) (*testpb.Empty, error) { | ||||||
| 	if md, ok := metadata.FromContext(ctx); ok { | 	if md, ok := metadata.FromContext(ctx); ok { | ||||||
| 		// For testing purpose, returns an error if there is attached metadata other than
 | 		// For testing purpose, returns an error if user-agent is failAppUA.
 | ||||||
| 		// the user agent set by the client application.
 | 		// To test that client gets the correct error.
 | ||||||
| 		if _, ok := md["user-agent"]; !ok { | 		if ua, ok := md["user-agent"]; !ok || strings.HasPrefix(ua[0], failAppUA) { | ||||||
| 			return nil, grpc.Errorf(codes.DataLoss, "missing expected user-agent") | 			return nil, grpc.Errorf(codes.DataLoss, "error for testing: "+failAppUA) | ||||||
| 		} | 		} | ||||||
| 		var str []string | 		var str []string | ||||||
| 		for _, entry := range md["user-agent"] { | 		for _, entry := range md["user-agent"] { | ||||||
|  | @ -215,9 +216,10 @@ func (s *testServer) StreamingOutputCall(args *testpb.StreamingOutputCallRequest | ||||||
| 		if _, exists := md[":authority"]; !exists { | 		if _, exists := md[":authority"]; !exists { | ||||||
| 			return grpc.Errorf(codes.DataLoss, "expected an :authority metadata: %v", md) | 			return grpc.Errorf(codes.DataLoss, "expected an :authority metadata: %v", md) | ||||||
| 		} | 		} | ||||||
| 		// For testing purpose, returns an error if there is attached metadata except for authority.
 | 		// For testing purpose, returns an error if user-agent is failAppUA.
 | ||||||
| 		if len(md) > 1 { | 		// To test that client gets the correct error.
 | ||||||
| 			return grpc.Errorf(codes.DataLoss, "got extra metadata") | 		if ua, ok := md["user-agent"]; !ok || strings.HasPrefix(ua[0], failAppUA) { | ||||||
|  | 			return grpc.Errorf(codes.DataLoss, "error for testing: "+failAppUA) | ||||||
| 		} | 		} | ||||||
| 	} | 	} | ||||||
| 	cs := args.GetResponseParameters() | 	cs := args.GetResponseParameters() | ||||||
|  | @ -1351,8 +1353,8 @@ func testEmptyUnaryWithUserAgent(t *testing.T, e env) { | ||||||
| 	if err != nil || !proto.Equal(&testpb.Empty{}, reply) { | 	if err != nil || !proto.Equal(&testpb.Empty{}, reply) { | ||||||
| 		t.Fatalf("TestService/EmptyCall(_, _) = %v, %v, want %v, <nil>", reply, err, &testpb.Empty{}) | 		t.Fatalf("TestService/EmptyCall(_, _) = %v, %v, want %v, <nil>", reply, err, &testpb.Empty{}) | ||||||
| 	} | 	} | ||||||
| 	if v, ok := header["ua"]; !ok || v[0] != testAppUA { | 	if v, ok := header["ua"]; !ok || !strings.HasPrefix(v[0], testAppUA) { | ||||||
| 		t.Fatalf("header[\"ua\"] = %q, %t, want %q, true", v, ok, testAppUA) | 		t.Fatalf("header[\"ua\"] = %q, %t, want string with prefix %q, true", v, ok, testAppUA) | ||||||
| 	} | 	} | ||||||
| 
 | 
 | ||||||
| 	te.srv.Stop() | 	te.srv.Stop() | ||||||
|  | @ -1367,12 +1369,13 @@ func TestFailedEmptyUnary(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| func testFailedEmptyUnary(t *testing.T, e env) { | func testFailedEmptyUnary(t *testing.T, e env) { | ||||||
| 	te := newTest(t, e) | 	te := newTest(t, e) | ||||||
|  | 	te.userAgent = failAppUA | ||||||
| 	te.startServer(&testServer{security: e.security}) | 	te.startServer(&testServer{security: e.security}) | ||||||
| 	defer te.tearDown() | 	defer te.tearDown() | ||||||
| 	tc := testpb.NewTestServiceClient(te.clientConn()) | 	tc := testpb.NewTestServiceClient(te.clientConn()) | ||||||
| 
 | 
 | ||||||
| 	ctx := metadata.NewContext(context.Background(), testMetadata) | 	ctx := metadata.NewContext(context.Background(), testMetadata) | ||||||
| 	wantErr := grpc.Errorf(codes.DataLoss, "missing expected user-agent") | 	wantErr := grpc.Errorf(codes.DataLoss, "error for testing: "+failAppUA) | ||||||
| 	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); !equalErrors(err, wantErr) { | 	if _, err := tc.EmptyCall(ctx, &testpb.Empty{}); !equalErrors(err, wantErr) { | ||||||
| 		t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, %v", err, wantErr) | 		t.Fatalf("TestService/EmptyCall(_, _) = _, %v, want _, %v", err, wantErr) | ||||||
| 	} | 	} | ||||||
|  | @ -1573,6 +1576,7 @@ func testMetadataUnaryRPC(t *testing.T, e env) { | ||||||
| 	if header != nil { | 	if header != nil { | ||||||
| 		delete(header, "trailer") // RFC 2616 says server SHOULD (but optional) declare trailers
 | 		delete(header, "trailer") // RFC 2616 says server SHOULD (but optional) declare trailers
 | ||||||
| 		delete(header, "date")    // the Date header is also optional
 | 		delete(header, "date")    // the Date header is also optional
 | ||||||
|  | 		delete(header, "user-agent") | ||||||
| 	} | 	} | ||||||
| 	if !reflect.DeepEqual(header, testMetadata) { | 	if !reflect.DeepEqual(header, testMetadata) { | ||||||
| 		t.Fatalf("Received header metadata %v, want %v", header, testMetadata) | 		t.Fatalf("Received header metadata %v, want %v", header, testMetadata) | ||||||
|  | @ -1688,6 +1692,7 @@ func testSetAndSendHeaderUnaryRPC(t *testing.T, e env) { | ||||||
| 	if _, err := tc.UnaryCall(ctx, req, grpc.Header(&header), grpc.FailFast(false)); err != nil { | 	if _, err := tc.UnaryCall(ctx, req, grpc.Header(&header), grpc.FailFast(false)); err != nil { | ||||||
| 		t.Fatalf("TestService.UnaryCall(%v, _, _, _) = _, %v; want _, <nil>", ctx, err) | 		t.Fatalf("TestService.UnaryCall(%v, _, _, _) = _, %v; want _, <nil>", ctx, err) | ||||||
| 	} | 	} | ||||||
|  | 	delete(header, "user-agent") | ||||||
| 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | ||||||
| 	if !reflect.DeepEqual(header, expectedHeader) { | 	if !reflect.DeepEqual(header, expectedHeader) { | ||||||
| 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | ||||||
|  | @ -1731,6 +1736,7 @@ func testMultipleSetHeaderUnaryRPC(t *testing.T, e env) { | ||||||
| 	if _, err := tc.UnaryCall(ctx, req, grpc.Header(&header), grpc.FailFast(false)); err != nil { | 	if _, err := tc.UnaryCall(ctx, req, grpc.Header(&header), grpc.FailFast(false)); err != nil { | ||||||
| 		t.Fatalf("TestService.UnaryCall(%v, _, _, _) = _, %v; want _, <nil>", ctx, err) | 		t.Fatalf("TestService.UnaryCall(%v, _, _, _) = _, %v; want _, <nil>", ctx, err) | ||||||
| 	} | 	} | ||||||
|  | 	delete(header, "user-agent") | ||||||
| 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | ||||||
| 	if !reflect.DeepEqual(header, expectedHeader) { | 	if !reflect.DeepEqual(header, expectedHeader) { | ||||||
| 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | ||||||
|  | @ -1773,6 +1779,7 @@ func testMultipleSetHeaderUnaryRPCError(t *testing.T, e env) { | ||||||
| 	if _, err := tc.UnaryCall(ctx, req, grpc.Header(&header), grpc.FailFast(false)); err == nil { | 	if _, err := tc.UnaryCall(ctx, req, grpc.Header(&header), grpc.FailFast(false)); err == nil { | ||||||
| 		t.Fatalf("TestService.UnaryCall(%v, _, _, _) = _, %v; want _, <non-nil>", ctx, err) | 		t.Fatalf("TestService.UnaryCall(%v, _, _, _) = _, %v; want _, <non-nil>", ctx, err) | ||||||
| 	} | 	} | ||||||
|  | 	delete(header, "user-agent") | ||||||
| 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | ||||||
| 	if !reflect.DeepEqual(header, expectedHeader) { | 	if !reflect.DeepEqual(header, expectedHeader) { | ||||||
| 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | ||||||
|  | @ -1816,6 +1823,7 @@ func testSetAndSendHeaderStreamingRPC(t *testing.T, e env) { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("%v.Header() = _, %v, want _, <nil>", stream, err) | 		t.Fatalf("%v.Header() = _, %v, want _, <nil>", stream, err) | ||||||
| 	} | 	} | ||||||
|  | 	delete(header, "user-agent") | ||||||
| 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | ||||||
| 	if !reflect.DeepEqual(header, expectedHeader) { | 	if !reflect.DeepEqual(header, expectedHeader) { | ||||||
| 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | ||||||
|  | @ -1878,6 +1886,7 @@ func testMultipleSetHeaderStreamingRPC(t *testing.T, e env) { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("%v.Header() = _, %v, want _, <nil>", stream, err) | 		t.Fatalf("%v.Header() = _, %v, want _, <nil>", stream, err) | ||||||
| 	} | 	} | ||||||
|  | 	delete(header, "user-agent") | ||||||
| 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | ||||||
| 	if !reflect.DeepEqual(header, expectedHeader) { | 	if !reflect.DeepEqual(header, expectedHeader) { | ||||||
| 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | ||||||
|  | @ -1935,6 +1944,7 @@ func testMultipleSetHeaderStreamingRPCError(t *testing.T, e env) { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("%v.Header() = _, %v, want _, <nil>", stream, err) | 		t.Fatalf("%v.Header() = _, %v, want _, <nil>", stream, err) | ||||||
| 	} | 	} | ||||||
|  | 	delete(header, "user-agent") | ||||||
| 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | 	expectedHeader := metadata.Join(testMetadata, testMetadata2) | ||||||
| 	if !reflect.DeepEqual(header, expectedHeader) { | 	if !reflect.DeepEqual(header, expectedHeader) { | ||||||
| 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | 		t.Fatalf("Received header metadata %v, want %v", header, expectedHeader) | ||||||
|  | @ -2311,12 +2321,14 @@ func testMetadataStreamingRPC(t *testing.T, e env) { | ||||||
| 			delete(headerMD, "transport_security_type") | 			delete(headerMD, "transport_security_type") | ||||||
| 		} | 		} | ||||||
| 		delete(headerMD, "trailer") // ignore if present
 | 		delete(headerMD, "trailer") // ignore if present
 | ||||||
|  | 		delete(headerMD, "user-agent") | ||||||
| 		if err != nil || !reflect.DeepEqual(testMetadata, headerMD) { | 		if err != nil || !reflect.DeepEqual(testMetadata, headerMD) { | ||||||
| 			t.Errorf("#1 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata) | 			t.Errorf("#1 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata) | ||||||
| 		} | 		} | ||||||
| 		// test the cached value.
 | 		// test the cached value.
 | ||||||
| 		headerMD, err = stream.Header() | 		headerMD, err = stream.Header() | ||||||
| 		delete(headerMD, "trailer") // ignore if present
 | 		delete(headerMD, "trailer") // ignore if present
 | ||||||
|  | 		delete(headerMD, "user-agent") | ||||||
| 		if err != nil || !reflect.DeepEqual(testMetadata, headerMD) { | 		if err != nil || !reflect.DeepEqual(testMetadata, headerMD) { | ||||||
| 			t.Errorf("#2 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata) | 			t.Errorf("#2 %v.Header() = %v, %v, want %v, <nil>", stream, headerMD, err, testMetadata) | ||||||
| 		} | 		} | ||||||
|  | @ -2422,6 +2434,7 @@ func TestFailedServerStreaming(t *testing.T) { | ||||||
| 
 | 
 | ||||||
| func testFailedServerStreaming(t *testing.T, e env) { | func testFailedServerStreaming(t *testing.T, e env) { | ||||||
| 	te := newTest(t, e) | 	te := newTest(t, e) | ||||||
|  | 	te.userAgent = failAppUA | ||||||
| 	te.startServer(&testServer{security: e.security}) | 	te.startServer(&testServer{security: e.security}) | ||||||
| 	defer te.tearDown() | 	defer te.tearDown() | ||||||
| 	tc := testpb.NewTestServiceClient(te.clientConn()) | 	tc := testpb.NewTestServiceClient(te.clientConn()) | ||||||
|  | @ -2441,7 +2454,7 @@ func testFailedServerStreaming(t *testing.T, e env) { | ||||||
| 	if err != nil { | 	if err != nil { | ||||||
| 		t.Fatalf("%v.StreamingOutputCall(_) = _, %v, want <nil>", tc, err) | 		t.Fatalf("%v.StreamingOutputCall(_) = _, %v, want <nil>", tc, err) | ||||||
| 	} | 	} | ||||||
| 	wantErr := grpc.Errorf(codes.DataLoss, "got extra metadata") | 	wantErr := grpc.Errorf(codes.DataLoss, "error for testing: "+failAppUA) | ||||||
| 	if _, err := stream.Recv(); !equalErrors(err, wantErr) { | 	if _, err := stream.Recv(); !equalErrors(err, wantErr) { | ||||||
| 		t.Fatalf("%v.Recv() = _, %v, want _, %v", stream, err, wantErr) | 		t.Fatalf("%v.Recv() = _, %v, want _, %v", stream, err, wantErr) | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|  | @ -186,15 +186,6 @@ func (d *decodeState) processHeaderField(f hpack.HeaderField) { | ||||||
| 		d.method = f.Value | 		d.method = f.Value | ||||||
| 	default: | 	default: | ||||||
| 		if !isReservedHeader(f.Name) || isWhitelistedPseudoHeader(f.Name) { | 		if !isReservedHeader(f.Name) || isWhitelistedPseudoHeader(f.Name) { | ||||||
| 			if f.Name == "user-agent" { |  | ||||||
| 				i := strings.LastIndex(f.Value, " ") |  | ||||||
| 				if i == -1 { |  | ||||||
| 					// There is no application user agent string being set.
 |  | ||||||
| 					return |  | ||||||
| 				} |  | ||||||
| 				// Extract the application user agent string.
 |  | ||||||
| 				f.Value = f.Value[:i] |  | ||||||
| 			} |  | ||||||
| 			if d.mdata == nil { | 			if d.mdata == nil { | ||||||
| 				d.mdata = make(map[string][]string) | 				d.mdata = make(map[string][]string) | ||||||
| 			} | 			} | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue