Uploaded image for project: 'Undertow'
  1. Undertow
  2. UNDERTOW-1396

Undertow logs an ERROR when client unexpectedly closes a connection while receiving content from a server behind ProxyHandler

XMLWordPrintable

    • Icon: Enhancement Enhancement
    • Resolution: Cannot Reproduce
    • Icon: Minor Minor
    • None
    • 2.0.11.Final
    • Proxy
    • None

      Undertow pollutes logs with ERROR messages when client (browser, etc) closes connection while receiving data from an application behind ProxyHandler (load balancer in our case). Expected error message should be at most DEBUG in this scenario.

      Example program:

      import io.undertow.Handlers;
      import io.undertow.Undertow;
      import io.undertow.server.handlers.proxy.LoadBalancingProxyClient;
      import io.undertow.servlet.Servlets;
      import io.undertow.servlet.api.DeploymentInfo;
      import io.undertow.servlet.api.DeploymentManager;
      
      import javax.servlet.ServletException;
      import javax.servlet.ServletOutputStream;
      import javax.servlet.http.HttpServlet;
      import javax.servlet.http.HttpServletRequest;
      import javax.servlet.http.HttpServletResponse;
      import java.io.IOException;
      import java.io.InputStream;
      import java.net.HttpURLConnection;
      import java.net.URI;
      import java.net.URL;
      
      public class App {
      
          public static void main(String[] args) throws ServletException {
              // Application
              DeploymentInfo servletBuilder = Servlets.deployment()
                      .setClassLoader(App.class.getClassLoader())
                      .setContextPath("/")
                      .setDeploymentName("test.war")
                      .addServlets(Servlets.servlet("test", RequestPrinter.class).addMapping("/*"));
              DeploymentManager manager = Servlets.defaultContainer().addDeployment(servletBuilder);
              manager.deploy();
      
              Undertow applicationServer = Undertow.builder()
                      .addHttpListener(8080, "localhost")
                      .setHandler(manager.start())
                      .build();
              applicationServer.start();
      
              // Proxy
              LoadBalancingProxyClient proxyClient = new LoadBalancingProxyClient();
              proxyClient.addHost(URI.create("http://localhost:8080"));
              Undertow loadBalancer = Undertow.builder()
                      .addHttpListener(8180, "localhost")
                      .setHandler(Handlers.proxyHandler(proxyClient))
                      .build();
      
              loadBalancer.start();
      
              try {
                  URL url = new URL("http://localhost:8180/");
                  HttpURLConnection urlConnection = (HttpURLConnection) url.openConnection();
                  InputStream inputStream = urlConnection.getInputStream();
                  // read a small part of the response and exit
                  byte[] buffer = new byte[10];
                  inputStream.read(buffer, 0, 10);
                  System.out.println("Done reading");
              } catch (Exception e) {
                  e.printStackTrace();
              }
          }
      
          public static class RequestPrinter extends HttpServlet {
              @Override
              protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws IOException {
                  // Write lots of data
                  ServletOutputStream outputStream = resp.getOutputStream();
                  for (int i = 0; i < 100000; i++) {
                      outputStream.println("ResponseLine#" + i);
                  }
              }
          }
      }
      

      Output:

      Aug 13, 2018 11:17:57 AM org.xnio.Xnio <clinit>
      INFO: XNIO version 3.3.8.Final
      Aug 13, 2018 11:17:57 AM org.xnio.nio.NioXnio <clinit>
      INFO: XNIO NIO Implementation Version 3.3.8.Final
      Done reading
      Aug 13, 2018 11:17:58 AM io.undertow.server.handlers.proxy.ProxyHandler handleFailure
      ERROR: UT005028: Proxy request to / failed
      java.nio.channels.ClosedChannelException
      at io.undertow.client.http.HttpClientConnection$5.handleEvent(HttpClientConnection.java:192)
      at io.undertow.client.http.HttpClientConnection$5.handleEvent(HttpClientConnection.java:171)
      at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      at org.xnio.StreamConnection.invokeCloseListener(StreamConnection.java:80)
      at org.xnio.Connection.close(Connection.java:142)
      at org.xnio.IoUtils.safeClose(IoUtils.java:134)
      at io.undertow.util.ConnectionUtils.doDrain(ConnectionUtils.java:130)
      at io.undertow.util.ConnectionUtils.cleanClose(ConnectionUtils.java:74)
      at io.undertow.client.http.HttpClientConnection.close(HttpClientConnection.java:472)
      at org.xnio.IoUtils.safeClose(IoUtils.java:134)
      at io.undertow.server.handlers.proxy.ProxyHandler$IoExceptionHandler.handleException(ProxyHandler.java:790)
      at org.xnio.ChannelListeners.invokeChannelExceptionHandler(ChannelListeners.java:126)
      at io.undertow.util.Transfer$TransferListener.handleEvent(Transfer.java:193)
      at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      at io.undertow.channels.DetachableStreamSinkChannel$SetterDelegatingListener.handleEvent(DetachableStreamSinkChannel.java:285)
      at io.undertow.channels.DetachableStreamSinkChannel$SetterDelegatingListener.handleEvent(DetachableStreamSinkChannel.java:272)
      at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)
      at org.xnio.conduits.WriteReadyHandler$ChannelListenerHandler.writeReady(WriteReadyHandler.java:65)
      at org.xnio.nio.NioSocketConduit.handleReady(NioSocketConduit.java:93)
      at org.xnio.nio.WorkerThread.run(WorkerThread.java:561)

              rhn-cservice-bbaranow Bartosz Baranowski
              pfyod_jira Pavels Fjodorovs (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              2 Start watching this issue

                Created:
                Updated:
                Resolved: