use of com.linkedin.multipart.exceptions.MultiPartIllegalFormatException in project rest.li by linkedin.
the class TestMIMEReaderExceptions method missingContentTypeHeader.
// These tests all verify that we throw the correct exception in the face of RFC violating bodies:
@Test
public void missingContentTypeHeader() {
StreamRequest streamRequest = null;
try {
streamRequest = mock(StreamRequest.class);
when(streamRequest.getHeader(MultiPartMIMEUtils.CONTENT_TYPE_HEADER)).thenReturn(null);
MultiPartMIMEReader.createAndAcquireStream(streamRequest);
Assert.fail();
} catch (MultiPartIllegalFormatException illegalMimeFormatException) {
Assert.assertEquals(illegalMimeFormatException.getMessage(), "Malformed multipart mime request. No Content-Type header in this request");
verify(streamRequest, times(1)).getHeader(MultiPartMIMEUtils.CONTENT_TYPE_HEADER);
}
}
use of com.linkedin.multipart.exceptions.MultiPartIllegalFormatException in project rest.li by linkedin.
the class MultiPartMIMEUtils method extractBoundary.
static String extractBoundary(final String contentTypeHeader) throws MultiPartIllegalFormatException {
if (!contentTypeHeader.toLowerCase().startsWith(MultiPartMIMEUtils.MULTIPART_PREFIX)) {
throw new MultiPartIllegalFormatException("Malformed multipart mime request. Not a valid multipart mime header.");
}
if (!contentTypeHeader.contains(";")) {
throw new MultiPartIllegalFormatException("Malformed multipart mime request. Improperly formatted Content-Type header. " + "Expected at least one parameter in addition to the content type.");
}
final String[] contentTypeParameters = contentTypeHeader.split(";");
// In case someone used something like bOuNdArY
final Map<String, String> parameterMap = new TreeMap<>(String.CASE_INSENSITIVE_ORDER);
for (final String parameter : contentTypeParameters) {
// We don't need the first bit here.
if (parameter.startsWith(MULTIPART_PREFIX)) {
continue;
}
final String trimmedParameter = parameter.trim();
// According to the RFC, there could be an '=' character in the boundary so we can't just split on =.
// We find the first equals and then go from there. It should also be noted that the RFC does allow
// boundaries to start and end with quotes.
final int firstEquals = trimmedParameter.indexOf("=");
// equals is the last character.
if (firstEquals == 0 || firstEquals == -1 || firstEquals == trimmedParameter.length() - 1) {
throw new MultiPartIllegalFormatException("Invalid parameter format.");
}
final String parameterKey = trimmedParameter.substring(0, firstEquals);
String parameterValue = trimmedParameter.substring(firstEquals + 1, trimmedParameter.length());
if (parameterValue.charAt(0) == '"') {
if (parameterValue.charAt(parameterValue.length() - 1) != '"') {
throw new MultiPartIllegalFormatException("Invalid parameter format.");
}
// Remove the leading and trailing '"'
parameterValue = parameterValue.substring(1, parameterValue.length() - 1);
}
// there are multiple boundary parameters.
if (parameterMap.containsKey(parameterKey)) {
throw new MultiPartIllegalFormatException("Invalid parameter format. Multiple declarations of the same parameter!");
}
parameterMap.put(parameterKey, parameterValue);
}
final String boundaryValue = parameterMap.get(BOUNDARY_PARAMETER);
if (boundaryValue == null) {
throw new MultiPartIllegalFormatException("No boundary parameter found!");
}
return boundaryValue;
}
use of com.linkedin.multipart.exceptions.MultiPartIllegalFormatException in project rest.li by linkedin.
the class TestMIMEReaderExceptions method invalidContentType.
@Test
public void invalidContentType() throws Exception {
StreamRequest streamRequest = null;
try {
streamRequest = mock(StreamRequest.class);
when(streamRequest.getHeader(MultiPartMIMEUtils.CONTENT_TYPE_HEADER)).thenReturn("Some erroneous content type");
MultiPartMIMEReader.createAndAcquireStream(streamRequest);
Assert.fail();
} catch (MultiPartIllegalFormatException illegalMimeFormatException) {
Assert.assertEquals(illegalMimeFormatException.getMessage(), "Malformed multipart mime request. Not a valid multipart mime header.");
verify(streamRequest, times(1)).getHeader(MultiPartMIMEUtils.CONTENT_TYPE_HEADER);
}
}
use of com.linkedin.multipart.exceptions.MultiPartIllegalFormatException in project rest.li by linkedin.
the class TestMIMEReaderExceptions method executeRequestWithDesiredException.
// /////////////////////////////////////////////////////////////////////////////////////
private void executeRequestWithDesiredException(final ByteString requestPayload, final int chunkSize, final String contentTypeHeader, final String desiredExceptionMessage) throws Exception {
mockR2AndWrite(requestPayload, chunkSize, contentTypeHeader);
final CountDownLatch latch = new CountDownLatch(1);
MultiPartMIMEReader reader = MultiPartMIMEReader.createAndAcquireStream(_streamRequest);
_currentMultiPartMIMEReaderCallback = new MultiPartMIMEExceptionReaderCallbackImpl(latch, reader);
reader.registerReaderCallback(_currentMultiPartMIMEReaderCallback);
latch.await(_testTimeout, TimeUnit.MILLISECONDS);
// Verify the correct exception was sent to the reader callback. The test itself will then verify
// if the correct error (if applicable) was sent to the single part reader callback.
Assert.assertTrue(_currentMultiPartMIMEReaderCallback.getStreamError() instanceof MultiPartIllegalFormatException);
Assert.assertEquals(_currentMultiPartMIMEReaderCallback.getStreamError().getMessage(), desiredExceptionMessage);
// Verify these are unusable.
try {
reader.drainAllParts();
Assert.fail();
} catch (MultiPartReaderFinishedException multiPartReaderFinishedException) {
// pass
}
// Unnecessary to verify how many times requestData on the read handle was called.
verify(_readHandle, atLeastOnce()).request(isA(Integer.class));
verify(_readHandle, times(1)).cancel();
verify(_streamRequest, times(1)).getEntityStream();
verify(_streamRequest, times(1)).getHeader(MIMETestUtils.HEADER_CONTENT_TYPE);
verify(_entityStream, times(1)).setReader(isA(MultiPartMIMEReader.R2MultiPartMIMEReader.class));
verifyNoMoreInteractions(_streamRequest);
verifyNoMoreInteractions(_entityStream);
}
use of com.linkedin.multipart.exceptions.MultiPartIllegalFormatException in project rest.li by linkedin.
the class TestMIMEReaderExceptions method payloadMissingFinalBoundary.
@Test(dataProvider = "multiplePartsDataSource")
public void payloadMissingFinalBoundary(final int chunkSize, final List<MimeBodyPart> bodyPartList) throws Exception {
MimeMultipart multiPartMimeBody = new MimeMultipart();
// Add your body parts
for (final MimeBodyPart bodyPart : bodyPartList) {
multiPartMimeBody.addBodyPart(bodyPart);
}
final ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
multiPartMimeBody.writeTo(byteArrayOutputStream);
final byte[] mimePayload = byteArrayOutputStream.toByteArray();
// To simulate the missing boundary, we have to trim 3 bytes off of the end. We need to snip the very last 2 bytes
// because javax mail places a CRLF at the very end (which is not needed) and then another byte before that (which is a
// hyphen) so that the final boundary never occurs.
final byte[] trimmedMimePayload = Arrays.copyOf(mimePayload, mimePayload.length - 3);
final ByteString requestPayload = ByteString.copy(trimmedMimePayload);
executeRequestWithDesiredException(requestPayload, chunkSize, multiPartMimeBody.getContentType(), "Malformed multipart mime request. Finishing boundary missing!");
List<SinglePartMIMEExceptionReaderCallbackImpl> singlePartMIMEReaderCallbacks = _currentMultiPartMIMEReaderCallback.getSinglePartMIMEReaderCallbacks();
Assert.assertEquals(singlePartMIMEReaderCallbacks.size(), multiPartMimeBody.getCount());
// The last one should have gotten a stream error
for (int i = 0; i < singlePartMIMEReaderCallbacks.size() - 1; i++) {
// Actual
final SinglePartMIMEExceptionReaderCallbackImpl currentCallback = singlePartMIMEReaderCallbacks.get(i);
// Expected
final BodyPart currentExpectedPart = multiPartMimeBody.getBodyPart(i);
// Construct expected headers and verify they match
final Map<String, String> expectedHeaders = new HashMap<>();
@SuppressWarnings("unchecked") final Enumeration<Header> allHeaders = currentExpectedPart.getAllHeaders();
while (allHeaders.hasMoreElements()) {
final Header header = allHeaders.nextElement();
expectedHeaders.put(header.getName(), header.getValue());
}
Assert.assertEquals(currentCallback.getHeaders(), expectedHeaders);
// Verify the body matches
Assert.assertNotNull(currentCallback.getFinishedData());
if (currentExpectedPart.getContent() instanceof byte[]) {
Assert.assertEquals(currentCallback.getFinishedData().copyBytes(), currentExpectedPart.getContent());
} else {
// Default is String
Assert.assertEquals(new String(currentCallback.getFinishedData().copyBytes()), currentExpectedPart.getContent());
}
}
SinglePartMIMEExceptionReaderCallbackImpl singlePartMIMEExceptionReaderCallback = singlePartMIMEReaderCallbacks.get(singlePartMIMEReaderCallbacks.size() - 1);
Assert.assertNull(singlePartMIMEExceptionReaderCallback.getFinishedData());
Assert.assertTrue(singlePartMIMEExceptionReaderCallback.getStreamError() instanceof MultiPartIllegalFormatException);
try {
singlePartMIMEExceptionReaderCallback.getSinglePartMIMEReader().requestPartData();
Assert.fail();
} catch (SinglePartFinishedException singlePartFinishedException) {
// pass
}
}
Aggregations