/* (c) 2014 Open Source Geospatial Foundation - all rights reserved
* (c) 2001 - 2013 OpenPlans
* This code is licensed under the GPL 2.0 license, available at the root
* application directory.
*/
package org.geoserver.monitor;
import java.io.BufferedReader;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import javax.servlet.ServletInputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
public class MonitorServletRequest extends HttpServletRequestWrapper {
/**
* Don't restrict the maximum length of a request body.
*/
public static final long BODY_SIZE_UNBOUNDED = -1;
MonitorInputStream input;
long maxSize;
public MonitorServletRequest(HttpServletRequest request, long maxSize) {
super(request);
this.maxSize = maxSize;
}
public byte[] getBodyContent() throws IOException {
MonitorInputStream stream = getInputStream();
return stream.getData();
}
public long getBytesRead(){
try {
MonitorInputStream stream = getInputStream();
return stream.getBytesRead();
} catch (IOException ex) {
return 0;
}
}
@Override
public MonitorInputStream getInputStream() throws IOException {
if (input == null) {
ServletInputStream delegateTo = super.getInputStream();
input = new MonitorInputStream(delegateTo, maxSize);
}
return input;
}
@Override
public BufferedReader getReader() throws IOException {
String encoding = getCharacterEncoding();
if (encoding == null) {
return new BufferedReader(new InputStreamReader(getInputStream()));
} else {
return new BufferedReader(new InputStreamReader(getInputStream(), encoding));
}
}
static class MonitorInputStream extends ServletInputStream {
ByteArrayOutputStream buffer;
ServletInputStream delegate;
long nbytes = 0;
long maxSize;
public MonitorInputStream(ServletInputStream delegate, long maxSize) {
this.delegate = delegate;
this.maxSize = maxSize;
if (maxSize > 0) {
buffer = new ByteArrayOutputStream();
}
}
public int available() throws IOException {
return delegate.available();
}
public void close() throws IOException {
delegate.close();
}
public void mark(int readlimit) {
delegate.mark(readlimit);
}
public boolean markSupported() {
return delegate.markSupported();
}
public void reset() throws IOException {
delegate.reset();
}
public long skip(long n) throws IOException {
nbytes += n;
return delegate.skip(n);
}
@Override
public int read() throws IOException {
int b = delegate.read();
if (!bufferIsFull()) {
buffer.write((byte) b);
}
if(b>=0) nbytes += 1; // Increment byte count unless EoF marker
return b;
}
@Override
public int read(byte[] b) throws IOException {
int n = delegate.read(b);
fill(b, 0, n);
nbytes += n;
return n;
}
@Override
public int read(byte[] b, int off, int len) throws IOException {
int n = delegate.read(b, off, len);
fill(b, off, n);
nbytes += n;
return n;
}
@Override
public int readLine(byte[] b, int off, int len) throws IOException {
int n = delegate.readLine(b, off, len);
fill(b, off, n);
nbytes += n;
return n;
}
void fill(byte[] b, int off, int len) {
if (len < 0)
return;
if (!bufferIsFull()) {
if (maxSize > 0) {
long residual = maxSize - buffer.size();
len = len < residual ? len : (int) residual;
}
buffer.write(b, off, len);
}
}
boolean bufferIsFull() {
return maxSize == 0 || (buffer.size() >= maxSize && maxSize > 0);
}
public byte[] getData() {
return buffer == null ? new byte[0] : buffer.toByteArray();
}
public long getBytesRead() {
return nbytes;
}
public void dispose() {
buffer = null;
delegate = null;
}
}
}