下面列出了怎么用 io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException 的API类实例代码及写法,或者点击链接到github查看源代码。
protected void failureHandler(RoutingContext context) {
LOGGER.error("http server failed.", context.failure());
AbstractRestInvocation restProducerInvocation = context.get(RestConst.REST_PRODUCER_INVOCATION);
Throwable e = context.failure();
if (e instanceof ErrorDataDecoderException) {
Throwable cause = e.getCause();
if (cause instanceof InvocationException) {
e = cause;
}
}
// only when unexpected exception happens, it will run into here.
// the connection should be closed.
handleFailureAndClose(context, restProducerInvocation, e);
}
@Test
public void failureHandlerErrorDataWithInvocation(@Mocked RoutingContext context, @Mocked InvocationException e) {
RestProducerInvocation restProducerInvocation = new RestProducerInvocation();
ErrorDataDecoderException edde = new ErrorDataDecoderException(e);
MockHttpServerResponse response = new MockHttpServerResponse();
new Expectations() {
{
context.get(RestConst.REST_PRODUCER_INVOCATION);
result = restProducerInvocation;
context.failure();
returns(edde, edde);
context.response();
result = response;
}
};
Deencapsulation.invoke(dispatcher, "failureHandler", context);
Assert.assertSame(e, this.throwable);
Assert.assertTrue(response.responseClosed);
}
@Test
public void failureHandlerErrorDataWithNormal(@Mocked RoutingContext context) {
RestProducerInvocation restProducerInvocation = new RestProducerInvocation();
Exception e = new Exception();
ErrorDataDecoderException edde = new ErrorDataDecoderException(e);
MockHttpServerResponse response = new MockHttpServerResponse();
new Expectations() {
{
context.get(RestConst.REST_PRODUCER_INVOCATION);
result = restProducerInvocation;
context.failure();
returns(edde, edde);
context.response();
result = response;
}
};
Deencapsulation.invoke(dispatcher, "failureHandler", context);
Assert.assertSame(edde, this.throwable);
Assert.assertTrue(response.responseClosed);
}
@Test
public void failureHandlerWithNoRestProducerInvocationAndInvocationException(@Mocked RoutingContext context) {
InvocationException e = new InvocationException(Status.REQUEST_ENTITY_TOO_LARGE, "testMsg");
ErrorDataDecoderException edde = new ErrorDataDecoderException(e);
MockHttpServerResponse response = new MockHttpServerResponse();
new Expectations() {
{
context.get(RestConst.REST_PRODUCER_INVOCATION);
result = null;
context.failure();
returns(edde, edde);
context.response();
result = response;
}
};
Deencapsulation.invoke(dispatcher, "failureHandler", context);
Assert.assertThat(response.responseHeader, Matchers.hasEntry(HttpHeaders.CONTENT_TYPE, MediaType.WILDCARD));
Assert.assertThat(response.responseStatusCode, Matchers.is(Status.REQUEST_ENTITY_TOO_LARGE.getStatusCode()));
Assert.assertThat(response.responseStatusMessage, Matchers.is(Status.REQUEST_ENTITY_TOO_LARGE.getReasonPhrase()));
Assert.assertThat(response.responseChunk,
Matchers.is("{\"message\":\"" + Status.REQUEST_ENTITY_TOO_LARGE.getReasonPhrase() + "\"}"));
Assert.assertTrue(response.responseEnded);
}
/**
* Decode component
*
* @return the decoded component
*/
private static String decodeAttribute(String s, Charset charset) {
try {
return QueryStringDecoder.decodeComponent(s, charset);
} catch (IllegalArgumentException e) {
throw new ErrorDataDecoderException("Bad string: '" + s + '\'', e);
}
}
/**
* Load the field value or file data from a Multipart request 从多部分请求加载字段值或文件数据
*
* @return {@code true} if the last chunk is loaded (boundary delimiter found), {@code false} if need more chunks
* @throws ErrorDataDecoderException
*/
private static boolean loadDataMultipartStandard(ByteBuf undecodedChunk, String delimiter, HttpData httpData) {
final int startReaderIndex = undecodedChunk.readerIndex();
final int delimeterLength = delimiter.length();
int index = 0;
int lastPosition = startReaderIndex;
byte prevByte = HttpConstants.LF;
boolean delimiterFound = false;
while (undecodedChunk.isReadable()) {
final byte nextByte = undecodedChunk.readByte();
// Check the delimiter
if (prevByte == HttpConstants.LF && nextByte == delimiter.codePointAt(index)) {
index++;
if (delimeterLength == index) {
delimiterFound = true;
break;
}
continue;
}
lastPosition = undecodedChunk.readerIndex();
if (nextByte == HttpConstants.LF) {
index = 0;
lastPosition -= (prevByte == HttpConstants.CR)? 2 : 1;
}
prevByte = nextByte;
}
if (prevByte == HttpConstants.CR) {
lastPosition--;
}
ByteBuf content = undecodedChunk.copy(startReaderIndex, lastPosition - startReaderIndex);
try {
httpData.addContent(content, delimiterFound);
} catch (IOException e) {
throw new ErrorDataDecoderException(e);
}
undecodedChunk.readerIndex(lastPosition);
return delimiterFound;
}
/**
* Decode component
*
* @return the decoded component
*/
private static String decodeAttribute(String s, Charset charset) {
try {
return QueryStringDecoder.decodeComponent(s, charset);
} catch (IllegalArgumentException e) {
throw new ErrorDataDecoderException("Bad string: '" + s + '\'', e);
}
}
/**
* Load the field value from a Multipart request 从多部分请求加载字段值
*
* @return {@code true} if the last chunk is loaded (boundary delimiter found), {@code false} if need more chunks
* @throws ErrorDataDecoderException
*/
private static boolean loadDataMultipart(ByteBuf undecodedChunk, String delimiter, HttpData httpData) {
if (!undecodedChunk.hasArray()) {
return loadDataMultipartStandard(undecodedChunk, delimiter, httpData);
}
final SeekAheadOptimize sao = new SeekAheadOptimize(undecodedChunk);
final int startReaderIndex = undecodedChunk.readerIndex();
final int delimeterLength = delimiter.length();
int index = 0;
int lastRealPos = sao.pos;
byte prevByte = HttpConstants.LF;
boolean delimiterFound = false;
while (sao.pos < sao.limit) {
final byte nextByte = sao.bytes[sao.pos++];
// Check the delimiter
if (prevByte == HttpConstants.LF && nextByte == delimiter.codePointAt(index)) {
index++;
if (delimeterLength == index) {
delimiterFound = true;
break;
}
continue;
}
lastRealPos = sao.pos;
if (nextByte == HttpConstants.LF) {
index = 0;
lastRealPos -= (prevByte == HttpConstants.CR)? 2 : 1;
}
prevByte = nextByte;
}
if (prevByte == HttpConstants.CR) {
lastRealPos--;
}
final int lastPosition = sao.getReadPosition(lastRealPos);
final ByteBuf content = undecodedChunk.copy(startReaderIndex, lastPosition - startReaderIndex);
try {
httpData.addContent(content, delimiterFound);
} catch (IOException e) {
throw new ErrorDataDecoderException(e);
}
undecodedChunk.readerIndex(lastPosition);
return delimiterFound;
}
@Test
public void shouldHandleErrorDataDecoderException() {
verifyExceptionHandled(new ErrorDataDecoderException(), singletonError(testProjectApiErrors.getMalformedRequestApiError()));
}