@Test public void should_return_expected_response_when_endpoint_disabled_chunked_request_size_validation() throws Exception { NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.POST) .withUri(BasicEndpointWithRequestSizeValidationDisabled.MATCHING_PATH) .withPaylod(generatePayloadOfSizeInBytes(GLOBAL_MAX_REQUEST_SIZE + 100)) .withHeader(HttpHeaders.Names.TRANSFER_ENCODING, CHUNKED); // when NettyHttpClientResponse serverResponse = request.execute(serverConfig.endpointsPort(), incompleteCallTimeoutMillis); // then assertThat(serverResponse.statusCode).isEqualTo(HttpResponseStatus.OK.code()); assertThat(serverResponse.payload).isEqualTo(BasicEndpointWithRequestSizeValidationDisabled.RESPONSE_PAYLOAD); }
@Test public void should_return_expected_response_when_chunked_request_not_exceeding_endpoint_overridden_request_size() throws Exception { NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.POST) .withUri(BasicEndpointWithRequestSizeValidationOverride.MATCHING_PATH) .withPaylod(generatePayloadOfSizeInBytes(BasicEndpointWithRequestSizeValidationOverride.MAX_REQUEST_SIZE)) .withHeader(HttpHeaders.Names.TRANSFER_ENCODING, CHUNKED); // when NettyHttpClientResponse serverResponse = request.execute(serverConfig.endpointsPort(), incompleteCallTimeoutMillis); // then assertThat(serverResponse.statusCode).isEqualTo(HttpResponseStatus.OK.code()); assertThat(serverResponse.payload).isEqualTo(BasicEndpointWithRequestSizeValidationOverride.RESPONSE_PAYLOAD); }
@Test public void should_return_expected_response_when_chunked_request_not_exceeding_global_request_size() throws Exception { NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.POST) .withUri(BasicEndpoint.MATCHING_PATH) .withPaylod(generatePayloadOfSizeInBytes(GLOBAL_MAX_REQUEST_SIZE)) .withHeader(HttpHeaders.Names.TRANSFER_ENCODING, CHUNKED); // when NettyHttpClientResponse serverResponse = request.execute(serverConfig.endpointsPort(), incompleteCallTimeoutMillis); // then assertThat(serverResponse.statusCode).isEqualTo(HttpResponseStatus.OK.code()); assertThat(serverResponse.payload).isEqualTo(BasicEndpoint.RESPONSE_PAYLOAD); }
.withMethod(scenario.requestMethod) .withUri(RouterEndpoint.MATCHING_PATH) .withHeader(SOME_EXPECTED_REQUEST_HEADER.getKey(), SOME_EXPECTED_REQUEST_HEADER.getValue()) .withHeader(HttpHeaders.Names.HOST, "localhost") .withHeader(CONTENT_LENGTH, 0) .withHeader(DownstreamEndpoint.DESIRED_RESPONSE_STATUS_CODE_HEADER_KEY, scenario.responseStatusCode); request.withHeader(DownstreamEndpoint.RESPONSE_SHOULD_BE_CHUNKED_REQUEST_HEADER_KEY, "true");
.withUri(RouterEndpoint.MATCHING_PATH) .withPaylod(origRequestPayload) .withHeader(SOME_EXPECTED_REQUEST_HEADER.getKey(), SOME_EXPECTED_REQUEST_HEADER.getValue()) .withHeader(HttpHeaders.Names.HOST, "localhost"); request = request.withHeader(TRANSFER_ENCODING, CHUNKED); request = request.withHeader(CONTENT_LENGTH, origRequestPayload.length()); request.withHeader(DownstreamEndpoint.RESPONSE_SHOULD_BE_CHUNKED_REQUEST_HEADER_KEY, "true");
.withMethod(HttpMethod.GET) .withUri(BasicEndpoint.MATCHING_PATH) .withHeader(ACCEPT_ENCODING, compressionType.contentEncodingHeaderValue) .withHeader(BasicEndpoint.DESIRED_UNCOMPRESSED_PAYLOAD_SIZE_HEADER_KEY, desiredUncompressedPayloadSize);
.withMethod(HttpMethod.POST) .withUri(RouterEndpointForwardingToDelayEndpoint.MATCHING_PATH) .withHeader(INTENTIONAL_EXPLOSION_AFTER_LAST_CHUNK_HEADER_KEY, "true");
.withMethod(HttpMethod.POST) .withUri(RouterEndpoint.MATCHING_PATH) .withHeader(SOME_EXPECTED_REQUEST_HEADER.getKey(), SOME_EXPECTED_REQUEST_HEADER.getValue()) .withHeader(HttpHeaders.Names.HOST, "localhost") .withHeader(DownstreamEndpoint.RESPONSE_SHOULD_BE_EMPTY_REQUEST_HEADER_KEY, "true"); request = request.withHeader(TRANSFER_ENCODING, CHUNKED); request = request.withHeader(CONTENT_LENGTH, 0); request.withHeader(DownstreamEndpoint.RESPONSE_SHOULD_BE_CHUNKED_REQUEST_HEADER_KEY, "true");
@DataProvider(value = { "GZIP", "DEFLATE", "IDENTITY" }, splitBy = "\\|") @Test public void response_should_not_be_compressed_when_ResponseInfo_disables_compression( CompressionType compressionType ) throws Exception { // given NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.GET) .withUri(BasicEndpoint.MATCHING_PATH) .withHeader(ACCEPT_ENCODING, compressionType.contentEncodingHeaderValue) .withHeader(BasicEndpoint.DESIRED_UNCOMPRESSED_PAYLOAD_SIZE_HEADER_KEY, 1000) .withHeader(BasicEndpoint.DISABLE_COMPRESSION_HEADER_KEY, "true"); // when NettyHttpClientResponse serverResponse = request.execute(serverConfig.endpointsPort(), incompleteCallTimeoutMillis); // then assertThat(serverResponse.statusCode).isEqualTo(HttpResponseStatus.OK.code()); assertThat(serverResponse.headers.get(CONTENT_ENCODING)).isNull(); assertThat(serverResponse.payload).hasSize(1000); assertThat(serverResponse.payload).startsWith(BasicEndpoint.RESPONSE_PAYLOAD_PREFIX); }
/** * This test verifies the corner case where the downstream system short circuits and returns a response before * it receives the full request (i.e. the request chunks are still streaming when the response is returned). * This should cause request chunks to fail to stream with an error, but the downstream response should still * be returned to the original caller successfully. */ @Test public void proxy_endpoints_should_successfully_return_short_circuited_downstream_response() throws Exception { // Do this test a bunch of times to try and catch all the race condition possibilities. for (int i = 0; i < 20; i++) { // given int payloadSize = 1024 * 1000; String payload = generatePayload(payloadSize); NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.POST) .withUri(RouterEndpointForwardingToShortCircuitError.MATCHING_PATH) .withPaylod(payload) .withHeader(HttpHeaders.Names.CONTENT_LENGTH, payloadSize); // when NettyHttpClientResponse serverResponse = request.execute(proxyServerConfig.endpointsPort(), 3000); // then verifyErrorReceived(serverResponse.payload, serverResponse.statusCode, FAIL_FAST_API_ERROR); } }
@Test public void http_call_with_bad_content_type_header_should_result_in_expected_400_error() throws Exception { // given NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.GET) .withUri(BasicEndpoint.MATCHING_PATH) .withHeader(HttpHeaderNames.CONTENT_TYPE.toString(), ";"); // when NettyHttpClientResponse response = request.execute(downstreamServerConfig.endpointsPort(), 3000); // then verifyErrorReceived(response.payload, response.statusCode, new ApiErrorWithMetadata(SampleCoreApiError.MALFORMED_REQUEST, Pair.of("cause", "Invalid HTTP request")) ); }
@Test public void should_return_bad_request_when_chunked_request_exceeds_global_configured_max_request_size() throws Exception { NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.POST) .withUri(BasicEndpoint.MATCHING_PATH) .withPaylod(generatePayloadOfSizeInBytes(GLOBAL_MAX_REQUEST_SIZE + 1)) .withHeader(HttpHeaders.Names.TRANSFER_ENCODING, CHUNKED); // when NettyHttpClientResponse serverResponse = request.execute(serverConfig.endpointsPort(), incompleteCallTimeoutMillis); // then assertThat(serverResponse.statusCode).isEqualTo(HttpResponseStatus.BAD_REQUEST.code()); assertBadRequestErrorMessageAndMetadata(serverResponse.payload); }
@Test public void should_return_bad_request_when_chunked_request_exceeds_endpoint_overridden_configured_max_request_size() throws Exception { NettyHttpClientRequestBuilder request = request() .withMethod(HttpMethod.POST) .withUri(BasicEndpointWithRequestSizeValidationOverride.MATCHING_PATH) .withPaylod(generatePayloadOfSizeInBytes(BasicEndpointWithRequestSizeValidationOverride.MAX_REQUEST_SIZE + 1)) .withHeader(HttpHeaders.Names.TRANSFER_ENCODING, CHUNKED); // when NettyHttpClientResponse serverResponse = request.execute(serverConfig.endpointsPort(), incompleteCallTimeoutMillis); // then assertThat(serverResponse.statusCode).isEqualTo(HttpResponseStatus.BAD_REQUEST.code()); assertBadRequestErrorMessageAndMetadata(serverResponse.payload); }
public NettyHttpClientRequestBuilder withHeaders(Iterable<Pair<String, Object>> headers) { for (Pair<String, Object> header : headers) { withHeader(header.getKey(), header.getValue()); } return this; }