-
Notifications
You must be signed in to change notification settings - Fork 4.7k
transport: surface subsequent data when receiving non-gRPC header #8929
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Changes from 2 commits
3dc8573
3cd1bf5
95cf20b
038dd99
6dd9c4f
4e270af
b59203a
685f4ef
b6f3bf2
1effa8e
e60496c
8725f9f
3ae8eaf
a83d60e
6e579f2
7895aef
e3d1434
2069ce9
15e67d0
db6ea10
6afa8f8
df12e44
f5c04f2
44e4144
0d23730
df306a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -34,6 +34,7 @@ import ( | |
| "os" | ||
| "reflect" | ||
| "runtime" | ||
| "strconv" | ||
| "strings" | ||
| "sync" | ||
| "sync/atomic" | ||
|
|
@@ -6787,6 +6788,118 @@ func (s) TestAuthorityHeader(t *testing.T) { | |
| } | ||
| } | ||
|
|
||
| func (s) TestHTTPServerSendsNonGRPCHeaderSurfaceFurtherData(t *testing.T) { | ||
| tests := []struct { | ||
| name string | ||
| responses []httpServerResponse | ||
| wantCode codes.Code | ||
| wantErr string | ||
| }{ | ||
| { | ||
| name: "non-gRPC content-type without payload", | ||
| responses: []httpServerResponse{ | ||
| { | ||
| headers: [][]string{ | ||
| { | ||
| ":status", "200", | ||
| "content-type", "text/html", | ||
| }, | ||
| }, | ||
| // payload: nil | ||
| }, | ||
| }, | ||
| wantCode: codes.Unknown, | ||
| wantErr: `rpc error: code = Unknown desc = unexpected HTTP status code received from server: 200 (OK); transport: received unexpected content-type "text/html" | ||
| data: ""`, | ||
| }, | ||
| { | ||
| name: "non-gRPC content-type with payload", | ||
| responses: []httpServerResponse{ | ||
| { | ||
| headers: [][]string{ | ||
| { | ||
| ":status", "200", | ||
| "content-type", "text/html", | ||
| }, | ||
| }, | ||
| payload: []byte(`<html><body>Hello World</body></html>`), | ||
| }, | ||
| }, | ||
| wantCode: codes.Unknown, | ||
| wantErr: `rpc error: code = Unknown desc = unexpected HTTP status code received from server: 200 (OK); transport: received unexpected content-type "text/html" | ||
| data: "<html><body>Hello World</body></html>"`, | ||
| }, | ||
| { | ||
| name: "non-gRPC content-type with bytes payload length more than transport.NonGRPCDataMaxLen", | ||
| responses: []httpServerResponse{ | ||
| { | ||
| headers: [][]string{ | ||
| { | ||
| ":status", "200", | ||
| "content-type", "text/html", | ||
| }, | ||
| }, | ||
| payload: bytes.Repeat([]byte("a"), transport.NonGRPCDataMaxLen+1), | ||
| }, | ||
| }, | ||
| wantCode: codes.Unknown, | ||
| wantErr: `rpc error: code = Unknown desc = unexpected HTTP status code received from server: 200 (OK); transport: received unexpected content-type "text/html" | ||
| data: ` + strconv.Quote(strings.Repeat("a", transport.NonGRPCDataMaxLen)), | ||
| }, | ||
| { | ||
| name: "content-type not provided", | ||
| responses: []httpServerResponse{ | ||
| { | ||
| headers: [][]string{{ | ||
| ":status", "502", | ||
| }}, | ||
| payload: []byte("hello"), | ||
| }, | ||
| }, | ||
| wantCode: codes.Unavailable, | ||
| wantErr: `rpc error: code = Unavailable desc = unexpected HTTP status code received from server: 502 (Bad Gateway); malformed header: missing HTTP content-type | ||
|
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Nit: Since we are also checking the returned status with
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I skip the However I did't use {
name: "non-gRPC content-type with bytes payload length more than nonGRPCDataMaxLen",
responses: []httpServerResponse{
{
headers: [][]string{
{
":status", "200",
"content-type", "text/html",
},
},
payload: bytes.Repeat([]byte("a"), nonGRPCDataMaxLen+1),
},
},
wantCode: codes.Unknown,
wantErr: `rpc error: code = Unknown desc = unexpected HTTP status code received from server: 200 (OK); transport: received unexpected content-type "text/html"
data: ` + strconv.Quote(strings.Repeat("a", nonGRPCDataMaxLen)),
},When the payload exceeds |
||
| data: "hello"`, | ||
| }, | ||
| } | ||
|
|
||
| for _, test := range tests { | ||
| t.Run(test.name, func(t *testing.T) { | ||
| lis, err := net.Listen("tcp", "localhost:0") | ||
| if err != nil { | ||
| t.Fatalf("net.Listen() failed: %v", err) | ||
| } | ||
| defer lis.Close() | ||
|
|
||
| hs := &httpServer{responses: test.responses} | ||
| hs.start(t, lis) | ||
|
|
||
| ctx, cancel := context.WithTimeout(context.Background(), defaultTestTimeout) | ||
| defer cancel() | ||
|
|
||
| cc, err := grpc.NewClient(lis.Addr().String(), grpc.WithTransportCredentials(insecure.NewCredentials())) | ||
| if err != nil { | ||
| t.Fatalf("grpc.NewClient() failed: %v", err) | ||
| } | ||
| defer cc.Close() | ||
|
|
||
| client := testgrpc.NewTestServiceClient(cc) | ||
| _, err = client.EmptyCall(ctx, &testpb.Empty{}) | ||
|
|
||
|
chengxilo marked this conversation as resolved.
Outdated
|
||
| if err == nil { | ||
| t.Fatalf("EmptyCall() = nil; want non-nil error due to non-gRPC response") | ||
| } | ||
|
|
||
| if got, want := status.Code(err), test.wantCode; got != want { | ||
| t.Fatalf("Unexpected error code: got %v, want %v\nfull error:\n%v", got, want, err) | ||
| } | ||
|
|
||
| if err.Error() != test.wantErr { | ||
| t.Errorf("Unexpected error message: got\n %v, want\n %v", err.Error(), test.wantErr) | ||
| } | ||
| }) | ||
| } | ||
| } | ||
|
|
||
| // wrapCloseListener tracks Accepts/Closes and maintains a counter of the | ||
| // number of open connections. | ||
| type wrapCloseListener struct { | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.