[OLINGO-729] Better support of RFC1341 Multipart for

This commit is contained in:
Michael Bolz 2015-07-07 22:43:18 +02:00
parent 3a103d5342
commit 925a86d963
6 changed files with 339 additions and 245 deletions

View File

@ -20,7 +20,6 @@ package org.apache.olingo.server.core.deserializer.batch;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.LinkedList;
import java.util.List;
@ -74,7 +73,7 @@ public class BatchParser {
private List<List<Line>> splitBodyParts(final InputStream in, final String boundary) throws IOException,
BatchDeserializerException {
final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(new InputStreamReader(in));
final BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(in);
final List<Line> message = reader.toLineList();
reader.close();

View File

@ -18,37 +18,41 @@
*/
package org.apache.olingo.server.core.deserializer.batch;
import org.apache.olingo.commons.api.format.ContentType;
import java.io.IOException;
import java.io.Reader;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;
public class BufferedReaderIncludingLineEndings extends Reader {
private static final char CR = '\r';
private static final char LF = '\n';
public class BufferedReaderIncludingLineEndings {
private static final byte CR = '\r';
private static final byte LF = '\n';
private static final int EOF = -1;
private static final int BUFFER_SIZE = 8192;
private Reader reader;
private char[] buffer;
public static final Charset DEFAULT_CHARSET = Charset.forName("UTF-8");
private InputStream reader;
private byte[] buffer;
private int offset = 0;
private int limit = 0;
public BufferedReaderIncludingLineEndings(final Reader reader) {
public BufferedReaderIncludingLineEndings(final InputStream reader) {
this(reader, BUFFER_SIZE);
}
public BufferedReaderIncludingLineEndings(final Reader reader, final int bufferSize) {
public BufferedReaderIncludingLineEndings(final InputStream reader, final int bufferSize) {
if (bufferSize <= 0) {
throw new IllegalArgumentException("Buffer size must be greater than zero.");
}
this.reader = reader;
buffer = new char[bufferSize];
buffer = new byte[bufferSize];
}
@Override
public int read(final char[] charBuffer, final int bufferOffset, final int length) throws IOException {
if ((bufferOffset + length) > charBuffer.length) {
public int read(final byte[] byteBuffer, final int bufferOffset, final int length) throws IOException {
if ((bufferOffset + length) > byteBuffer.length) {
throw new IndexOutOfBoundsException("Buffer is too small");
}
@ -86,7 +90,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
bytesToRead -= readByte;
for (int i = 0; i < readByte; i++) {
charBuffer[currentOutputOffset++] = buffer[offset++];
byteBuffer[currentOutputOffset++] = buffer[offset++];
}
}
}
@ -105,6 +109,27 @@ public class BufferedReaderIncludingLineEndings extends Reader {
return result;
}
private Charset currentCharset = DEFAULT_CHARSET;
private void updateCurrentCharset(String currentLine) {
if(currentLine != null) {
if(currentLine.startsWith("Content-Type:") && currentLine.contains(ContentType.PARAMETER_CHARSET)) {
currentLine = currentLine.substring(13, currentLine.length()-2).trim();
ContentType t = ContentType.parse(currentLine);
if(t != null) {
String charsetString = t.getParameter(ContentType.PARAMETER_CHARSET);
currentCharset = Charset.forName(charsetString);
}
} else if(isEndBoundary(currentLine)) {
currentCharset = Charset.forName("us-ascii");
}
}
}
private boolean isEndBoundary(String currentLine) {
return false;
}
public List<Line> toLineList() throws IOException {
final List<Line> result = new ArrayList<Line>();
String currentLine;
@ -122,7 +147,7 @@ public class BufferedReaderIncludingLineEndings extends Reader {
return null;
}
final StringBuilder stringBuffer = new StringBuilder();
ByteBuffer buffer = ByteBuffer.allocate(BUFFER_SIZE);
boolean foundLineEnd = false; // EOF will be considered as line ending
while (!foundLineEnd) {
@ -134,8 +159,14 @@ public class BufferedReaderIncludingLineEndings extends Reader {
}
if (!foundLineEnd) {
char currentChar = buffer[offset++];
stringBuffer.append(currentChar);
byte currentChar = this.buffer[offset++];
if(!buffer.hasRemaining()) {
buffer.flip();
ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
tmp.put(buffer);
buffer = tmp;
}
buffer.put(currentChar);
if (currentChar == LF) {
foundLineEnd = true;
@ -149,44 +180,27 @@ public class BufferedReaderIncludingLineEndings extends Reader {
}
// Check if there is at least one character
if (limit != EOF && buffer[offset] == LF) {
stringBuffer.append(LF);
if (limit != EOF && this.buffer[offset] == LF) {
buffer.put(LF);
offset++;
}
}
}
}
return (stringBuffer.length() == 0) ? null : stringBuffer.toString();
if(buffer.position() == 0) {
return null;
} else {
String currentLine = new String(buffer.array(), 0, buffer.position(), getCurrentCharset());
updateCurrentCharset(currentLine);
return currentLine;
}
}
@Override
public void close() throws IOException {
reader.close();
}
@Override
public boolean ready() throws IOException {
// Not EOF and buffer refill is not required
return !isEOF() && !(limit == offset);
}
@Override
public void reset() throws IOException {
throw new IOException("Reset is not supported");
}
@Override
public void mark(final int readAheadLimit) throws IOException {
throw new IOException("Mark is not supported");
}
@Override
public boolean markSupported() {
return false;
}
@Override
public long skip(final long n) throws IOException {
if (n == 0) {
return 0;
@ -230,4 +244,8 @@ public class BufferedReaderIncludingLineEndings extends Reader {
return limit;
}
private Charset getCurrentCharset() {
return currentCharset;
}
}

View File

@ -22,11 +22,14 @@ import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.nio.ByteBuffer;
import java.nio.charset.Charset;
import java.util.List;
import java.util.Map;
import java.util.UUID;
import org.apache.olingo.commons.api.ODataRuntimeException;
import org.apache.olingo.commons.api.format.ContentType;
import org.apache.olingo.commons.api.http.HttpContentType;
import org.apache.olingo.commons.api.http.HttpHeader;
import org.apache.olingo.commons.api.http.HttpStatusCode;
@ -45,14 +48,14 @@ public class BatchResponseSerializer {
public InputStream serialize(final List<ODataResponsePart> responses, final String boundary)
throws BatchSerializerException {
StringBuilder builder = createBody(responses, boundary);
BodyBuilder builder = createBody(responses, boundary);
return new ByteArrayInputStream(builder.toString().getBytes());
return new ByteArrayInputStream(builder.getContent());
}
private StringBuilder createBody(final List<ODataResponsePart> batchResponses, final String boundary)
private BodyBuilder createBody(final List<ODataResponsePart> batchResponses, final String boundary)
throws BatchSerializerException {
final StringBuilder builder = new StringBuilder();
final BodyBuilder builder = new BodyBuilder();
for (final ODataResponsePart part : batchResponses) {
builder.append(getDashBoundary(boundary));
@ -68,7 +71,7 @@ public class BatchResponseSerializer {
return builder;
}
private void appendChangeSet(final ODataResponsePart part, final StringBuilder builder)
private void appendChangeSet(final ODataResponsePart part, final BodyBuilder builder)
throws BatchSerializerException {
final String changeSetBoundary = generateBoundary("changeset");
@ -83,21 +86,154 @@ public class BatchResponseSerializer {
builder.append(getCloseDelimiter(changeSetBoundary));
}
private void appendBodyPart(final ODataResponse response, final StringBuilder builder, final boolean isChangeSet)
private void appendBodyPart(final ODataResponse response, final BodyBuilder builder, final boolean isChangeSet)
throws BatchSerializerException {
byte[] body = getBody(response);
appendBodyPartHeader(response, builder, isChangeSet);
builder.append(CRLF);
appendStatusLine(response, builder);
appendResponseHeader(response, body.length, builder);
Body body = new Body(response);
appendResponseHeader(response, body.getLength(), builder);
builder.append(CRLF);
builder.append(new String(body));
builder.append(body);
builder.append(CRLF);
}
private void appendChangeSetHeader(final BodyBuilder builder, final String changeSetBoundary) {
appendHeader(HttpHeader.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + "; boundary="
+ changeSetBoundary, builder);
}
private void appendHeader(final String name, final String value, final BodyBuilder builder) {
builder.append(name)
.append(COLON)
.append(SP)
.append(value)
.append(CRLF);
}
private void appendStatusLine(final ODataResponse response, final BodyBuilder builder) {
builder.append("HTTP/1.1")
.append(SP)
.append(response.getStatusCode())
.append(SP)
.append(HttpStatusCode.fromStatusCode(response.getStatusCode()).toString())
.append(CRLF);
}
private void appendResponseHeader(final ODataResponse response, final int contentLength,
final BodyBuilder builder) {
final Map<String, String> header = response.getHeaders();
for (final String key : header.keySet()) {
// Requests do never has a content id header
if (!key.equalsIgnoreCase(HttpHeader.CONTENT_ID)) {
appendHeader(key, header.get(key), builder);
}
}
appendHeader(HttpHeader.CONTENT_LENGTH, "" + contentLength, builder);
}
private void appendBodyPartHeader(final ODataResponse response, final BodyBuilder builder,
final boolean isChangeSet) throws BatchSerializerException {
appendHeader(HttpHeader.CONTENT_TYPE, HttpContentType.APPLICATION_HTTP, builder);
appendHeader(BatchParserCommon.CONTENT_TRANSFER_ENCODING, BatchParserCommon.BINARY_ENCODING, builder);
if (isChangeSet) {
if (response.getHeaders().get(HttpHeader.CONTENT_ID) != null) {
appendHeader(HttpHeader.CONTENT_ID, response.getHeaders().get(HttpHeader.CONTENT_ID), builder);
} else {
throw new BatchSerializerException("Missing content id", MessageKeys.MISSING_CONTENT_ID);
}
}
}
private String getDashBoundary(final String boundary) {
return DOUBLE_DASH + boundary + CRLF;
}
private String getCloseDelimiter(final String boundary) {
return DOUBLE_DASH + boundary + DOUBLE_DASH + CRLF;
}
private String generateBoundary(final String value) {
return value + "_" + UUID.randomUUID().toString();
}
private class BodyBuilder {
private final Charset CHARSET_UTF_8 = Charset.forName("utf-8");
private ByteBuffer buffer = ByteBuffer.allocate(8192);
private boolean isClosed = false;
public byte[] getContent() {
isClosed = true;
byte[] tmp = new byte[buffer.position()];
buffer.flip();
buffer.get(tmp, 0, buffer.limit());
return tmp;
}
public BodyBuilder append(String string) {
byte [] b = string.getBytes(CHARSET_UTF_8);
put(b);
return this;
}
private void put(byte[] b) {
if(isClosed) {
throw new RuntimeException("BodyBuilder is closed.");
}
if(buffer.remaining() < b.length) {
buffer.flip();
ByteBuffer tmp = ByteBuffer.allocate(buffer.limit() *2);
tmp.put(buffer);
buffer = tmp;
}
buffer.put(b);
}
public BodyBuilder append(int statusCode) {
return append(String.valueOf(statusCode));
}
public BodyBuilder append(Body body) {
put(body.getContent());
return this;
}
public String toString() {
// byte[] tmp = new byte[buffer.position()];
// buffer.get(tmp, 0, buffer.position());
return new String(buffer.array(), 0, buffer.position());
}
}
private class Body {
private final Charset CHARSET_DEFAULT = Charset.forName("utf-8");
private final byte[] content;
private Charset charset = CHARSET_DEFAULT;
public Body(ODataResponse response) {
this.content = getBody(response);
String contentType = response.getHeaders().get(HttpHeader.CONTENT_TYPE);
if(contentType != null) {
ContentType ct = ContentType.create(contentType);
if(ct != null) {
String usedCharset = ct.getParameter(ContentType.PARAMETER_CHARSET);
if(usedCharset != null) {
this.charset = Charset.forName(usedCharset);
}
}
}
}
public int getLength() {
return content.length;
}
private byte[] getBody(final ODataResponse response) {
final InputStream content = response.getContent();
final ByteArrayOutputStream out = new ByteArrayOutputStream();
@ -121,65 +257,8 @@ public class BatchResponseSerializer {
}
}
private void appendChangeSetHeader(final StringBuilder builder, final String changeSetBoundary) {
appendHeader(HttpHeader.CONTENT_TYPE, HttpContentType.MULTIPART_MIXED + "; boundary="
+ changeSetBoundary, builder);
public byte[] getContent() {
return content;
}
private void appendHeader(final String name, final String value, final StringBuilder builder) {
builder.append(name)
.append(COLON)
.append(SP)
.append(value)
.append(CRLF);
}
private void appendStatusLine(final ODataResponse response, final StringBuilder builder) {
builder.append("HTTP/1.1")
.append(SP)
.append(response.getStatusCode())
.append(SP)
.append(HttpStatusCode.fromStatusCode(response.getStatusCode()).toString())
.append(CRLF);
}
private void appendResponseHeader(final ODataResponse response, final int contentLength,
final StringBuilder builder) {
final Map<String, String> header = response.getHeaders();
for (final String key : header.keySet()) {
// Requests do never has a content id header
if (!key.equalsIgnoreCase(HttpHeader.CONTENT_ID)) {
appendHeader(key, header.get(key), builder);
}
}
appendHeader(HttpHeader.CONTENT_LENGTH, "" + contentLength, builder);
}
private void appendBodyPartHeader(final ODataResponse response, final StringBuilder builder,
final boolean isChangeSet) throws BatchSerializerException {
appendHeader(HttpHeader.CONTENT_TYPE, HttpContentType.APPLICATION_HTTP, builder);
appendHeader(BatchParserCommon.CONTENT_TRANSFER_ENCODING, BatchParserCommon.BINARY_ENCODING, builder);
if (isChangeSet) {
if (response.getHeaders().get(HttpHeader.CONTENT_ID) != null) {
appendHeader(HttpHeader.CONTENT_ID, response.getHeaders().get(HttpHeader.CONTENT_ID), builder);
} else {
throw new BatchSerializerException("Missing content id", MessageKeys.MISSING_CONTENT_ID);
}
}
}
private String getDashBoundary(final String boundary) {
return DOUBLE_DASH + boundary + CRLF;
}
private String getCloseDelimiter(final String boundary) {
return DOUBLE_DASH + boundary + DOUBLE_DASH + CRLF;
}
private String generateBoundary(final String value) {
return value + "_" + UUID.randomUUID().toString();
}
}

View File

@ -26,7 +26,6 @@ import static org.mockito.Mockito.when;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
@ -150,7 +149,7 @@ public class MockedBatchHandlerTest {
batchHandler.process(request, response, true);
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
new BufferedReaderIncludingLineEndings(response.getContent());
final List<String> responseContent = reader.toList();
reader.close();
@ -221,7 +220,7 @@ public class MockedBatchHandlerTest {
batchHandler.process(request, response, true);
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
new BufferedReaderIncludingLineEndings(response.getContent());
final List<String> responseContent = reader.toList();
int line = 0;
@ -300,7 +299,7 @@ public class MockedBatchHandlerTest {
batchHandler.process(request, response, true);
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
new BufferedReaderIncludingLineEndings(response.getContent());
final List<String> responseContent = reader.toList();
reader.close();
@ -418,7 +417,7 @@ public class MockedBatchHandlerTest {
batchHandler.process(request, response, true);
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(response.getContent()));
new BufferedReaderIncludingLineEndings(response.getContent());
final List<String> responseContent = reader.toList();
reader.close();

View File

@ -24,7 +24,6 @@ import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStreamReader;
import java.util.List;
import org.junit.Test;
@ -71,7 +70,7 @@ public class BufferedReaderIncludingLineEndingsTest {
@Test
public void testNoBytes() throws Exception {
BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(new byte[0])));
new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(new byte[0]));
assertNull(reader.readLine());
assertNull(reader.readLine());
@ -246,7 +245,7 @@ public class BufferedReaderIncludingLineEndingsTest {
@Test
public void testReadMoreBufferCapacityThanCharacterAvailable() throws Exception {
final String TEXT = "Foo";
char[] buffer = new char[20];
byte[] buffer = new byte[20];
BufferedReaderIncludingLineEndings reader = create(TEXT);
assertEquals(3, reader.read(buffer, 0, 20));
@ -274,109 +273,15 @@ public class BufferedReaderIncludingLineEndingsTest {
reader.close();
}
@Test
public void testSkipToMuch() throws Exception {
BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
assertEquals(8, reader.skip(10)); // Test\r
assertEquals(null, reader.readLine());
reader.close();
}
@Test
public void testReadBufferOne() throws Exception {
BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
assertEquals('T', reader.read());
assertEquals('e', reader.read());
assertEquals('s', reader.read());
assertEquals('t', reader.read());
assertEquals('\r', reader.read());
assertEquals('1', reader.read());
assertEquals('2', reader.read());
assertEquals('3', reader.read());
assertEquals(-1, reader.read());
assertEquals(-1, reader.read());
}
@Test
public void testReadZeroBytes() throws Exception {
BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL, 1);
char[] buffer = new char[3];
assertEquals(0, reader.read(buffer, 0, 0));
assertEquals('T', reader.read());
assertEquals(0, reader.read(buffer, 0, 0));
assertEquals("est\r", reader.readLine());
assertEquals("123", reader.readLine());
reader.close();
}
@Test
public void testRead() throws Exception {
BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
assertEquals('T', reader.read());
assertEquals('e', reader.read());
assertEquals('s', reader.read());
assertEquals('t', reader.read());
assertEquals('\r', reader.read());
assertEquals('1', reader.read());
assertEquals('2', reader.read());
assertEquals('3', reader.read());
assertEquals(-1, reader.read());
assertEquals(-1, reader.read());
}
@Test(expected = IndexOutOfBoundsException.class)
public void testFailReadBufferAndOffsetBiggerThanBuffer() throws Exception {
BufferedReaderIncludingLineEndings reader = create("");
final char[] buffer = new char[3];
reader.read(buffer, 1, 3);
}
@Test(expected = IndexOutOfBoundsException.class)
public void testFailLengthNegative() throws Exception {
final char[] buffer = new char[3];
BufferedReaderIncludingLineEndings reader = create("123");
reader.read(buffer, 1, -2);
reader.close();
}
@Test(expected = IndexOutOfBoundsException.class)
public void testFailOffsetNegative() throws Exception {
final char[] buffer = new char[3];
BufferedReaderIncludingLineEndings reader = create("123");
reader.read(buffer, -1, 2);
reader.close();
}
@Test
public void testReadAndReadLine() throws Exception {
final String TEXT = "Test\r" +
"bar\n" +
"123\r\n" +
"foo";
BufferedReaderIncludingLineEndings reader = create(TEXT);
assertEquals('T', reader.read());
assertEquals('e', reader.read());
assertEquals('s', reader.read());
assertEquals('t', reader.read());
assertEquals("\r", reader.readLine());
assertEquals("bar\n", reader.readLine());
assertEquals('1', reader.read());
assertEquals('2', reader.read());
assertEquals("3\r\n", reader.readLine());
assertEquals("foo", reader.readLine());
assertEquals(null, reader.readLine());
assertEquals(-1, reader.read());
}
// @Test
// public void testSkipToMuch() throws Exception {
// BufferedReaderIncludingLineEndings reader = create(TEXT_SMALL);
//
// assertEquals(8, reader.skip(10)); // Test\r
// assertEquals(null, reader.readLine());
// reader.close();
// }
//
@Test
public void testLineEqualsAndHashCode() {
@ -389,11 +294,11 @@ public class BufferedReaderIncludingLineEndingsTest {
assertTrue(l1.hashCode() != l3.hashCode());
}
@Test(expected = IllegalArgumentException.class)
public void testSkipNegative() throws Exception {
BufferedReaderIncludingLineEndings reader = create("123");
reader.skip(-1);
}
// @Test(expected = IllegalArgumentException.class)
// public void testSkipNegative() throws Exception {
// BufferedReaderIncludingLineEndings reader = create("123");
// reader.skip(-1);
// }
@Test(expected = IllegalArgumentException.class)
public void testFailBufferSizeZero() throws Exception {
@ -401,52 +306,33 @@ public class BufferedReaderIncludingLineEndingsTest {
reader.close();
}
@Test(expected = NullPointerException.class)
public void testInputStreamIsNull() throws Exception {
// Same behaviour like BufferedReader
BufferedReaderIncludingLineEndings reader = new BufferedReaderIncludingLineEndings(null);
reader.close();
}
@Test(expected = IllegalArgumentException.class)
public void testFailBufferSizeNegative() throws Exception {
BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY, -1);
reader.close();
}
@Test
public void testMarkSupoorted() throws Exception {
BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY);
// @Test
// public void testMarkSupoorted() throws Exception {
// BufferedReaderIncludingLineEndings reader = create(TEXT_EMPTY);
//
// assertEquals(false, reader.markSupported());
// reader.close();
// }
assertEquals(false, reader.markSupported());
reader.close();
}
@Test(expected = Exception.class)
public void testFailMark() throws Exception {
BufferedReaderIncludingLineEndings reader = create("123");
reader.mark(1);
}
@Test(expected = Exception.class)
public void testFailReset() throws Exception {
BufferedReaderIncludingLineEndings reader = create("123");
reader.reset();
}
@Test
public void testReady() throws Exception {
BufferedReaderIncludingLineEndings reader = create("123\r123");
assertEquals(false, reader.ready());
assertEquals("123\r", reader.readLine());
assertEquals(true, reader.ready());
assertEquals("123", reader.readLine());
assertEquals(false, reader.ready());
reader.close();
}
// @Test(expected = Exception.class)
// public void testFailMark() throws Exception {
// BufferedReaderIncludingLineEndings reader = create("123");
//
// reader.mark(1);
// }
//
// @Test(expected = Exception.class)
// public void testFailReset() throws Exception {
// BufferedReaderIncludingLineEndings reader = create("123");
//
// reader.reset();
// }
@Test
public void testToList() throws Exception {
@ -469,13 +355,13 @@ public class BufferedReaderIncludingLineEndingsTest {
}
private BufferedReaderIncludingLineEndings create(final String inputString) throws Exception {
return new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(inputString
.getBytes("UTF-8"))));
return new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(inputString
.getBytes("UTF-8")));
}
private BufferedReaderIncludingLineEndings create(final String inputString, final int bufferSize) throws Exception {
return new BufferedReaderIncludingLineEndings(new InputStreamReader(new ByteArrayInputStream(inputString
.getBytes("UTF-8"))), bufferSize);
return new BufferedReaderIncludingLineEndings(new ByteArrayInputStream(inputString
.getBytes("UTF-8")), bufferSize);
}
}

View File

@ -22,8 +22,8 @@ import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.assertTrue;
import java.io.ByteArrayInputStream;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
@ -64,7 +64,7 @@ public class BatchResponseSerializerTest {
final InputStream content = serializer.serialize(parts, BOUNDARY);
assertNotNull(content);
final BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
new BufferedReaderIncludingLineEndings(content);
final List<String> body = reader.toList();
reader.close();
@ -96,6 +96,119 @@ public class BatchResponseSerializerTest {
assertTrue(body.get(line++).contains("--batch_"));
}
@Test
public void testBatchResponseUmlauteUtf8() throws Exception {
final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
ODataResponse response = new ODataResponse();
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE,
ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=UTF-8");
response.setContent(IOUtils.toInputStream("Wälter Winter" + CRLF));
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
parts.add(new ODataResponsePart(responses, false));
ODataResponse changeSetResponse = new ODataResponse();
changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
responses = new ArrayList<ODataResponse>(1);
responses.add(changeSetResponse);
parts.add(new ODataResponsePart(responses, true));
BatchResponseSerializer serializer = new BatchResponseSerializer();
final InputStream content = serializer.serialize(parts, BOUNDARY);
assertNotNull(content);
final BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(content);
final List<String> body = reader.toList();
reader.close();
int line = 0;
assertEquals(24, body.size());
assertTrue(body.get(line++).contains("--batch_"));
assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
assertEquals("Content-Type: application/json; charset=UTF-8" + CRLF, body.get(line++));
assertEquals("Content-Length: 16" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals("Wälter Winter" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertTrue(body.get(line++).contains("--batch_"));
assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
assertEquals(CRLF, body.get(line++));
assertTrue(body.get(line++).contains("--changeset_"));
assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
assertEquals("Content-ID: 1" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
assertEquals("Content-Length: 0" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertTrue(body.get(line++).contains("--changeset_"));
assertTrue(body.get(line++).contains("--batch_"));
}
@Test
public void testBatchResponseUmlauteIso() throws Exception {
final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
ODataResponse response = new ODataResponse();
response.setStatusCode(HttpStatusCode.OK.getStatusCode());
response.setHeader(HttpHeader.CONTENT_TYPE,
ContentType.APPLICATION_JSON.toContentTypeString() + "; charset=iso-8859-1");
byte[] payload = ("Wälter Winter" + CRLF).getBytes("iso-8859-1");
response.setContent(new ByteArrayInputStream(payload));
List<ODataResponse> responses = new ArrayList<ODataResponse>(1);
responses.add(response);
parts.add(new ODataResponsePart(responses, false));
ODataResponse changeSetResponse = new ODataResponse();
changeSetResponse.setStatusCode(HttpStatusCode.NO_CONTENT.getStatusCode());
changeSetResponse.setHeader(HttpHeader.CONTENT_ID, "1");
responses = new ArrayList<ODataResponse>(1);
responses.add(changeSetResponse);
parts.add(new ODataResponsePart(responses, true));
BatchResponseSerializer serializer = new BatchResponseSerializer();
final InputStream content = serializer.serialize(parts, BOUNDARY);
assertNotNull(content);
final BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(content);
final List<String> body = reader.toList();
reader.close();
int line = 0;
assertEquals(24, body.size());
assertTrue(body.get(line++).contains("--batch_"));
assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals("HTTP/1.1 200 OK" + CRLF, body.get(line++));
assertEquals("Content-Type: application/json; charset=iso-8859-1" + CRLF, body.get(line++));
assertEquals("Content-Length: 15" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals("Wälter Winter" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertTrue(body.get(line++).contains("--batch_"));
assertTrue(body.get(line++).contains("Content-Type: multipart/mixed; boundary=changeset_"));
assertEquals(CRLF, body.get(line++));
assertTrue(body.get(line++).contains("--changeset_"));
assertEquals("Content-Type: application/http" + CRLF, body.get(line++));
assertEquals("Content-Transfer-Encoding: binary" + CRLF, body.get(line++));
assertEquals("Content-ID: 1" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals("HTTP/1.1 204 No Content" + CRLF, body.get(line++));
assertEquals("Content-Length: 0" + CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertEquals(CRLF, body.get(line++));
assertTrue(body.get(line++).contains("--changeset_"));
assertTrue(body.get(line++).contains("--batch_"));
}
@Test
public void testBatchResponseWithEndingCRLF() throws Exception {
final List<ODataResponsePart> parts = new ArrayList<ODataResponsePart>();
@ -119,7 +232,7 @@ public class BatchResponseSerializerTest {
final InputStream content = serializer.serialize(parts, BOUNDARY);
assertNotNull(content);
final BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
new BufferedReaderIncludingLineEndings(content);
final List<String> body = reader.toList();
reader.close();
@ -167,7 +280,7 @@ public class BatchResponseSerializerTest {
assertNotNull(content);
final BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
new BufferedReaderIncludingLineEndings(content);
final List<String> body = reader.toList();
reader.close();
@ -202,7 +315,7 @@ public class BatchResponseSerializerTest {
assertNotNull(content);
final BufferedReaderIncludingLineEndings reader =
new BufferedReaderIncludingLineEndings(new InputStreamReader(content));
new BufferedReaderIncludingLineEndings(content);
final List<String> body = reader.toList();
reader.close();