@@ -2588,7 +2588,7 @@ func (s) TestClientHandshakeInfoDialer(t *testing.T) {
2588
2588
}
2589
2589
}
2590
2590
2591
- func ( s ) TestClientDecodeHeaderStatusErr (t * testing.T ) {
2591
+ func TestClientDecodeHeaderStatusErr (t * testing.T ) {
2592
2592
testStream := func () * ClientStream {
2593
2593
return & ClientStream {
2594
2594
Stream : & Stream {
@@ -2620,6 +2620,8 @@ func (s) TestClientDecodeHeaderStatusErr(t *testing.T) {
2620
2620
wantStatus * status.Status
2621
2621
// end stream output
2622
2622
wantStatusEndStream * status.Status
2623
+ // head channel closed
2624
+ headerChanClosedForEndStream bool
2623
2625
}{
2624
2626
{
2625
2627
name : "valid header" ,
@@ -2644,11 +2646,14 @@ func (s) TestClientDecodeHeaderStatusErr(t *testing.T) {
2644
2646
},
2645
2647
wantStatus : status .New (
2646
2648
codes .Unknown ,
2647
- "malformed header: missing HTTP content-type" ,
2649
+ "unexpected HTTP status code received from server: 200 (OK); malformed header: missing HTTP content-type" ,
2648
2650
),
2651
+ headerChanClosedForEndStream : true ,
2652
+ // when headerChan is closed, it is already gRPC and we just need
2653
+ // grpc-status
2649
2654
wantStatusEndStream : status .New (
2650
- codes .Unknown ,
2651
- "malformed header: missing HTTP content-type " ,
2655
+ codes .OK ,
2656
+ "" ,
2652
2657
),
2653
2658
},
2654
2659
{
@@ -2680,11 +2685,32 @@ func (s) TestClientDecodeHeaderStatusErr(t *testing.T) {
2680
2685
codes .Internal ,
2681
2686
"malformed header: missing HTTP status; transport: received unexpected content-type \" application/json\" " ,
2682
2687
),
2688
+ // This content type will only come when end stream is also initial
2689
+ // header, otherwise we would already be talking gRPC
2683
2690
wantStatusEndStream : status .New (
2684
2691
codes .Internal ,
2685
2692
"malformed header: missing HTTP status; transport: received unexpected content-type \" application/json\" " ,
2686
2693
),
2687
2694
},
2695
+ {
2696
+ name : "invalid http content type with http status 504 translation" ,
2697
+ metaHeaderFrame : & http2.MetaHeadersFrame {
2698
+ Fields : []hpack.HeaderField {
2699
+ {Name : "content-type" , Value : "application/json" },
2700
+ {Name : ":status" , Value : "504" },
2701
+ },
2702
+ },
2703
+ wantStatus : status .New (
2704
+ codes .Unavailable ,
2705
+ "unexpected HTTP status code received from server: 504 (Gateway Timeout); transport: received unexpected content-type \" application/json\" " ,
2706
+ ),
2707
+ // This content type will only come when end stream is also initial
2708
+ // header, otherwise we would already be talking gRPC
2709
+ wantStatusEndStream : status .New (
2710
+ codes .Unavailable ,
2711
+ "unexpected HTTP status code received from server: 504 (Gateway Timeout); transport: received unexpected content-type \" application/json\" " ,
2712
+ ),
2713
+ },
2688
2714
{
2689
2715
name : "http fallback and invalid http status" ,
2690
2716
metaHeaderFrame : & http2.MetaHeadersFrame {
@@ -2697,9 +2723,12 @@ func (s) TestClientDecodeHeaderStatusErr(t *testing.T) {
2697
2723
codes .Internal ,
2698
2724
"transport: malformed http-status: strconv.ParseInt: parsing \" xxxx\" : invalid syntax" ,
2699
2725
),
2726
+ // for end stream, when we are already talking gRPC, we expect
2727
+ // grpc - status and fail for it, we will ignore http status.
2728
+ headerChanClosedForEndStream : true ,
2700
2729
wantStatusEndStream : status .New (
2701
2730
codes .Internal ,
2702
- "transport: malformed http-status: strconv.ParseInt: parsing \" xxxx \" : invalid syntax " ,
2731
+ "" ,
2703
2732
),
2704
2733
},
2705
2734
{
@@ -2747,8 +2776,9 @@ func (s) TestClientDecodeHeaderStatusErr(t *testing.T) {
2747
2776
{Name : ":status" , Value : "504" },
2748
2777
},
2749
2778
},
2750
- wantStatus : status .New (codes .OK , "" ),
2751
- wantStatusEndStream : status .New (codes .Internal , "" ),
2779
+ wantStatus : status .New (codes .OK , "" ),
2780
+ headerChanClosedForEndStream : true ,
2781
+ wantStatusEndStream : status .New (codes .Internal , "" ),
2752
2782
},
2753
2783
{
2754
2784
name : "ignore valid http status for grpc" ,
@@ -2797,6 +2827,9 @@ func (s) TestClientDecodeHeaderStatusErr(t *testing.T) {
2797
2827
})
2798
2828
t .Run (fmt .Sprintf ("%s-end_stream" , test .name ), func (t * testing.T ) {
2799
2829
ts := testStream ()
2830
+ if test .headerChanClosedForEndStream {
2831
+ ts .headerChanClosed = 1
2832
+ }
2800
2833
s := testClient (ts )
2801
2834
2802
2835
test .metaHeaderFrame .HeadersFrame = & http2.HeadersFrame {
0 commit comments