INT-1396 DefaultInboundRequestMapper now properly handles reading large byte payloads from request input streams
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -16,6 +16,7 @@
|
|||||||
|
|
||||||
package org.springframework.integration.http;
|
package org.springframework.integration.http;
|
||||||
|
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.ObjectInputStream;
|
import java.io.ObjectInputStream;
|
||||||
@@ -225,7 +226,8 @@ public class DefaultInboundRequestMapper implements InboundRequestMapper {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private byte[] createPayloadFromInputStream(HttpServletRequest request) throws Exception {
|
private byte[] createPayloadFromInputStream(HttpServletRequest request) throws Exception {
|
||||||
InputStream stream = request.getInputStream();
|
int bufferSize = 4096;
|
||||||
|
InputStream in = request.getInputStream();
|
||||||
int length = request.getContentLength();
|
int length = request.getContentLength();
|
||||||
if (length == -1) {
|
if (length == -1) {
|
||||||
throw new ResponseStatusCodeException(HttpServletResponse.SC_LENGTH_REQUIRED);
|
throw new ResponseStatusCodeException(HttpServletResponse.SC_LENGTH_REQUIRED);
|
||||||
@@ -234,9 +236,13 @@ public class DefaultInboundRequestMapper implements InboundRequestMapper {
|
|||||||
logger.debug("received " + request.getMethod() + " request, "
|
logger.debug("received " + request.getMethod() + " request, "
|
||||||
+ "creating byte array payload with content lenth: " + length);
|
+ "creating byte array payload with content lenth: " + length);
|
||||||
}
|
}
|
||||||
byte[] bytes = new byte[length];
|
ByteArrayOutputStream out = new ByteArrayOutputStream(bufferSize);
|
||||||
stream.read(bytes, 0, length);
|
byte[] buffer = new byte[bufferSize];
|
||||||
return bytes;
|
int bytesRead = -1;
|
||||||
|
while ((bytesRead = in.read(buffer)) != -1) {
|
||||||
|
out.write(buffer, 0, bytesRead);
|
||||||
|
}
|
||||||
|
return out.toByteArray();
|
||||||
}
|
}
|
||||||
|
|
||||||
private void populateHeaders(HttpServletRequest request, MessageBuilder<?> builder) {
|
private void populateHeaders(HttpServletRequest request, MessageBuilder<?> builder) {
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2009 the original author or authors.
|
* Copyright 2002-2011 the original author or authors.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
@@ -13,11 +13,23 @@
|
|||||||
* See the License for the specific language governing permissions and
|
* See the License for the specific language governing permissions and
|
||||||
* limitations under the License.
|
* limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package org.springframework.integration.http;
|
package org.springframework.integration.http;
|
||||||
|
|
||||||
|
import static org.easymock.EasyMock.createMock;
|
||||||
|
import static org.easymock.EasyMock.expect;
|
||||||
|
import static org.easymock.EasyMock.replay;
|
||||||
import static org.hamcrest.CoreMatchers.is;
|
import static org.hamcrest.CoreMatchers.is;
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
import static org.junit.Assert.assertThat;
|
import static org.junit.Assert.assertThat;
|
||||||
|
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.InputStream;
|
||||||
|
import java.util.concurrent.atomic.AtomicInteger;
|
||||||
|
|
||||||
|
import javax.servlet.ServletInputStream;
|
||||||
|
import javax.servlet.http.HttpServletRequest;
|
||||||
|
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import org.springframework.integration.core.Message;
|
import org.springframework.integration.core.Message;
|
||||||
import org.springframework.mock.web.MockHttpServletRequest;
|
import org.springframework.mock.web.MockHttpServletRequest;
|
||||||
@@ -81,4 +93,68 @@ public class DefaultInboundRequestMapperTests {
|
|||||||
assertThat(message.getPayload(), is(content));
|
assertThat(message.getPayload(), is(content));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void largeStreamTest() throws Exception {
|
||||||
|
final int size = 100000;
|
||||||
|
final byte[] content = new byte[size];
|
||||||
|
for (int i = 0; i < size; i++) {
|
||||||
|
content[i] = 7;
|
||||||
|
}
|
||||||
|
HttpServletRequest request = createMock(HttpServletRequest.class);
|
||||||
|
final InputStream inputStream = new InputStream() {
|
||||||
|
private final AtomicInteger next = new AtomicInteger(0);
|
||||||
|
public int read() throws IOException {
|
||||||
|
if (next.get() >= size) {
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
int index = next.getAndIncrement();
|
||||||
|
return content[index];
|
||||||
|
}
|
||||||
|
};
|
||||||
|
expect(request.getInputStream()).andReturn(new ServletInputStream() {
|
||||||
|
public int read(byte[] b) throws IOException {
|
||||||
|
int length = b.length;
|
||||||
|
if (length > 99990) {
|
||||||
|
length = 99990;
|
||||||
|
}
|
||||||
|
byte[] temp = new byte[length];
|
||||||
|
int numRead = inputStream.read(temp);
|
||||||
|
for (int i = 0; i < numRead; i++) {
|
||||||
|
b[i] = temp[i];
|
||||||
|
}
|
||||||
|
return numRead;
|
||||||
|
}
|
||||||
|
public int read(byte[] b, int off, int length) throws IOException {
|
||||||
|
if (length > 99990) {
|
||||||
|
length = 99990;
|
||||||
|
}
|
||||||
|
byte[] temp = new byte[length];
|
||||||
|
int numRead = inputStream.read(temp, 0, length);
|
||||||
|
for (int i = 0; i < numRead; i++) {
|
||||||
|
b[off + i] = temp[i];
|
||||||
|
}
|
||||||
|
return numRead;
|
||||||
|
}
|
||||||
|
public int read() throws IOException {
|
||||||
|
return inputStream.read();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
expect(request.getContentType()).andReturn(null);
|
||||||
|
expect(request.getMethod()).andReturn("POST").anyTimes();
|
||||||
|
expect(request.getContentLength()).andReturn(size);
|
||||||
|
expect(request.getHeaderNames()).andReturn(null);
|
||||||
|
expect(request.getRequestURL()).andReturn(new StringBuffer("http://test"));
|
||||||
|
expect(request.getUserPrincipal()).andReturn(null);
|
||||||
|
replay(request);
|
||||||
|
Message<?> message = mapper.toMessage(request);
|
||||||
|
byte[] payload = (byte[]) message.getPayload();
|
||||||
|
int byteValueCounter = 0;
|
||||||
|
for (byte b : payload) {
|
||||||
|
if (b == 7) {
|
||||||
|
byteValueCounter++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
assertEquals(size, byteValueCounter);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user