TestHeadersCausingStreamError tests headers that should cause a stream protocol error, which would end up with a RST_STREAM being sent to the client and also the server closing the stream.
(t *testing.T)
| 2086 | // error, which would end up with a RST_STREAM being sent to the client and also |
| 2087 | // the server closing the stream. |
| 2088 | func (s) TestHeadersCausingStreamError(t *testing.T) { |
| 2089 | tests := []struct { |
| 2090 | name string |
| 2091 | headers []struct { |
| 2092 | name string |
| 2093 | values []string |
| 2094 | } |
| 2095 | }{ |
| 2096 | // "Transports must consider requests containing the Connection header |
| 2097 | // as malformed" - A41 Malformed requests map to a stream error of type |
| 2098 | // PROTOCOL_ERROR. |
| 2099 | { |
| 2100 | name: "Connection header present", |
| 2101 | headers: []struct { |
| 2102 | name string |
| 2103 | values []string |
| 2104 | }{ |
| 2105 | {name: ":method", values: []string{"POST"}}, |
| 2106 | {name: ":path", values: []string{"foo"}}, |
| 2107 | {name: ":authority", values: []string{"localhost"}}, |
| 2108 | {name: "content-type", values: []string{"application/grpc"}}, |
| 2109 | {name: "connection", values: []string{"not-supported"}}, |
| 2110 | }, |
| 2111 | }, |
| 2112 | // multiple :authority or multiple Host headers would make the eventual |
| 2113 | // :authority ambiguous as per A41. Since these headers won't have a |
| 2114 | // content-type that corresponds to a grpc-client, the server should |
| 2115 | // simply write a RST_STREAM to the wire. |
| 2116 | { |
| 2117 | // Note: multiple authority headers are handled by the framer |
| 2118 | // itself, which will cause a stream error. Thus, it will never get |
| 2119 | // to operateHeaders with the check in operateHeaders for stream |
| 2120 | // error, but the server transport will still send a stream error. |
| 2121 | name: "Multiple authority headers", |
| 2122 | headers: []struct { |
| 2123 | name string |
| 2124 | values []string |
| 2125 | }{ |
| 2126 | {name: ":method", values: []string{"POST"}}, |
| 2127 | {name: ":path", values: []string{"foo"}}, |
| 2128 | {name: ":authority", values: []string{"localhost", "localhost2"}}, |
| 2129 | {name: "host", values: []string{"localhost"}}, |
| 2130 | }, |
| 2131 | }, |
| 2132 | } |
| 2133 | for _, test := range tests { |
| 2134 | t.Run(test.name, func(t *testing.T) { |
| 2135 | server := setUpServerOnly(t, 0, &ServerConfig{BufferPool: mem.DefaultBufferPool()}, suspended) |
| 2136 | defer server.stop() |
| 2137 | // Create a client directly to not tie what you can send to API of |
| 2138 | // http2_client.go (i.e. control headers being sent). |
| 2139 | mconn, err := net.Dial("tcp", server.lis.Addr().String()) |
| 2140 | if err != nil { |
| 2141 | t.Fatalf("Client failed to dial: %v", err) |
| 2142 | } |
| 2143 | defer mconn.Close() |
| 2144 | |
| 2145 | if n, err := mconn.Write(clientPreface); err != nil || n != len(clientPreface) { |
nothing calls this directly
no test coverage detected