TUN-4026: Fix regression where HTTP2 edge transport was no longer propagating control plane errors
This commit is contained in:
		
							parent
							
								
									4f88982584
								
							
						
					
					
						commit
						89b738f8fa
					
				|  | @ -108,6 +108,7 @@ func (c *http2Connection) ServeHTTP(w http.ResponseWriter, r *http.Request) { | ||||||
| 	switch connType { | 	switch connType { | ||||||
| 	case TypeControlStream: | 	case TypeControlStream: | ||||||
| 		proxyErr = c.serveControlStream(r.Context(), respWriter) | 		proxyErr = c.serveControlStream(r.Context(), respWriter) | ||||||
|  | 		c.controlStreamErr = proxyErr | ||||||
| 	case TypeWebsocket: | 	case TypeWebsocket: | ||||||
| 		stripWebsocketUpgradeHeader(r) | 		stripWebsocketUpgradeHeader(r) | ||||||
| 		proxyErr = c.config.OriginProxy.Proxy(respWriter, r, TypeWebsocket) | 		proxyErr = c.config.OriginProxy.Proxy(respWriter, r, TypeWebsocket) | ||||||
|  |  | ||||||
|  | @ -114,6 +114,7 @@ func TestServeHTTP(t *testing.T) { | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| type mockNamedTunnelRPCClient struct { | type mockNamedTunnelRPCClient struct { | ||||||
|  | 	shouldFail   error | ||||||
| 	registered   chan struct{} | 	registered   chan struct{} | ||||||
| 	unregistered chan struct{} | 	unregistered chan struct{} | ||||||
| } | } | ||||||
|  | @ -125,6 +126,9 @@ func (mc mockNamedTunnelRPCClient) RegisterConnection( | ||||||
| 	connIndex uint8, | 	connIndex uint8, | ||||||
| 	observer *Observer, | 	observer *Observer, | ||||||
| ) error { | ) error { | ||||||
|  | 	if mc.shouldFail != nil { | ||||||
|  | 		return mc.shouldFail | ||||||
|  | 	} | ||||||
| 	close(mc.registered) | 	close(mc.registered) | ||||||
| 	return nil | 	return nil | ||||||
| } | } | ||||||
|  | @ -136,12 +140,14 @@ func (mc mockNamedTunnelRPCClient) GracefulShutdown(ctx context.Context, gracePe | ||||||
| func (mockNamedTunnelRPCClient) Close() {} | func (mockNamedTunnelRPCClient) Close() {} | ||||||
| 
 | 
 | ||||||
| type mockRPCClientFactory struct { | type mockRPCClientFactory struct { | ||||||
|  | 	shouldFail   error | ||||||
| 	registered   chan struct{} | 	registered   chan struct{} | ||||||
| 	unregistered chan struct{} | 	unregistered chan struct{} | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| func (mf *mockRPCClientFactory) newMockRPCClient(context.Context, io.ReadWriteCloser, *zerolog.Logger) NamedTunnelRPCClient { | func (mf *mockRPCClientFactory) newMockRPCClient(context.Context, io.ReadWriteCloser, *zerolog.Logger) NamedTunnelRPCClient { | ||||||
| 	return mockNamedTunnelRPCClient{ | 	return mockNamedTunnelRPCClient{ | ||||||
|  | 		shouldFail:   mf.shouldFail, | ||||||
| 		registered:   mf.registered, | 		registered:   mf.registered, | ||||||
| 		unregistered: mf.unregistered, | 		unregistered: mf.unregistered, | ||||||
| 	} | 	} | ||||||
|  | @ -249,6 +255,39 @@ func TestServeControlStream(t *testing.T) { | ||||||
| 	wg.Wait() | 	wg.Wait() | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | func TestFailRegistration(t *testing.T) { | ||||||
|  | 	http2Conn, edgeConn := newTestHTTP2Connection() | ||||||
|  | 
 | ||||||
|  | 	rpcClientFactory := mockRPCClientFactory{ | ||||||
|  | 		shouldFail:   errDuplicationConnection, | ||||||
|  | 		registered:   make(chan struct{}), | ||||||
|  | 		unregistered: make(chan struct{}), | ||||||
|  | 	} | ||||||
|  | 	http2Conn.newRPCClientFunc = rpcClientFactory.newMockRPCClient | ||||||
|  | 
 | ||||||
|  | 	ctx, cancel := context.WithCancel(context.Background()) | ||||||
|  | 	var wg sync.WaitGroup | ||||||
|  | 	wg.Add(1) | ||||||
|  | 	go func() { | ||||||
|  | 		defer wg.Done() | ||||||
|  | 		http2Conn.Serve(ctx) | ||||||
|  | 	}() | ||||||
|  | 
 | ||||||
|  | 	req, err := http.NewRequestWithContext(ctx, http.MethodGet, "http://localhost:8080/", nil) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	req.Header.Set(internalUpgradeHeader, controlStreamUpgrade) | ||||||
|  | 
 | ||||||
|  | 	edgeHTTP2Conn, err := testTransport.NewClientConn(edgeConn) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	resp, err := edgeHTTP2Conn.RoundTrip(req) | ||||||
|  | 	require.NoError(t, err) | ||||||
|  | 	require.Equal(t, http.StatusBadGateway, resp.StatusCode) | ||||||
|  | 
 | ||||||
|  | 	assert.NotNil(t, http2Conn.controlStreamErr) | ||||||
|  | 	cancel() | ||||||
|  | 	wg.Wait() | ||||||
|  | } | ||||||
|  | 
 | ||||||
| func TestGracefulShutdownHTTP2(t *testing.T) { | func TestGracefulShutdownHTTP2(t *testing.T) { | ||||||
| 	http2Conn, edgeConn := newTestHTTP2Connection() | 	http2Conn, edgeConn := newTestHTTP2Connection() | ||||||
| 
 | 
 | ||||||
|  |  | ||||||
		Loading…
	
		Reference in New Issue