下面列出了 io.netty.handler.codec.http2.HttpConversionUtil.ExtensionHeaderNames #software.amazon.awssdk.http.SdkHttpRequest 实例代码,或者点击链接到github查看源代码,也可以在右侧发表评论。
@Bean
@ConditionalOnProperty(prefix = "hedera.mirror.importer.downloader", name = "cloudProvider", havingValue = "GCP")
public S3AsyncClient gcpCloudStorageClient() {
log.info("Configured to download from GCP with bucket name '{}'", downloaderProperties.getBucketName());
// Any valid region for aws client. Ignored by GCP.
S3AsyncClientBuilder clientBuilder = asyncClientBuilder("us-east-1")
.endpointOverride(URI.create(downloaderProperties.getCloudProvider().getEndpoint()));
String projectId = downloaderProperties.getGcpProjectId();
if (StringUtils.isNotBlank(projectId)) {
clientBuilder.overrideConfiguration(builder -> builder.addExecutionInterceptor(new ExecutionInterceptor() {
@Override
public SdkHttpRequest modifyHttpRequest(
Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
return context.httpRequest().toBuilder()
.appendRawQueryParameter("userProject", projectId).build();
}
}));
}
return clientBuilder.build();
}
@Test
public void awsThrottling() {
SdkHttpRequest request = SdkHttpRequest.builder()
.method(SdkHttpMethod.POST)
.uri(URI.create("https://ec2.us-east-1.amazonaws.com"))
.build();
SdkHttpResponse response = SdkHttpResponse.builder()
.statusCode(400)
.build();
Throwable error = AwsServiceException.builder()
.awsErrorDetails(AwsErrorDetails.builder()
.errorCode("Throttling")
.errorMessage("too many requests")
.build())
.build();
TestContext context = new TestContext(request, response, error);
execute(context, createAttributes("EC2", "DescribeInstances"), millis(30));
Assertions.assertEquals(1, registry.timers().count());
Timer t = registry.timers().findFirst().orElse(null);
Assertions.assertNotNull(t);
Assertions.assertEquals(1, t.count());
Assertions.assertEquals(millis(30), t.totalTime());
Assertions.assertEquals("400", get(t.id(), "http.status"));
Assertions.assertEquals("throttled", get(t.id(), "ipc.status"));
}
@Override
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
SdkHttpRequest httpRequest = context.httpRequest();
Subsegment subsegment = executionAttributes.getAttribute(entityKey);
if (subsegment == null) {
return httpRequest;
}
boolean isSampled = subsegment.getParentSegment().isSampled();
TraceHeader header = new TraceHeader(
subsegment.getParentSegment().getTraceId(),
isSampled ? subsegment.getId() : null,
isSampled ? TraceHeader.SampleDecision.SAMPLED : TraceHeader.SampleDecision.NOT_SAMPLED
);
return httpRequest.toBuilder().appendHeader(TraceHeader.HEADER_KEY, header.toString()).build();
}
@Override
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
SdkHttpRequest request = context.httpRequest();
Object originalRequest = context.request();
if (originalRequest instanceof PredictRequest) {
PredictRequest pr = (PredictRequest) originalRequest;
if (pr.predictEndpoint() == null) {
throw SdkClientException.builder().message("PredictRequest.PredictEndpoint is required!").build();
}
try {
URI endpoint = new URI(pr.predictEndpoint());
return request.toBuilder().uri(endpoint).build();
} catch (URISyntaxException e) {
throw SdkClientException.builder()
.message("Unable to parse PredictRequest.PredictEndpoint")
.cause(e)
.build();
}
}
return request;
}
@Override
public void beforeTransmission(Context.BeforeTransmission context, ExecutionAttributes attrs) {
logRetryAttempt(attrs);
String serviceName = attrs.getAttribute(SdkExecutionAttribute.SERVICE_NAME);
String opName = attrs.getAttribute(SdkExecutionAttribute.OPERATION_NAME);
String endpoint = serviceName + "." + opName;
SdkHttpRequest request = context.httpRequest();
IpcLogEntry logEntry = logger.createClientEntry()
.withOwner("aws-sdk-java-v2")
.withProtocol(IpcProtocol.http_1)
.withHttpMethod(request.method().name())
.withUri(request.getUri())
.withEndpoint(endpoint)
.withAttempt(extractAttempt(request))
.withAttemptFinal(false); // Don't know if it is the final attempt
request.headers().forEach((k, vs) -> vs.forEach(v -> logEntry.addRequestHeader(k, v)));
attrs.putAttribute(LOG_ENTRY, logEntry.markStart());
}
/**
* Configures the headers in the specified Apache HTTP request.
*/
private void addHeadersToRequest(HttpRequestBase httpRequest, SdkHttpRequest request) {
httpRequest.addHeader(HttpHeaders.HOST, getHostHeaderValue(request));
// Copy over any other headers already in our request
request.headers().entrySet().stream()
/*
* HttpClient4 fills in the Content-Length header and complains if
* it's already present, so we skip it here. We also skip the Host
* header to avoid sending it twice, which will interfere with some
* signing schemes.
*/
.filter(e -> !IGNORE_HEADERS.contains(e.getKey()))
.forEach(e -> e.getValue().forEach(h -> httpRequest.addHeader(e.getKey(), h)));
}
private String resolveHost(SdkHttpRequest request, String accountId, S3ControlConfiguration configuration) {
if (isDualstackEnabled(configuration) && isFipsEnabled(configuration)) {
throw SdkClientException.create("Cannot use both Dual-Stack endpoints and FIPS endpoints");
}
String host = request.getUri().getHost();
if (isDualstackEnabled(configuration)) {
if (!host.contains(ENDPOINT_PREFIX)) {
throw SdkClientException.create(String.format("The Dual-Stack option cannot be used with custom endpoints (%s)",
request.getUri()));
}
host = host.replace(ENDPOINT_PREFIX, String.format("%s.%s", ENDPOINT_PREFIX, "dualstack"));
} else if (isFipsEnabled(configuration)) {
if (!host.contains(ENDPOINT_PREFIX)) {
throw SdkClientException.create(String.format("The FIPS option cannot be used with custom endpoints (%s)",
request.getUri()));
}
host = host.replace(ENDPOINT_PREFIX, String.format("%s-%s", ENDPOINT_PREFIX, "fips"));
}
validateComponentIsHostnameCompliant(accountId, "account id");
return String.format("%s.%s", accountId, host);
}
@Test
public void successfulRequest() {
SdkHttpRequest request = SdkHttpRequest.builder()
.method(SdkHttpMethod.POST)
.uri(URI.create("https://ec2.us-east-1.amazonaws.com"))
.build();
SdkHttpResponse response = SdkHttpResponse.builder()
.statusCode(200)
.build();
TestContext context = new TestContext(request, response);
execute(context, createAttributes("EC2", "DescribeInstances"), millis(42));
Assertions.assertEquals(1, registry.timers().count());
Timer t = registry.timers().findFirst().orElse(null);
Assertions.assertNotNull(t);
Assertions.assertEquals(1, t.count());
Assertions.assertEquals(millis(42), t.totalTime());
Assertions.assertEquals("EC2.DescribeInstances", get(t.id(), "ipc.endpoint"));
Assertions.assertEquals("200", get(t.id(), "http.status"));
Assertions.assertEquals("POST", get(t.id(), "http.method"));
}
@Test
public void adapt_h1Request_requestIsCorrect() {
SdkHttpRequest request = SdkHttpRequest.builder()
.uri(URI.create("http://localhost:12345/foo/bar/baz"))
.putRawQueryParameter("foo", "bar")
.putRawQueryParameter("bar", "baz")
.putHeader("header1", "header1val")
.putHeader("header2", "header2val")
.method(SdkHttpMethod.GET)
.build();
HttpRequest adapted = h1Adapter.adapt(request);
assertThat(adapted.method()).isEqualTo(HttpMethod.valueOf("GET"));
assertThat(adapted.uri()).isEqualTo("/foo/bar/baz?foo=bar&bar=baz");
assertThat(adapted.protocolVersion()).isEqualTo(HttpVersion.HTTP_1_1);
assertThat(adapted.headers().getAll("Host")).containsExactly("localhost:12345");
assertThat(adapted.headers().getAll("header1")).containsExactly("header1val");
assertThat(adapted.headers().getAll("header2")).containsExactly("header2val");
}
@Override
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
ExecutionAttributes executionAttributes) {
// Some APIG operations marshall to the 'Accept' header to specify the
// format of the document returned by the service, such as GetExport
// https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-export-api.html.
// See the same fix in V1:
// https://github.com/aws/aws-sdk-java/blob/cd2275c07df8656033bfa9baa665354bfb17a6bf/aws-java-sdk-api-gateway/src/main/java/com/amazonaws/services/apigateway/internal/AcceptJsonRequestHandler.java#L29
SdkHttpRequest httpRequest = context.httpRequest();
if (!httpRequest.headers().containsKey("Accept")) {
return httpRequest
.toBuilder()
.putHeader("Accept", "application/json")
.build();
}
return httpRequest;
}
/**
* Get the HTTP full request from the execution context.
*/
private SdkHttpFullRequest getHttpFullRequest(ExecutionContext execCtx) {
SdkHttpRequest requestFromInterceptor = execCtx.interceptorContext().httpRequest();
Optional<RequestBody> bodyFromInterceptor = execCtx.interceptorContext().requestBody();
return SdkHttpFullRequest.builder()
.method(requestFromInterceptor.method())
.protocol(requestFromInterceptor.protocol())
.host(requestFromInterceptor.host())
.port(requestFromInterceptor.port())
.encodedPath(requestFromInterceptor.encodedPath())
.rawQueryParameters(requestFromInterceptor.rawQueryParameters())
.headers(requestFromInterceptor.headers())
.contentStreamProvider(bodyFromInterceptor.map(RequestBody::contentStreamProvider)
.orElse(null))
.build();
}
/**
* Extract the attempt number from the {@code amz-sdk-retry} header.
*/
private IpcAttempt extractAttempt(SdkHttpRequest request) {
int attempt = 0;
List<String> vs = request.headers().get("amz-sdk-retry");
if (vs != null) {
for (String v : vs) {
// Format is: {requestCount - 1}/{lastBackoffDelay}/{availableRetryCapacity}
// See internal RetryHandler for more details.
int pos = v.indexOf('/');
if (pos > 0) {
try {
attempt = Integer.parseInt(v.substring(0, pos)) + 1;
} catch (NumberFormatException e) {
// If we cannot parse it, then attempt is unknown
attempt = 0;
}
}
}
}
return IpcAttempt.forAttemptNumber(attempt);
}
@Override
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context,
ExecutionAttributes executionAttributes) {
if (context.request() instanceof CreateMultipartUploadRequest) {
SdkHttpRequest.Builder builder = context.httpRequest()
.toBuilder()
.putHeader(CONTENT_LENGTH, String.valueOf(0));
if (!context.httpRequest().firstMatchingHeader(CONTENT_TYPE).isPresent()) {
builder.putHeader(CONTENT_TYPE, "binary/octet-stream");
}
return builder.build();
}
return context.httpRequest();
}
/**
* Configures the headers in the specified Netty HTTP request.
*/
private void addHeadersToRequest(DefaultHttpRequest httpRequest, SdkHttpRequest request) {
httpRequest.headers().add(HOST, getHostHeaderValue(request));
String scheme = request.getUri().getScheme();
if (Protocol.HTTP2 == protocol && !StringUtils.isBlank(scheme)) {
httpRequest.headers().add(ExtensionHeaderNames.SCHEME.text(), scheme);
}
// Copy over any other headers already in our request
request.headers().entrySet().stream()
/*
* Skip the Host header to avoid sending it twice, which will
* interfere with some signing schemes.
*/
.filter(e -> !IGNORE_HEADERS.contains(e.getKey()))
.forEach(e -> e.getValue().forEach(h -> httpRequest.headers().add(e.getKey(), h)));
}
@Test
public void builderUsesProvidedTrustManagersProvider() throws Exception {
WireMockServer selfSignedServer = HttpTestUtils.createSelfSignedServer();
TrustManagerFactory managerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
managerFactory.init(HttpTestUtils.getSelfSignedKeyStore());
try (SdkAsyncHttpClient netty = NettyNioAsyncHttpClient.builder()
.tlsTrustManagersProvider(managerFactory::getTrustManagers)
.build()) {
selfSignedServer.start();
URI uri = URI.create("https://localhost:" + selfSignedServer.httpsPort());
SdkHttpRequest request = createRequest(uri);
RecordingResponseHandler recorder = new RecordingResponseHandler();
client.execute(AsyncExecuteRequest.builder().request(request).requestContentPublisher(createProvider("")).responseHandler(recorder).build());
recorder.completeFuture.get(5, TimeUnit.SECONDS);
} finally {
selfSignedServer.stop();
}
}
public static Context.ModifyHttpRequest modifyHttpRequestContext(SdkRequest request, SdkHttpRequest sdkHttpRequest) {
Optional<RequestBody> requestBody = Optional.of(RequestBody.fromString("helloworld"));
Optional<AsyncRequestBody> asyncRequestBody = Optional.of(AsyncRequestBody.fromString("helloworld"));
return new Context.ModifyHttpRequest() {
@Override
public SdkHttpRequest httpRequest() {
return sdkHttpRequest;
}
@Override
public Optional<RequestBody> requestBody() {
return requestBody;
}
@Override
public Optional<AsyncRequestBody> asyncRequestBody() {
return asyncRequestBody;
}
@Override
public SdkRequest request() {
return request;
}
};
}
@Test
public void afterUnmarshalling_putObjectRequest_shouldValidateChecksum() {
SdkHttpResponse sdkHttpResponse = getSdkHttpResponseWithChecksumHeader();
PutObjectResponse response = PutObjectResponse.builder()
.eTag(VALID_CHECKSUM)
.build();
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.build();
SdkHttpRequest sdkHttpRequest = SdkHttpFullRequest.builder()
.uri(URI.create("http://localhost:8080"))
.method(SdkHttpMethod.PUT)
.build();
Context.AfterUnmarshalling afterUnmarshallingContext =
InterceptorTestUtils.afterUnmarshallingContext(putObjectRequest, sdkHttpRequest, response, sdkHttpResponse);
interceptor.afterUnmarshalling(afterUnmarshallingContext, getExecutionAttributesWithChecksum());
}
private void parseRetryHeaderTest(String expected, String header) {
SdkHttpRequest request = SdkHttpRequest.builder()
.method(SdkHttpMethod.POST)
.uri(URI.create("https://ec2.us-east-1.amazonaws.com"))
.appendHeader("amz-sdk-retry", header)
.build();
SdkHttpResponse response = SdkHttpResponse.builder()
.statusCode(200)
.build();
TestContext context = new TestContext(request, response);
execute(context, createAttributes("EC2", "DescribeInstances"), millis(30));
Assertions.assertEquals(1, registry.timers().count());
Timer t = registry.timers().findFirst().orElse(null);
Assertions.assertNotNull(t);
Assertions.assertEquals(1, t.count());
Assertions.assertEquals(millis(30), t.totalTime());
Assertions.assertEquals(expected, get(t.id(), "ipc.attempt"));
}
private void verifyAccesspointArn(String protocol, String accessPointArn, String expectedEndpoint,
Region expectedSigningRegion,
S3Configuration.Builder builder, Region region) {
String key = "test-key";
URI customUri = URI.create(String.format("%s://s3-test.com/%s/%s", protocol, urlEncode(accessPointArn), key));
URI expectedUri = URI.create(String.format("%s/%s", expectedEndpoint, key));
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.bucket(accessPointArn)
.key(key)
.build();
Context.ModifyHttpRequest ctx = context(putObjectRequest, sdkHttpRequest(customUri));
ExecutionAttributes executionAttributes = new ExecutionAttributes();
S3Configuration s3Configuration = builder.build();
executionAttributes.putAttribute(SERVICE_CONFIG, s3Configuration);
executionAttributes.putAttribute(AWS_REGION, region);
executionAttributes.putAttribute(SIGNING_REGION, region);
SdkHttpRequest sdkHttpFullRequest = interceptor.modifyHttpRequest(ctx, executionAttributes);
assertThat(executionAttributes.getAttribute(SIGNING_REGION))
.isEqualTo(expectedSigningRegion);
assertThat(sdkHttpFullRequest.getUri()).isEqualTo(expectedUri);
}
private Context.ModifyHttpRequest context(SdkRequest request, SdkHttpRequest sdkHttpRequest) {
return new Context.ModifyHttpRequest() {
@Override
public SdkHttpRequest httpRequest() {
return sdkHttpRequest;
}
@Override
public Optional<RequestBody> requestBody() {
return null;
}
@Override
public Optional<AsyncRequestBody> asyncRequestBody() {
return null;
}
@Override
public SdkRequest request() {
return request;
}
};
}
@Test
public void afterUnmarshalling_putObjectRequest_shouldValidateChecksum() {
SdkHttpResponse sdkHttpResponse = getSdkHttpResponseWithChecksumHeader();
PutObjectResponse response = PutObjectResponse.builder()
.eTag(VALID_CHECKSUM)
.build();
PutObjectRequest putObjectRequest = PutObjectRequest.builder()
.build();
SdkHttpRequest sdkHttpRequest = SdkHttpFullRequest.builder()
.uri(URI.create("http://localhost:8080"))
.method(SdkHttpMethod.PUT)
.build();
Context.AfterUnmarshalling afterUnmarshallingContext =
InterceptorTestUtils.afterUnmarshallingContext(putObjectRequest, sdkHttpRequest, response, sdkHttpResponse);
interceptor.afterUnmarshalling(afterUnmarshallingContext, getExecutionAttributesWithChecksum());
}
@Test
public void adapt_defaultPortUsed() {
SdkHttpRequest sdkRequest = SdkHttpRequest.builder()
.uri(URI.create("http://localhost:80/"))
.method(SdkHttpMethod.HEAD)
.build();
HttpRequest result = h1Adapter.adapt(sdkRequest);
List<String> hostHeaders = result.headers()
.getAll(HttpHeaderNames.HOST.toString());
assertNotNull(hostHeaders);
assertEquals(1, hostHeaders.size());
assertEquals("localhost", hostHeaders.get(0));
sdkRequest = SdkHttpRequest.builder()
.uri(URI.create("https://localhost:443/"))
.method(SdkHttpMethod.HEAD)
.build();
result = h1Adapter.adapt(sdkRequest);
hostHeaders = result.headers()
.getAll(HttpHeaderNames.HOST.toString());
assertNotNull(hostHeaders);
assertEquals(1, hostHeaders.size());
assertEquals("localhost", hostHeaders.get(0));
}
private SdkHttpRequest.Builder beforeRequest(Object originalRequest, SdkHttpRequest.Builder mutableRequest) {
mutableRequest.putHeader("x-amz-glacier-version", "2012-06-01");
// "x-amz-content-sha256" header is required for sig v4 for some streaming operations
mutableRequest.putHeader("x-amz-content-sha256", "required");
if (originalRequest instanceof UploadMultipartPartRequest) {
mutableRequest.firstMatchingHeader("Content-Range")
.ifPresent(range -> mutableRequest.putHeader("Content-Length",
Long.toString(parseContentLengthFromRange(range))));
} else if (originalRequest instanceof GetJobOutputRequest || originalRequest instanceof DescribeJobRequest) {
String resourcePath = mutableRequest.encodedPath();
if (resourcePath != null) {
String newResourcePath = resourcePath.replace("{jobType}", "archive-retrievals");
mutableRequest.encodedPath(newResourcePath);
}
}
return mutableRequest;
}
@Override
public SdkHttpRequest modifyHttpRequest(Context.ModifyHttpRequest context, ExecutionAttributes executionAttributes) {
SdkHttpRequest httpRequest = context.httpRequest();
if (context.request() instanceof SearchRequest) {
return httpRequest.toBuilder()
.clearQueryParameters()
.method(SdkHttpMethod.POST)
.putHeader("Content-Type", singletonList("application/x-www-form-urlencoded"))
.build();
}
return context.httpRequest();
}
@Test
public void testSetsPresignedUrl() {
CopyDbSnapshotRequest request = makeTestRequest();
SdkHttpRequest presignedRequest = modifyHttpRequest(presignInterceptor, request, marshallRequest(request));
assertNotNull(presignedRequest.rawQueryParameters().get("PreSignedUrl").get(0));
}
@Test
public void defaultHttpPortsAreNotInDefaultHostHeader() {
SdkHttpRequest sdkRequest = SdkHttpRequest.builder()
.uri(URI.create("http://localhost:80/"))
.method(SdkHttpMethod.HEAD)
.build();
HttpExecuteRequest request = HttpExecuteRequest.builder()
.request(sdkRequest)
.build();
HttpRequestBase result = instance.create(request, requestConfig);
Header[] hostHeaders = result.getHeaders(HttpHeaders.HOST);
assertNotNull(hostHeaders);
assertEquals(1, hostHeaders.length);
assertEquals("localhost", hostHeaders[0].getValue());
sdkRequest = SdkHttpRequest.builder()
.uri(URI.create("https://localhost:443/"))
.method(SdkHttpMethod.HEAD)
.build();
request = HttpExecuteRequest.builder()
.request(sdkRequest)
.build();
result = instance.create(request, requestConfig);
hostHeaders = result.getHeaders(HttpHeaders.HOST);
assertNotNull(hostHeaders);
assertEquals(1, hostHeaders.length);
assertEquals("localhost", hostHeaders[0].getValue());
}
@Test
public void testSkipsPresigningIfSourceRegionNotSet() {
CopyDbSnapshotRequest request = CopyDbSnapshotRequest.builder().build();
SdkHttpRequest presignedRequest = modifyHttpRequest(presignInterceptor, request, marshallRequest(request));
assertNull(presignedRequest.rawQueryParameters().get("PreSignedUrl"));
}
@Test
public void testParsesDestinationRegionfromRequestEndpoint() throws URISyntaxException {
CopyDbSnapshotRequest request = CopyDbSnapshotRequest.builder()
.sourceRegion("us-east-1")
.build();
Region destination = Region.of("us-west-2");
SdkHttpFullRequest marshalled = marshallRequest(request);
final SdkHttpRequest presignedRequest = modifyHttpRequest(presignInterceptor, request, marshalled);
final URI presignedUrl = new URI(presignedRequest.rawQueryParameters().get("PreSignedUrl").get(0));
assertTrue(presignedUrl.toString().contains("DestinationRegion=" + destination.id()));
}
SdkHttpClient primeHttpClient() throws IOException {
server.enqueue(new MockResponse());
SdkHttpClient httpClient = UrlConnectionHttpClient.builder().build();
try {
httpClient.prepareRequest(HttpExecuteRequest.builder()
.request(SdkHttpRequest.builder()
.method(SdkHttpMethod.GET)
.uri(server.url("/").uri())
.build())
.build()).call();
} finally {
takeRequest();
}
return httpClient;
}
private String getHostHeaderValue(SdkHttpRequest request) {
// Apache doesn't allow us to include the port in the host header if it's a standard port for that protocol. For that
// reason, we don't include the port when we sign the message. See {@link SdkHttpRequest#port()}.
return !SdkHttpUtils.isUsingStandardPort(request.protocol(), request.port())
? request.host() + ":" + request.port()
: request.host();
}