Uploaded image for project: 'CXF'
  1. CXF
  2. CXF-8984

HttpClientHTTPConduit.HttpClientWrappedOutputStream throws NPE in closeInputStream()

    XMLWordPrintableJSON

Details

    • Bug
    • Status: Resolved
    • Major
    • Resolution: Fixed
    • 4.0.1, 4.0.2, 4.0.3
    • 3.6.3, 4.0.4
    • Transports
    • None
    • Unknown

    Description

      The package private class HttpClientWrappedOutputStream in org.apache.cxf.transport.http.HttpClientHTTPConduit implements the methods getInputStream() and closeInputStream().

      There are several paths where getInputStream() returns null. This will then lead to a NullPointerException in closeInputStream() because there is no null check.

              @Override
              protected InputStream getInputStream() throws IOException {
                  HttpResponse<InputStream> resp = getResponse();
                  String method = (String)outMessage.get(Message.HTTP_REQUEST_METHOD);
                  int sc = resp.statusCode();
                  if ("HEAD".equals(method)) {
                      try (InputStream in = resp.body()) {
                          return null;
                      }
                  }
                  if (sc == 204) {
                      //no content
                      return null;
                  }
                  if ("OPTIONS".equals(method) || (sc >= 300 && sc < 500)) {
                      Optional<String> f = resp.headers().firstValue("content-length");
                      Optional<String> fChunk = resp.headers().firstValue("transfer-encoding");
                      if (f.isPresent()) {
                          long l = Long.parseLong(f.get());
                          if (l == 0) {
                              try (InputStream in = resp.body()) {
                                  return null;
                              }
                          }
                      } else if (!fChunk.isPresent() || !"chunked".equals(fChunk.get())) {
                          if (resp.version() == Version.HTTP_2) {
                              InputStream in = resp.body();
                              if (in.available() <= 0) {
                                  try (in) {
                                      return null;
                                  }
                              }
                          } else {
                              try (InputStream in = resp.body()) {
                                  return null;
                              }
                          }
                      }
                  }
                  return new HttpClientFilteredInputStream(resp.body());
              }
              @Override
              protected void closeInputStream() throws IOException {
                  getInputStream().close();
              }
      

      We encountered this issue with SOAP WS POST requests that return status 204.
      A downgrade to 4.0.0 fixed it, as HttpClientHTTPConduit was introduced with 4.0.1.

       

      The fix looks (too?) easy:

              @Override
              protected void closeInputStream() throws IOException {
                  InputStream is = getInputStream();
                  if (is != null) {
                      is.close();
                  }
              }

       

      I will gladly create a PR for this, but maybe someone else can double-check if this is really as simple as it looks like
      Version 4.0.1 was released in May 2023, and it looks unlikely to me that no-one else stumbled upon this problem until now.

       

      Attachments

        Issue Links

          Activity

            People

              Unassigned Unassigned
              thegli Thomas Egli
              Votes:
              0 Vote for this issue
              Watchers:
              1 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved: