code: private static InputStream getInputStream(final Socket socket) throws IOException {
      final InputStream delegate = socket.getInputStream();
      return new InputStream() {
        @Override public void close() throws IOException {
          synchronized (socket) {
            socket.shutdownInput();
            if (socket.isOutputShutdown()) {
              socket.close();
            }
          }
        }
        
        // Boring delegates from here on down
        @Override public int read() throws IOException {
          return delegate.read();
        }
        
        @Override public int read(byte[] b) throws IOException {
          return delegate.read(b);
        }
        
        @Override public int read(byte[] b, int off, int len) throws IOException {
          return delegate.read(b, off, len);
        }
        
        @Override public long skip(long n) throws IOException {
          return delegate.skip(n);
        }
        
        @Override public int available() throws IOException {
          return delegate.available();
        }
        
        @Override public void mark(int readlimit) {
          delegate.mark(readlimit);
        }
        
        @Override public void reset() throws IOException {
          delegate.reset();
        }
        
        @Override public boolean markSupported() {
          return delegate.markSupported();
        }
      };
    }
docs: Returns an {@link InputStream} for the socket, but unlike {@link Socket#getInputStream()}
  when you call {@link InputStream#close() close} it only closes the input end of the socket
  instead of the entire socket.