类 io.netty.handler.codec.http.multipart.HttpPostRequestDecoder.ErrorDataDecoderException 源码实例Demo

下面列出了怎么用 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()));
}
 
 同包方法