All Downloads are FREE. Search and download functionalities are using the official Maven repository.

fi.evolver.basics.spring.http.LoggingServletRequestWrapper Maven / Gradle / Ivy

package fi.evolver.basics.spring.http;

import java.io.*;
import java.util.zip.GZIPOutputStream;

import org.apache.commons.io.input.TeeInputStream;
import org.apache.commons.io.output.CountingOutputStream;

import jakarta.servlet.ReadListener;
import jakarta.servlet.ServletInputStream;
import jakarta.servlet.http.HttpServletRequest;
import jakarta.servlet.http.HttpServletRequestWrapper;

class LoggingServletRequestWrapper extends HttpServletRequestWrapper {

	private ByteArrayOutputStream baos;
	private GZIPOutputStream gzip;
	private CountingOutputStream countingOutputStream;

	private BufferedReader bufferedReader;
	private CopyingServletInputStream copyingServletInputStream;

	public LoggingServletRequestWrapper(HttpServletRequest request) throws IOException {
		super(request);
		baos = new ByteArrayOutputStream();
		gzip = new GZIPOutputStream(baos);
		countingOutputStream = new CountingOutputStream(gzip);
	}

	@Override
	@SuppressWarnings("resource")
	public BufferedReader getReader() throws IOException {
		if (bufferedReader == null) {
			String encoding = getCharacterEncoding();
			if (encoding == null) {
				encoding = "UTF-8";
			}
			bufferedReader = new BufferedReader(new CopyingReader(super.getReader(), countingOutputStream, encoding));
		}
		return bufferedReader;
	}

	@Override
	public ServletInputStream getInputStream() throws IOException {
		if (copyingServletInputStream == null) {
			copyingServletInputStream = new CopyingServletInputStream(super.getInputStream(), countingOutputStream);
		}
		return copyingServletInputStream;
	}

	public byte[] getGzippedRequest() throws IOException {
		if (bufferedReader != null) {
			while (bufferedReader.read() != -1) { /* Looping for read side effects */ }
		}
		if (copyingServletInputStream != null) {
			while (copyingServletInputStream.read() != -1) { /* Looping for read side effects */ }
		}

		gzip.finish();
		return baos.toByteArray();
	}

	public int getRequestLength() {
		if (countingOutputStream == null) {
			return 0;
		}
		return countingOutputStream.getCount();
	}

	private static class CopyingServletInputStream extends ServletInputStream {

		private final ServletInputStream input;
		private final TeeInputStream teeInputStream;

		public CopyingServletInputStream(ServletInputStream input, OutputStream branch) {
			this.input = input;
			this.teeInputStream = new TeeInputStream(input, branch);
		}

		@Override
		public int read() throws IOException {
			return teeInputStream.read();
		}

		@Override
		public boolean isFinished() {
			return input.isFinished();
		}

		@Override
		public boolean isReady() {
			return input.isReady();
		}

		@Override
		public void setReadListener(ReadListener readListener) {
			input.setReadListener(readListener);
		}

	}

	private static class CopyingReader extends Reader {

		private Writer writer;
		private Reader input;

		public CopyingReader(Reader input, OutputStream output, String encoding) throws UnsupportedEncodingException {
			this.input = input;
			this.writer = new OutputStreamWriter(output, encoding);
		}

		@Override
		public void close() throws IOException {
			input.close();
			writer.close();
		}

		@Override
		public int read(char[] cbuf, int off, int len) throws IOException {
			int read = input.read(cbuf, off, len);
			writer.write(cbuf, off, len);
			return read;
		}

	}

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy