1*3c7ae9deSAndroid Build Coastguard Worker /**
2*3c7ae9deSAndroid Build Coastguard Worker * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
3*3c7ae9deSAndroid Build Coastguard Worker * SPDX-License-Identifier: Apache-2.0.
4*3c7ae9deSAndroid Build Coastguard Worker */
5*3c7ae9deSAndroid Build Coastguard Worker #include "aws_signing.h"
6*3c7ae9deSAndroid Build Coastguard Worker #include "credentials.h"
7*3c7ae9deSAndroid Build Coastguard Worker #include "crt.h"
8*3c7ae9deSAndroid Build Coastguard Worker #include "http_request_utils.h"
9*3c7ae9deSAndroid Build Coastguard Worker #include "java_class_ids.h"
10*3c7ae9deSAndroid Build Coastguard Worker #include "retry_utils.h"
11*3c7ae9deSAndroid Build Coastguard Worker #include <aws/common/string.h>
12*3c7ae9deSAndroid Build Coastguard Worker #include <aws/http/connection.h>
13*3c7ae9deSAndroid Build Coastguard Worker #include <aws/http/proxy.h>
14*3c7ae9deSAndroid Build Coastguard Worker #include <aws/http/request_response.h>
15*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/channel_bootstrap.h>
16*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/retry_strategy.h>
17*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/stream.h>
18*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/tls_channel_handler.h>
19*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/uri.h>
20*3c7ae9deSAndroid Build Coastguard Worker #include <aws/s3/s3_client.h>
21*3c7ae9deSAndroid Build Coastguard Worker #include <aws/s3/s3express_credentials_provider.h>
22*3c7ae9deSAndroid Build Coastguard Worker #include <http_proxy_options.h>
23*3c7ae9deSAndroid Build Coastguard Worker #include <http_proxy_options_environment_variable.h>
24*3c7ae9deSAndroid Build Coastguard Worker #include <jni.h>
25*3c7ae9deSAndroid Build Coastguard Worker
26*3c7ae9deSAndroid Build Coastguard Worker /* on 32-bit platforms, casting pointers to longs throws a warning we don't need */
27*3c7ae9deSAndroid Build Coastguard Worker #if UINTPTR_MAX == 0xffffffff
28*3c7ae9deSAndroid Build Coastguard Worker # if defined(_MSC_VER)
29*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(push)
30*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(disable : 4305) /* 'type cast': truncation from 'jlong' to 'jni_tls_ctx_options *' */
31*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(disable : 4221)
32*3c7ae9deSAndroid Build Coastguard Worker # else
33*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic push
34*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
35*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
36*3c7ae9deSAndroid Build Coastguard Worker # endif
37*3c7ae9deSAndroid Build Coastguard Worker #endif
38*3c7ae9deSAndroid Build Coastguard Worker
39*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_callback_data {
40*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm;
41*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3_client;
42*3c7ae9deSAndroid Build Coastguard Worker struct aws_signing_config_data signing_config_data;
43*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3express_provider_factory;
44*3c7ae9deSAndroid Build Coastguard Worker };
45*3c7ae9deSAndroid Build Coastguard Worker
46*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data {
47*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm;
48*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3_meta_request;
49*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3_meta_request_response_handler_native_adapter;
50*3c7ae9deSAndroid Build Coastguard Worker struct aws_input_stream *input_stream;
51*3c7ae9deSAndroid Build Coastguard Worker struct aws_signing_config_data signing_config_data;
52*3c7ae9deSAndroid Build Coastguard Worker jthrowable java_exception;
53*3c7ae9deSAndroid Build Coastguard Worker };
54*3c7ae9deSAndroid Build Coastguard Worker
55*3c7ae9deSAndroid Build Coastguard Worker static void s_on_s3_client_shutdown_complete_callback(void *user_data);
56*3c7ae9deSAndroid Build Coastguard Worker static void s_on_s3_meta_request_shutdown_complete_callback(void *user_data);
57*3c7ae9deSAndroid Build Coastguard Worker
aws_s3_tcp_keep_alive_options_from_java(JNIEnv * env,jobject jni_s3_tcp_keep_alive_options,struct aws_s3_tcp_keep_alive_options * s3_tcp_keep_alive_options)58*3c7ae9deSAndroid Build Coastguard Worker int aws_s3_tcp_keep_alive_options_from_java(
59*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
60*3c7ae9deSAndroid Build Coastguard Worker jobject jni_s3_tcp_keep_alive_options,
61*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_tcp_keep_alive_options *s3_tcp_keep_alive_options) {
62*3c7ae9deSAndroid Build Coastguard Worker
63*3c7ae9deSAndroid Build Coastguard Worker uint16_t jni_keep_alive_interval_sec = (*env)->GetShortField(
64*3c7ae9deSAndroid Build Coastguard Worker env, jni_s3_tcp_keep_alive_options, s3_tcp_keep_alive_options_properties.keep_alive_interval_sec_field_id);
65*3c7ae9deSAndroid Build Coastguard Worker
66*3c7ae9deSAndroid Build Coastguard Worker uint16_t jni_keep_alive_timeout_sec = (*env)->GetShortField(
67*3c7ae9deSAndroid Build Coastguard Worker env, jni_s3_tcp_keep_alive_options, s3_tcp_keep_alive_options_properties.keep_alive_timeout_sec_field_id);
68*3c7ae9deSAndroid Build Coastguard Worker
69*3c7ae9deSAndroid Build Coastguard Worker uint16_t jni_keep_alive_max_failed_probes = (*env)->GetShortField(
70*3c7ae9deSAndroid Build Coastguard Worker env, jni_s3_tcp_keep_alive_options, s3_tcp_keep_alive_options_properties.keep_alive_max_failed_probes_field_id);
71*3c7ae9deSAndroid Build Coastguard Worker
72*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(*s3_tcp_keep_alive_options);
73*3c7ae9deSAndroid Build Coastguard Worker
74*3c7ae9deSAndroid Build Coastguard Worker s3_tcp_keep_alive_options->keep_alive_interval_sec = jni_keep_alive_interval_sec;
75*3c7ae9deSAndroid Build Coastguard Worker s3_tcp_keep_alive_options->keep_alive_timeout_sec = jni_keep_alive_timeout_sec;
76*3c7ae9deSAndroid Build Coastguard Worker s3_tcp_keep_alive_options->keep_alive_max_failed_probes = jni_keep_alive_max_failed_probes;
77*3c7ae9deSAndroid Build Coastguard Worker
78*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_SUCCESS;
79*3c7ae9deSAndroid Build Coastguard Worker }
80*3c7ae9deSAndroid Build Coastguard Worker
81*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_s3express_provider_java_impl {
82*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm;
83*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3express_provider;
84*3c7ae9deSAndroid Build Coastguard Worker };
85*3c7ae9deSAndroid Build Coastguard Worker
86*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_s3express_provider_callback_data {
87*3c7ae9deSAndroid Build Coastguard Worker void *log_id;
88*3c7ae9deSAndroid Build Coastguard Worker aws_on_get_credentials_callback_fn *get_cred_callback;
89*3c7ae9deSAndroid Build Coastguard Worker void *get_cred_user_data;
90*3c7ae9deSAndroid Build Coastguard Worker };
91*3c7ae9deSAndroid Build Coastguard Worker
92*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL
Java_software_amazon_awssdk_crt_s3_S3ExpressCredentialsProvider_s3expressCredentialsProviderGetCredentialsCompleted(JNIEnv * env,jclass jni_class,jlong nativeHandler,jobject java_credentials)93*3c7ae9deSAndroid Build Coastguard Worker Java_software_amazon_awssdk_crt_s3_S3ExpressCredentialsProvider_s3expressCredentialsProviderGetCredentialsCompleted(
94*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
95*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
96*3c7ae9deSAndroid Build Coastguard Worker jlong nativeHandler,
97*3c7ae9deSAndroid Build Coastguard Worker jobject java_credentials) {
98*3c7ae9deSAndroid Build Coastguard Worker
99*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
100*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_s3express_provider_callback_data *callback_data = (void *)nativeHandler;
101*3c7ae9deSAndroid Build Coastguard Worker struct aws_credentials *native_credentials = NULL;
102*3c7ae9deSAndroid Build Coastguard Worker int error_code = AWS_ERROR_SUCCESS;
103*3c7ae9deSAndroid Build Coastguard Worker
104*3c7ae9deSAndroid Build Coastguard Worker if (!java_credentials || aws_jni_check_and_clear_exception(env)) {
105*3c7ae9deSAndroid Build Coastguard Worker /* TODO: a separate error code?? */
106*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
107*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
108*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Failed to get S3Express credentials from Java",
109*3c7ae9deSAndroid Build Coastguard Worker (void *)callback_data->log_id);
110*3c7ae9deSAndroid Build Coastguard Worker error_code = AWS_ERROR_HTTP_CALLBACK_FAILURE;
111*3c7ae9deSAndroid Build Coastguard Worker goto done;
112*3c7ae9deSAndroid Build Coastguard Worker }
113*3c7ae9deSAndroid Build Coastguard Worker
114*3c7ae9deSAndroid Build Coastguard Worker native_credentials = aws_credentials_new_from_java_credentials(env, java_credentials);
115*3c7ae9deSAndroid Build Coastguard Worker if (!native_credentials) {
116*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Failed to create native credentials");
117*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
118*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
119*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Failed to create native credentials from Java",
120*3c7ae9deSAndroid Build Coastguard Worker (void *)callback_data->log_id);
121*3c7ae9deSAndroid Build Coastguard Worker goto done;
122*3c7ae9deSAndroid Build Coastguard Worker }
123*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor session_token = aws_credentials_get_session_token(native_credentials);
124*3c7ae9deSAndroid Build Coastguard Worker
125*3c7ae9deSAndroid Build Coastguard Worker if (session_token.len == 0) {
126*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3ExpressCredentialsProvider - sessionToken must be non-null");
127*3c7ae9deSAndroid Build Coastguard Worker error_code = AWS_ERROR_HTTP_CALLBACK_FAILURE;
128*3c7ae9deSAndroid Build Coastguard Worker aws_credentials_release(native_credentials);
129*3c7ae9deSAndroid Build Coastguard Worker native_credentials = NULL;
130*3c7ae9deSAndroid Build Coastguard Worker goto done;
131*3c7ae9deSAndroid Build Coastguard Worker }
132*3c7ae9deSAndroid Build Coastguard Worker
133*3c7ae9deSAndroid Build Coastguard Worker done:
134*3c7ae9deSAndroid Build Coastguard Worker callback_data->get_cred_callback(native_credentials, error_code, callback_data->get_cred_user_data);
135*3c7ae9deSAndroid Build Coastguard Worker aws_credentials_release(native_credentials);
136*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), callback_data);
137*3c7ae9deSAndroid Build Coastguard Worker }
138*3c7ae9deSAndroid Build Coastguard Worker
s_s3express_get_creds_java(struct aws_s3express_credentials_provider * provider,const struct aws_credentials * original_credentials,const struct aws_credentials_properties_s3express * s3express_properties,aws_on_get_credentials_callback_fn callback,void * user_data)139*3c7ae9deSAndroid Build Coastguard Worker static int s_s3express_get_creds_java(
140*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3express_credentials_provider *provider,
141*3c7ae9deSAndroid Build Coastguard Worker const struct aws_credentials *original_credentials,
142*3c7ae9deSAndroid Build Coastguard Worker const struct aws_credentials_properties_s3express *s3express_properties,
143*3c7ae9deSAndroid Build Coastguard Worker aws_on_get_credentials_callback_fn callback,
144*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
145*3c7ae9deSAndroid Build Coastguard Worker
146*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_s3express_provider_java_impl *impl = provider->impl;
147*3c7ae9deSAndroid Build Coastguard Worker int result = AWS_OP_ERR;
148*3c7ae9deSAndroid Build Coastguard Worker
149*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
150*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm);
151*3c7ae9deSAndroid Build Coastguard Worker if (!env) {
152*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
153*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_SUCCESS;
154*3c7ae9deSAndroid Build Coastguard Worker }
155*3c7ae9deSAndroid Build Coastguard Worker jobject properties_object = NULL;
156*3c7ae9deSAndroid Build Coastguard Worker jobject original_credentials_object = NULL;
157*3c7ae9deSAndroid Build Coastguard Worker
158*3c7ae9deSAndroid Build Coastguard Worker properties_object = (*env)->NewObject(
159*3c7ae9deSAndroid Build Coastguard Worker env,
160*3c7ae9deSAndroid Build Coastguard Worker s3express_credentials_properties_properties.s3express_credentials_properties_class,
161*3c7ae9deSAndroid Build Coastguard Worker s3express_credentials_properties_properties.constructor_method_id);
162*3c7ae9deSAndroid Build Coastguard Worker if ((*env)->ExceptionCheck(env) || properties_object == NULL) {
163*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
164*3c7ae9deSAndroid Build Coastguard Worker env,
165*3c7ae9deSAndroid Build Coastguard Worker "S3ExpressCredentialsProvider.getS3ExpressCredentials: Failed to create S3ExpressCredentialsProperties "
166*3c7ae9deSAndroid Build Coastguard Worker "object.");
167*3c7ae9deSAndroid Build Coastguard Worker goto done;
168*3c7ae9deSAndroid Build Coastguard Worker }
169*3c7ae9deSAndroid Build Coastguard Worker original_credentials_object = aws_java_credentials_from_native_new(env, original_credentials);
170*3c7ae9deSAndroid Build Coastguard Worker if ((*env)->ExceptionCheck(env) || original_credentials_object == NULL) {
171*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
172*3c7ae9deSAndroid Build Coastguard Worker env, "S3ExpressCredentialsProvider.getS3ExpressCredentials: Failed to create Credentials object.");
173*3c7ae9deSAndroid Build Coastguard Worker goto done;
174*3c7ae9deSAndroid Build Coastguard Worker }
175*3c7ae9deSAndroid Build Coastguard Worker
176*3c7ae9deSAndroid Build Coastguard Worker jstring jni_host = aws_jni_string_from_cursor(env, &s3express_properties->host);
177*3c7ae9deSAndroid Build Coastguard Worker jstring jni_region = aws_jni_string_from_cursor(env, &s3express_properties->region);
178*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetObjectField(env, properties_object, s3express_credentials_properties_properties.host_field_id, jni_host);
179*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetObjectField(
180*3c7ae9deSAndroid Build Coastguard Worker env, properties_object, s3express_credentials_properties_properties.region_field_id, jni_region);
181*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_host);
182*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_region);
183*3c7ae9deSAndroid Build Coastguard Worker
184*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_s3express_provider_callback_data *callback_data =
185*3c7ae9deSAndroid Build Coastguard Worker aws_mem_calloc(aws_jni_get_allocator(), 1, sizeof(struct s3_client_s3express_provider_callback_data));
186*3c7ae9deSAndroid Build Coastguard Worker
187*3c7ae9deSAndroid Build Coastguard Worker callback_data->get_cred_callback = callback;
188*3c7ae9deSAndroid Build Coastguard Worker callback_data->get_cred_user_data = user_data;
189*3c7ae9deSAndroid Build Coastguard Worker callback_data->log_id = impl->java_s3express_provider;
190*3c7ae9deSAndroid Build Coastguard Worker
191*3c7ae9deSAndroid Build Coastguard Worker /* Invoke the java call */
192*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
193*3c7ae9deSAndroid Build Coastguard Worker env,
194*3c7ae9deSAndroid Build Coastguard Worker impl->java_s3express_provider,
195*3c7ae9deSAndroid Build Coastguard Worker s3express_credentials_provider_properties.getS3ExpressCredentials,
196*3c7ae9deSAndroid Build Coastguard Worker properties_object,
197*3c7ae9deSAndroid Build Coastguard Worker original_credentials_object,
198*3c7ae9deSAndroid Build Coastguard Worker (jlong)callback_data);
199*3c7ae9deSAndroid Build Coastguard Worker
200*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
201*3c7ae9deSAndroid Build Coastguard Worker /* Check if any exception raised */
202*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
203*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
204*3c7ae9deSAndroid Build Coastguard Worker "id=%p: S3ExpressCredentialsProvider.getS3ExpressCredentials failed",
205*3c7ae9deSAndroid Build Coastguard Worker (void *)impl->java_s3express_provider);
206*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), callback_data);
207*3c7ae9deSAndroid Build Coastguard Worker goto done;
208*3c7ae9deSAndroid Build Coastguard Worker }
209*3c7ae9deSAndroid Build Coastguard Worker result = AWS_OP_SUCCESS;
210*3c7ae9deSAndroid Build Coastguard Worker done:
211*3c7ae9deSAndroid Build Coastguard Worker if (properties_object) {
212*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, properties_object);
213*3c7ae9deSAndroid Build Coastguard Worker }
214*3c7ae9deSAndroid Build Coastguard Worker if (original_credentials_object) {
215*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, original_credentials_object);
216*3c7ae9deSAndroid Build Coastguard Worker }
217*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(impl->jvm, env);
218*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
219*3c7ae9deSAndroid Build Coastguard Worker return result;
220*3c7ae9deSAndroid Build Coastguard Worker }
221*3c7ae9deSAndroid Build Coastguard Worker
s_s3express_destroy_java(struct aws_s3express_credentials_provider * provider)222*3c7ae9deSAndroid Build Coastguard Worker static void s_s3express_destroy_java(struct aws_s3express_credentials_provider *provider) {
223*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_s3express_provider_java_impl *impl = provider->impl;
224*3c7ae9deSAndroid Build Coastguard Worker
225*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
226*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(impl->jvm);
227*3c7ae9deSAndroid Build Coastguard Worker if (!env) {
228*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
229*3c7ae9deSAndroid Build Coastguard Worker return;
230*3c7ae9deSAndroid Build Coastguard Worker }
231*3c7ae9deSAndroid Build Coastguard Worker /* Invoke the java call */
232*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
233*3c7ae9deSAndroid Build Coastguard Worker env, impl->java_s3express_provider, s3express_credentials_provider_properties.destroyProvider);
234*3c7ae9deSAndroid Build Coastguard Worker
235*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, impl->java_s3express_provider);
236*3c7ae9deSAndroid Build Coastguard Worker
237*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(impl->jvm, env);
238*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
239*3c7ae9deSAndroid Build Coastguard Worker /* Once the java call returns, the java resource should be cleaned up already. We can finish up the shutdown
240*3c7ae9deSAndroid Build Coastguard Worker * process. Clean up the native part. */
241*3c7ae9deSAndroid Build Coastguard Worker aws_simple_completion_callback *callback = provider->shutdown_complete_callback;
242*3c7ae9deSAndroid Build Coastguard Worker void *user_data = provider->shutdown_user_data;
243*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(provider->allocator, provider);
244*3c7ae9deSAndroid Build Coastguard Worker callback(user_data);
245*3c7ae9deSAndroid Build Coastguard Worker }
246*3c7ae9deSAndroid Build Coastguard Worker
247*3c7ae9deSAndroid Build Coastguard Worker static struct aws_s3express_credentials_provider_vtable s_java_s3express_vtable = {
248*3c7ae9deSAndroid Build Coastguard Worker .get_credentials = s_s3express_get_creds_java,
249*3c7ae9deSAndroid Build Coastguard Worker .destroy = s_s3express_destroy_java,
250*3c7ae9deSAndroid Build Coastguard Worker };
251*3c7ae9deSAndroid Build Coastguard Worker
s_s3express_provider_jni_factory(struct aws_allocator * allocator,struct aws_s3_client * client,aws_simple_completion_callback shutdown_complete_callback,void * shutdown_user_data,void * factory_user_data)252*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3express_credentials_provider *s_s3express_provider_jni_factory(
253*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator,
254*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_client *client,
255*3c7ae9deSAndroid Build Coastguard Worker aws_simple_completion_callback shutdown_complete_callback,
256*3c7ae9deSAndroid Build Coastguard Worker void *shutdown_user_data,
257*3c7ae9deSAndroid Build Coastguard Worker void *factory_user_data) {
258*3c7ae9deSAndroid Build Coastguard Worker
259*3c7ae9deSAndroid Build Coastguard Worker (void)client;
260*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_callback_data *client_data = factory_user_data;
261*3c7ae9deSAndroid Build Coastguard Worker
262*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3express_credentials_provider *provider = NULL;
263*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_s3express_provider_java_impl *impl = NULL;
264*3c7ae9deSAndroid Build Coastguard Worker
265*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
266*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(client_data->jvm);
267*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
268*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
269*3c7ae9deSAndroid Build Coastguard Worker return NULL;
270*3c7ae9deSAndroid Build Coastguard Worker }
271*3c7ae9deSAndroid Build Coastguard Worker
272*3c7ae9deSAndroid Build Coastguard Worker aws_mem_acquire_many(
273*3c7ae9deSAndroid Build Coastguard Worker allocator,
274*3c7ae9deSAndroid Build Coastguard Worker 2,
275*3c7ae9deSAndroid Build Coastguard Worker &provider,
276*3c7ae9deSAndroid Build Coastguard Worker sizeof(struct aws_s3express_credentials_provider),
277*3c7ae9deSAndroid Build Coastguard Worker &impl,
278*3c7ae9deSAndroid Build Coastguard Worker sizeof(struct s3_client_s3express_provider_java_impl));
279*3c7ae9deSAndroid Build Coastguard Worker /* Call into the java factory to create the java impl */
280*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(client_data->java_s3express_provider_factory != NULL);
281*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3express_provider = (*env)->CallObjectMethod(
282*3c7ae9deSAndroid Build Coastguard Worker env,
283*3c7ae9deSAndroid Build Coastguard Worker client_data->java_s3express_provider_factory,
284*3c7ae9deSAndroid Build Coastguard Worker s3express_credentials_provider_factory_properties.createS3ExpressCredentialsProvider,
285*3c7ae9deSAndroid Build Coastguard Worker client_data->java_s3_client);
286*3c7ae9deSAndroid Build Coastguard Worker
287*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
288*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
289*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
290*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Failed to create Java S3Express Provider",
291*3c7ae9deSAndroid Build Coastguard Worker (void *)client_data->java_s3express_provider_factory);
292*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(allocator, provider);
293*3c7ae9deSAndroid Build Coastguard Worker provider = NULL;
294*3c7ae9deSAndroid Build Coastguard Worker goto done;
295*3c7ae9deSAndroid Build Coastguard Worker }
296*3c7ae9deSAndroid Build Coastguard Worker impl->java_s3express_provider = (*env)->NewGlobalRef(env, java_s3express_provider);
297*3c7ae9deSAndroid Build Coastguard Worker
298*3c7ae9deSAndroid Build Coastguard Worker jint jvmresult = (*env)->GetJavaVM(env, &impl->jvm);
299*3c7ae9deSAndroid Build Coastguard Worker (void)jvmresult;
300*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(jvmresult == 0);
301*3c7ae9deSAndroid Build Coastguard Worker
302*3c7ae9deSAndroid Build Coastguard Worker aws_s3express_credentials_provider_init_base(provider, allocator, &s_java_s3express_vtable, impl);
303*3c7ae9deSAndroid Build Coastguard Worker provider->shutdown_complete_callback = shutdown_complete_callback;
304*3c7ae9deSAndroid Build Coastguard Worker provider->shutdown_user_data = shutdown_user_data;
305*3c7ae9deSAndroid Build Coastguard Worker
306*3c7ae9deSAndroid Build Coastguard Worker /* We are done using the factory, when succeed, clean it up. TODO: we don't have to clean it up here */
307*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, client_data->java_s3express_provider_factory);
308*3c7ae9deSAndroid Build Coastguard Worker client_data->java_s3express_provider_factory = NULL;
309*3c7ae9deSAndroid Build Coastguard Worker
310*3c7ae9deSAndroid Build Coastguard Worker done:
311*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(client_data->jvm, env);
312*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
313*3c7ae9deSAndroid Build Coastguard Worker return provider;
314*3c7ae9deSAndroid Build Coastguard Worker }
315*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_s3_S3Client_s3ClientNew(JNIEnv * env,jclass jni_class,jobject s3_client_jobject,jbyteArray jni_region,jlong jni_client_bootstrap,jlong jni_tls_ctx,jobject java_signing_config,jlong part_size_jlong,jlong multipart_upload_threshold_jlong,jdouble throughput_target_gbps,jboolean enable_read_backpressure,jlong initial_read_window_jlong,int max_connections,jobject jni_standard_retry_options,jboolean compute_content_md5,jint jni_proxy_connection_type,jbyteArray jni_proxy_host,jint jni_proxy_port,jlong jni_proxy_tls_context,jint jni_proxy_authorization_type,jbyteArray jni_proxy_authorization_username,jbyteArray jni_proxy_authorization_password,jint jni_environment_variable_proxy_connection_type,jlong jni_environment_variable_proxy_tls_connection_options,jint jni_environment_variable_type,int connect_timeout_ms,jobject jni_s3_tcp_keep_alive_options,jlong jni_monitoring_throughput_threshold_in_bytes_per_second,jint jni_monitoring_failure_interval_in_seconds,jboolean enable_s3express,jobject java_s3express_provider_factory,jlong jni_memory_limit_bytes_jlong)316*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jlong JNICALL Java_software_amazon_awssdk_crt_s3_S3Client_s3ClientNew(
317*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
318*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
319*3c7ae9deSAndroid Build Coastguard Worker jobject s3_client_jobject,
320*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_region,
321*3c7ae9deSAndroid Build Coastguard Worker jlong jni_client_bootstrap,
322*3c7ae9deSAndroid Build Coastguard Worker jlong jni_tls_ctx,
323*3c7ae9deSAndroid Build Coastguard Worker jobject java_signing_config,
324*3c7ae9deSAndroid Build Coastguard Worker jlong part_size_jlong,
325*3c7ae9deSAndroid Build Coastguard Worker jlong multipart_upload_threshold_jlong,
326*3c7ae9deSAndroid Build Coastguard Worker jdouble throughput_target_gbps,
327*3c7ae9deSAndroid Build Coastguard Worker jboolean enable_read_backpressure,
328*3c7ae9deSAndroid Build Coastguard Worker jlong initial_read_window_jlong,
329*3c7ae9deSAndroid Build Coastguard Worker int max_connections,
330*3c7ae9deSAndroid Build Coastguard Worker jobject jni_standard_retry_options,
331*3c7ae9deSAndroid Build Coastguard Worker jboolean compute_content_md5,
332*3c7ae9deSAndroid Build Coastguard Worker jint jni_proxy_connection_type,
333*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_proxy_host,
334*3c7ae9deSAndroid Build Coastguard Worker jint jni_proxy_port,
335*3c7ae9deSAndroid Build Coastguard Worker jlong jni_proxy_tls_context,
336*3c7ae9deSAndroid Build Coastguard Worker jint jni_proxy_authorization_type,
337*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_proxy_authorization_username,
338*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_proxy_authorization_password,
339*3c7ae9deSAndroid Build Coastguard Worker jint jni_environment_variable_proxy_connection_type,
340*3c7ae9deSAndroid Build Coastguard Worker jlong jni_environment_variable_proxy_tls_connection_options,
341*3c7ae9deSAndroid Build Coastguard Worker jint jni_environment_variable_type,
342*3c7ae9deSAndroid Build Coastguard Worker int connect_timeout_ms,
343*3c7ae9deSAndroid Build Coastguard Worker jobject jni_s3_tcp_keep_alive_options,
344*3c7ae9deSAndroid Build Coastguard Worker jlong jni_monitoring_throughput_threshold_in_bytes_per_second,
345*3c7ae9deSAndroid Build Coastguard Worker jint jni_monitoring_failure_interval_in_seconds,
346*3c7ae9deSAndroid Build Coastguard Worker jboolean enable_s3express,
347*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3express_provider_factory,
348*3c7ae9deSAndroid Build Coastguard Worker jlong jni_memory_limit_bytes_jlong) {
349*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
350*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
351*3c7ae9deSAndroid Build Coastguard Worker
352*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
353*3c7ae9deSAndroid Build Coastguard Worker
354*3c7ae9deSAndroid Build Coastguard Worker struct aws_client_bootstrap *client_bootstrap = (struct aws_client_bootstrap *)jni_client_bootstrap;
355*3c7ae9deSAndroid Build Coastguard Worker
356*3c7ae9deSAndroid Build Coastguard Worker if (!client_bootstrap) {
357*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(env, "Invalid Client Bootstrap");
358*3c7ae9deSAndroid Build Coastguard Worker return (jlong)NULL;
359*3c7ae9deSAndroid Build Coastguard Worker }
360*3c7ae9deSAndroid Build Coastguard Worker
361*3c7ae9deSAndroid Build Coastguard Worker uint64_t part_size = (uint64_t)part_size_jlong;
362*3c7ae9deSAndroid Build Coastguard Worker uint64_t multipart_upload_threshold = (uint64_t)multipart_upload_threshold_jlong;
363*3c7ae9deSAndroid Build Coastguard Worker uint64_t memory_limit_in_bytes = (uint64_t)jni_memory_limit_bytes_jlong;
364*3c7ae9deSAndroid Build Coastguard Worker
365*3c7ae9deSAndroid Build Coastguard Worker size_t initial_read_window;
366*3c7ae9deSAndroid Build Coastguard Worker if (aws_size_t_from_java(env, &initial_read_window, initial_read_window_jlong, "Initial read window")) {
367*3c7ae9deSAndroid Build Coastguard Worker return (jlong)NULL;
368*3c7ae9deSAndroid Build Coastguard Worker }
369*3c7ae9deSAndroid Build Coastguard Worker
370*3c7ae9deSAndroid Build Coastguard Worker struct aws_retry_strategy *retry_strategy = NULL;
371*3c7ae9deSAndroid Build Coastguard Worker
372*3c7ae9deSAndroid Build Coastguard Worker if (jni_standard_retry_options != NULL) {
373*3c7ae9deSAndroid Build Coastguard Worker struct aws_standard_retry_options retry_options;
374*3c7ae9deSAndroid Build Coastguard Worker
375*3c7ae9deSAndroid Build Coastguard Worker if (aws_standard_retry_options_from_java(env, jni_standard_retry_options, &retry_options)) {
376*3c7ae9deSAndroid Build Coastguard Worker return (jlong)NULL;
377*3c7ae9deSAndroid Build Coastguard Worker }
378*3c7ae9deSAndroid Build Coastguard Worker
379*3c7ae9deSAndroid Build Coastguard Worker if (retry_options.backoff_retry_options.el_group == NULL) {
380*3c7ae9deSAndroid Build Coastguard Worker retry_options.backoff_retry_options.el_group = client_bootstrap->event_loop_group;
381*3c7ae9deSAndroid Build Coastguard Worker }
382*3c7ae9deSAndroid Build Coastguard Worker
383*3c7ae9deSAndroid Build Coastguard Worker retry_strategy = aws_retry_strategy_new_standard(allocator, &retry_options);
384*3c7ae9deSAndroid Build Coastguard Worker
385*3c7ae9deSAndroid Build Coastguard Worker if (retry_strategy == NULL) {
386*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Could not create retry strategy with standard-retry-options");
387*3c7ae9deSAndroid Build Coastguard Worker return (jlong)NULL;
388*3c7ae9deSAndroid Build Coastguard Worker }
389*3c7ae9deSAndroid Build Coastguard Worker }
390*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_tcp_keep_alive_options *s3_tcp_keep_alive_options = NULL;
391*3c7ae9deSAndroid Build Coastguard Worker
392*3c7ae9deSAndroid Build Coastguard Worker if (jni_s3_tcp_keep_alive_options != NULL) {
393*3c7ae9deSAndroid Build Coastguard Worker s3_tcp_keep_alive_options = aws_mem_calloc(allocator, 1, sizeof(struct aws_s3_tcp_keep_alive_options));
394*3c7ae9deSAndroid Build Coastguard Worker if (aws_s3_tcp_keep_alive_options_from_java(env, jni_s3_tcp_keep_alive_options, s3_tcp_keep_alive_options)) {
395*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Could not create s3_tcp_keep_alive_options");
396*3c7ae9deSAndroid Build Coastguard Worker return (jlong)NULL;
397*3c7ae9deSAndroid Build Coastguard Worker }
398*3c7ae9deSAndroid Build Coastguard Worker }
399*3c7ae9deSAndroid Build Coastguard Worker
400*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor region = aws_jni_byte_cursor_from_jbyteArray_acquire(env, jni_region);
401*3c7ae9deSAndroid Build Coastguard Worker
402*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_callback_data *callback_data =
403*3c7ae9deSAndroid Build Coastguard Worker aws_mem_calloc(allocator, 1, sizeof(struct s3_client_callback_data));
404*3c7ae9deSAndroid Build Coastguard Worker
405*3c7ae9deSAndroid Build Coastguard Worker struct aws_signing_config_aws signing_config;
406*3c7ae9deSAndroid Build Coastguard Worker struct aws_credentials *anonymous_credentials = NULL;
407*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(signing_config);
408*3c7ae9deSAndroid Build Coastguard Worker if (java_signing_config != NULL) {
409*3c7ae9deSAndroid Build Coastguard Worker if (aws_build_signing_config(env, java_signing_config, &callback_data->signing_config_data, &signing_config)) {
410*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Invalid signingConfig");
411*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(allocator, callback_data);
412*3c7ae9deSAndroid Build Coastguard Worker return (jlong)NULL;
413*3c7ae9deSAndroid Build Coastguard Worker }
414*3c7ae9deSAndroid Build Coastguard Worker } else {
415*3c7ae9deSAndroid Build Coastguard Worker anonymous_credentials = aws_credentials_new_anonymous(allocator);
416*3c7ae9deSAndroid Build Coastguard Worker signing_config.credentials = anonymous_credentials;
417*3c7ae9deSAndroid Build Coastguard Worker }
418*3c7ae9deSAndroid Build Coastguard Worker
419*3c7ae9deSAndroid Build Coastguard Worker if (java_s3express_provider_factory != NULL && enable_s3express) {
420*3c7ae9deSAndroid Build Coastguard Worker /* Create a JNI factory */
421*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3express_provider_factory = (*env)->NewGlobalRef(env, java_s3express_provider_factory);
422*3c7ae9deSAndroid Build Coastguard Worker }
423*3c7ae9deSAndroid Build Coastguard Worker
424*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(callback_data);
425*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3_client = (*env)->NewGlobalRef(env, s3_client_jobject);
426*3c7ae9deSAndroid Build Coastguard Worker
427*3c7ae9deSAndroid Build Coastguard Worker jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
428*3c7ae9deSAndroid Build Coastguard Worker (void)jvmresult;
429*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(jvmresult == 0);
430*3c7ae9deSAndroid Build Coastguard Worker
431*3c7ae9deSAndroid Build Coastguard Worker struct aws_tls_connection_options *tls_options = NULL;
432*3c7ae9deSAndroid Build Coastguard Worker struct aws_tls_connection_options tls_options_storage;
433*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(tls_options_storage);
434*3c7ae9deSAndroid Build Coastguard Worker if (jni_tls_ctx) {
435*3c7ae9deSAndroid Build Coastguard Worker struct aws_tls_ctx *tls_ctx = (void *)jni_tls_ctx;
436*3c7ae9deSAndroid Build Coastguard Worker tls_options = &tls_options_storage;
437*3c7ae9deSAndroid Build Coastguard Worker aws_tls_connection_options_init_from_ctx(tls_options, tls_ctx);
438*3c7ae9deSAndroid Build Coastguard Worker }
439*3c7ae9deSAndroid Build Coastguard Worker
440*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_client_config client_config = {
441*3c7ae9deSAndroid Build Coastguard Worker .max_active_connections_override = max_connections,
442*3c7ae9deSAndroid Build Coastguard Worker .region = region,
443*3c7ae9deSAndroid Build Coastguard Worker .client_bootstrap = client_bootstrap,
444*3c7ae9deSAndroid Build Coastguard Worker .tls_connection_options = tls_options,
445*3c7ae9deSAndroid Build Coastguard Worker .signing_config = &signing_config,
446*3c7ae9deSAndroid Build Coastguard Worker .part_size = part_size,
447*3c7ae9deSAndroid Build Coastguard Worker .multipart_upload_threshold = multipart_upload_threshold,
448*3c7ae9deSAndroid Build Coastguard Worker .throughput_target_gbps = throughput_target_gbps,
449*3c7ae9deSAndroid Build Coastguard Worker .enable_read_backpressure = enable_read_backpressure,
450*3c7ae9deSAndroid Build Coastguard Worker .initial_read_window = initial_read_window,
451*3c7ae9deSAndroid Build Coastguard Worker .retry_strategy = retry_strategy,
452*3c7ae9deSAndroid Build Coastguard Worker .shutdown_callback = s_on_s3_client_shutdown_complete_callback,
453*3c7ae9deSAndroid Build Coastguard Worker .shutdown_callback_user_data = callback_data,
454*3c7ae9deSAndroid Build Coastguard Worker .compute_content_md5 = compute_content_md5 ? AWS_MR_CONTENT_MD5_ENABLED : AWS_MR_CONTENT_MD5_DISABLED,
455*3c7ae9deSAndroid Build Coastguard Worker .connect_timeout_ms = connect_timeout_ms,
456*3c7ae9deSAndroid Build Coastguard Worker .tcp_keep_alive_options = s3_tcp_keep_alive_options,
457*3c7ae9deSAndroid Build Coastguard Worker .enable_s3express = enable_s3express,
458*3c7ae9deSAndroid Build Coastguard Worker .s3express_provider_override_factory =
459*3c7ae9deSAndroid Build Coastguard Worker java_s3express_provider_factory ? s_s3express_provider_jni_factory : NULL,
460*3c7ae9deSAndroid Build Coastguard Worker .factory_user_data = callback_data,
461*3c7ae9deSAndroid Build Coastguard Worker .memory_limit_in_bytes = memory_limit_in_bytes,
462*3c7ae9deSAndroid Build Coastguard Worker };
463*3c7ae9deSAndroid Build Coastguard Worker
464*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_monitoring_options monitoring_options;
465*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(monitoring_options);
466*3c7ae9deSAndroid Build Coastguard Worker if (jni_monitoring_throughput_threshold_in_bytes_per_second >= 0 &&
467*3c7ae9deSAndroid Build Coastguard Worker jni_monitoring_failure_interval_in_seconds >= 2) {
468*3c7ae9deSAndroid Build Coastguard Worker monitoring_options.minimum_throughput_bytes_per_second =
469*3c7ae9deSAndroid Build Coastguard Worker jni_monitoring_throughput_threshold_in_bytes_per_second;
470*3c7ae9deSAndroid Build Coastguard Worker monitoring_options.allowable_throughput_failure_interval_seconds = jni_monitoring_failure_interval_in_seconds;
471*3c7ae9deSAndroid Build Coastguard Worker client_config.monitoring_options = &monitoring_options;
472*3c7ae9deSAndroid Build Coastguard Worker }
473*3c7ae9deSAndroid Build Coastguard Worker
474*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_proxy_options proxy_options;
475*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(proxy_options);
476*3c7ae9deSAndroid Build Coastguard Worker
477*3c7ae9deSAndroid Build Coastguard Worker struct aws_tls_connection_options proxy_tls_conn_options;
478*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(proxy_tls_conn_options);
479*3c7ae9deSAndroid Build Coastguard Worker
480*3c7ae9deSAndroid Build Coastguard Worker aws_http_proxy_options_jni_init(
481*3c7ae9deSAndroid Build Coastguard Worker env,
482*3c7ae9deSAndroid Build Coastguard Worker &proxy_options,
483*3c7ae9deSAndroid Build Coastguard Worker jni_proxy_connection_type,
484*3c7ae9deSAndroid Build Coastguard Worker &proxy_tls_conn_options,
485*3c7ae9deSAndroid Build Coastguard Worker jni_proxy_host,
486*3c7ae9deSAndroid Build Coastguard Worker jni_proxy_port,
487*3c7ae9deSAndroid Build Coastguard Worker jni_proxy_authorization_username,
488*3c7ae9deSAndroid Build Coastguard Worker jni_proxy_authorization_password,
489*3c7ae9deSAndroid Build Coastguard Worker jni_proxy_authorization_type,
490*3c7ae9deSAndroid Build Coastguard Worker (struct aws_tls_ctx *)jni_proxy_tls_context);
491*3c7ae9deSAndroid Build Coastguard Worker
492*3c7ae9deSAndroid Build Coastguard Worker if (jni_proxy_host != NULL) {
493*3c7ae9deSAndroid Build Coastguard Worker client_config.proxy_options = &proxy_options;
494*3c7ae9deSAndroid Build Coastguard Worker }
495*3c7ae9deSAndroid Build Coastguard Worker
496*3c7ae9deSAndroid Build Coastguard Worker struct proxy_env_var_settings proxy_ev_settings;
497*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(proxy_ev_settings);
498*3c7ae9deSAndroid Build Coastguard Worker
499*3c7ae9deSAndroid Build Coastguard Worker aws_http_proxy_environment_variable_setting_jni_init(
500*3c7ae9deSAndroid Build Coastguard Worker &proxy_ev_settings,
501*3c7ae9deSAndroid Build Coastguard Worker jni_environment_variable_proxy_connection_type,
502*3c7ae9deSAndroid Build Coastguard Worker jni_environment_variable_type,
503*3c7ae9deSAndroid Build Coastguard Worker (struct aws_tls_connection_options *)jni_environment_variable_proxy_tls_connection_options);
504*3c7ae9deSAndroid Build Coastguard Worker
505*3c7ae9deSAndroid Build Coastguard Worker client_config.proxy_ev_settings = &proxy_ev_settings;
506*3c7ae9deSAndroid Build Coastguard Worker
507*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_client *client = aws_s3_client_new(allocator, &client_config);
508*3c7ae9deSAndroid Build Coastguard Worker if (!client) {
509*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3Client.aws_s3_client_new: creating aws_s3_client failed");
510*3c7ae9deSAndroid Build Coastguard Worker /* Clean up stuff */
511*3c7ae9deSAndroid Build Coastguard Worker aws_signing_config_data_clean_up(&callback_data->signing_config_data, env);
512*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(allocator, callback_data);
513*3c7ae9deSAndroid Build Coastguard Worker }
514*3c7ae9deSAndroid Build Coastguard Worker aws_credentials_release(anonymous_credentials);
515*3c7ae9deSAndroid Build Coastguard Worker
516*3c7ae9deSAndroid Build Coastguard Worker aws_retry_strategy_release(retry_strategy);
517*3c7ae9deSAndroid Build Coastguard Worker
518*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, jni_region, region);
519*3c7ae9deSAndroid Build Coastguard Worker
520*3c7ae9deSAndroid Build Coastguard Worker aws_http_proxy_options_jni_clean_up(
521*3c7ae9deSAndroid Build Coastguard Worker env, &proxy_options, jni_proxy_host, jni_proxy_authorization_username, jni_proxy_authorization_password);
522*3c7ae9deSAndroid Build Coastguard Worker
523*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), s3_tcp_keep_alive_options);
524*3c7ae9deSAndroid Build Coastguard Worker
525*3c7ae9deSAndroid Build Coastguard Worker return (jlong)client;
526*3c7ae9deSAndroid Build Coastguard Worker }
527*3c7ae9deSAndroid Build Coastguard Worker
528*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL
Java_software_amazon_awssdk_crt_s3_S3Client_s3ClientDestroy(JNIEnv * env,jclass jni_class,jlong jni_s3_client)529*3c7ae9deSAndroid Build Coastguard Worker Java_software_amazon_awssdk_crt_s3_S3Client_s3ClientDestroy(JNIEnv *env, jclass jni_class, jlong jni_s3_client) {
530*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
531*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
532*3c7ae9deSAndroid Build Coastguard Worker
533*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_client *client = (struct aws_s3_client *)jni_s3_client;
534*3c7ae9deSAndroid Build Coastguard Worker if (!client) {
535*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3Client.s3_client_clean_up: Invalid/null client");
536*3c7ae9deSAndroid Build Coastguard Worker return;
537*3c7ae9deSAndroid Build Coastguard Worker }
538*3c7ae9deSAndroid Build Coastguard Worker
539*3c7ae9deSAndroid Build Coastguard Worker aws_s3_client_release(client);
540*3c7ae9deSAndroid Build Coastguard Worker }
541*3c7ae9deSAndroid Build Coastguard Worker
s_on_s3_client_shutdown_complete_callback(void * user_data)542*3c7ae9deSAndroid Build Coastguard Worker static void s_on_s3_client_shutdown_complete_callback(void *user_data) {
543*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_callback_data *callback = (struct s3_client_callback_data *)user_data;
544*3c7ae9deSAndroid Build Coastguard Worker
545*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
546*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(callback->jvm);
547*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
548*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
549*3c7ae9deSAndroid Build Coastguard Worker return;
550*3c7ae9deSAndroid Build Coastguard Worker }
551*3c7ae9deSAndroid Build Coastguard Worker
552*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_DEBUG(AWS_LS_S3_CLIENT, "S3 Client Shutdown Complete");
553*3c7ae9deSAndroid Build Coastguard Worker if (callback->java_s3_client != NULL) {
554*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(env, callback->java_s3_client, s3_client_properties.onShutdownComplete);
555*3c7ae9deSAndroid Build Coastguard Worker
556*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
557*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
558*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
559*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Ignored Exception from S3Client.onShutdownCompete callback",
560*3c7ae9deSAndroid Build Coastguard Worker (void *)callback->java_s3_client);
561*3c7ae9deSAndroid Build Coastguard Worker }
562*3c7ae9deSAndroid Build Coastguard Worker }
563*3c7ae9deSAndroid Build Coastguard Worker
564*3c7ae9deSAndroid Build Coastguard Worker // We're done with this callback data, free it.
565*3c7ae9deSAndroid Build Coastguard Worker if (callback->java_s3express_provider_factory) {
566*3c7ae9deSAndroid Build Coastguard Worker /* Clean up factory data if still exist */
567*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, callback->java_s3express_provider_factory);
568*3c7ae9deSAndroid Build Coastguard Worker callback->java_s3express_provider_factory = NULL;
569*3c7ae9deSAndroid Build Coastguard Worker }
570*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, callback->java_s3_client);
571*3c7ae9deSAndroid Build Coastguard Worker
572*3c7ae9deSAndroid Build Coastguard Worker aws_signing_config_data_clean_up(&callback->signing_config_data, env);
573*3c7ae9deSAndroid Build Coastguard Worker
574*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(callback->jvm, env);
575*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
576*3c7ae9deSAndroid Build Coastguard Worker
577*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), user_data);
578*3c7ae9deSAndroid Build Coastguard Worker }
579*3c7ae9deSAndroid Build Coastguard Worker
s_on_s3_meta_request_body_callback(struct aws_s3_meta_request * meta_request,const struct aws_byte_cursor * body,uint64_t range_start,void * user_data)580*3c7ae9deSAndroid Build Coastguard Worker static int s_on_s3_meta_request_body_callback(
581*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request,
582*3c7ae9deSAndroid Build Coastguard Worker const struct aws_byte_cursor *body,
583*3c7ae9deSAndroid Build Coastguard Worker uint64_t range_start,
584*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
585*3c7ae9deSAndroid Build Coastguard Worker (void)body;
586*3c7ae9deSAndroid Build Coastguard Worker (void)range_start;
587*3c7ae9deSAndroid Build Coastguard Worker int return_value = AWS_OP_ERR;
588*3c7ae9deSAndroid Build Coastguard Worker
589*3c7ae9deSAndroid Build Coastguard Worker uint64_t range_end = range_start + body->len;
590*3c7ae9deSAndroid Build Coastguard Worker
591*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data *callback_data =
592*3c7ae9deSAndroid Build Coastguard Worker (struct s3_client_make_meta_request_callback_data *)user_data;
593*3c7ae9deSAndroid Build Coastguard Worker
594*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
595*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
596*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
597*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
598*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
599*3c7ae9deSAndroid Build Coastguard Worker }
600*3c7ae9deSAndroid Build Coastguard Worker
601*3c7ae9deSAndroid Build Coastguard Worker jobject jni_payload = aws_jni_byte_array_from_cursor(env, body);
602*3c7ae9deSAndroid Build Coastguard Worker if (jni_payload == NULL) {
603*3c7ae9deSAndroid Build Coastguard Worker /* JVM is out of memory, but native code can still have memory available, handle it and don't crash. */
604*3c7ae9deSAndroid Build Coastguard Worker aws_jni_check_and_clear_exception(env);
605*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(callback_data->jvm, env);
606*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
607*3c7ae9deSAndroid Build Coastguard Worker return aws_raise_error(AWS_ERROR_JAVA_CRT_JVM_OUT_OF_MEMORY);
608*3c7ae9deSAndroid Build Coastguard Worker }
609*3c7ae9deSAndroid Build Coastguard Worker
610*3c7ae9deSAndroid Build Coastguard Worker jint body_response_result = 0;
611*3c7ae9deSAndroid Build Coastguard Worker
612*3c7ae9deSAndroid Build Coastguard Worker if (callback_data->java_s3_meta_request_response_handler_native_adapter != NULL) {
613*3c7ae9deSAndroid Build Coastguard Worker body_response_result = (*env)->CallIntMethod(
614*3c7ae9deSAndroid Build Coastguard Worker env,
615*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3_meta_request_response_handler_native_adapter,
616*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_response_handler_native_adapter_properties.onResponseBody,
617*3c7ae9deSAndroid Build Coastguard Worker jni_payload,
618*3c7ae9deSAndroid Build Coastguard Worker range_start,
619*3c7ae9deSAndroid Build Coastguard Worker range_end);
620*3c7ae9deSAndroid Build Coastguard Worker
621*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_get_and_clear_exception(env, &(callback_data->java_exception))) {
622*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
623*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
624*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Received exception from S3MetaRequest.onResponseBody callback",
625*3c7ae9deSAndroid Build Coastguard Worker (void *)meta_request);
626*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
627*3c7ae9deSAndroid Build Coastguard Worker goto cleanup;
628*3c7ae9deSAndroid Build Coastguard Worker }
629*3c7ae9deSAndroid Build Coastguard Worker
630*3c7ae9deSAndroid Build Coastguard Worker /* The Java onResponseBody API lets users return a size for auto-incrementing the read window */
631*3c7ae9deSAndroid Build Coastguard Worker if (body_response_result > 0) {
632*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_increment_read_window(meta_request, (uint64_t)body_response_result);
633*3c7ae9deSAndroid Build Coastguard Worker }
634*3c7ae9deSAndroid Build Coastguard Worker }
635*3c7ae9deSAndroid Build Coastguard Worker return_value = AWS_OP_SUCCESS;
636*3c7ae9deSAndroid Build Coastguard Worker
637*3c7ae9deSAndroid Build Coastguard Worker cleanup:
638*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_payload);
639*3c7ae9deSAndroid Build Coastguard Worker
640*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(callback_data->jvm, env);
641*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
642*3c7ae9deSAndroid Build Coastguard Worker
643*3c7ae9deSAndroid Build Coastguard Worker return return_value;
644*3c7ae9deSAndroid Build Coastguard Worker }
645*3c7ae9deSAndroid Build Coastguard Worker
s_marshal_http_headers_to_buf(const struct aws_http_headers * headers,struct aws_byte_buf * out_headers_buf)646*3c7ae9deSAndroid Build Coastguard Worker static int s_marshal_http_headers_to_buf(const struct aws_http_headers *headers, struct aws_byte_buf *out_headers_buf) {
647*3c7ae9deSAndroid Build Coastguard Worker /* calculate initial header capacity */
648*3c7ae9deSAndroid Build Coastguard Worker size_t headers_initial_capacity = 0;
649*3c7ae9deSAndroid Build Coastguard Worker for (size_t header_index = 0; header_index < aws_http_headers_count(headers); ++header_index) {
650*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_header header;
651*3c7ae9deSAndroid Build Coastguard Worker aws_http_headers_get_index(headers, header_index, &header);
652*3c7ae9deSAndroid Build Coastguard Worker /* aws_marshal_http_headers_array_to_dynamic_buffer() impl drives this calculation */
653*3c7ae9deSAndroid Build Coastguard Worker headers_initial_capacity += header.name.len + header.value.len + 8;
654*3c7ae9deSAndroid Build Coastguard Worker }
655*3c7ae9deSAndroid Build Coastguard Worker
656*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
657*3c7ae9deSAndroid Build Coastguard Worker
658*3c7ae9deSAndroid Build Coastguard Worker if (aws_byte_buf_init(out_headers_buf, allocator, headers_initial_capacity)) {
659*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
660*3c7ae9deSAndroid Build Coastguard Worker }
661*3c7ae9deSAndroid Build Coastguard Worker
662*3c7ae9deSAndroid Build Coastguard Worker if (aws_marshal_http_headers_to_dynamic_buffer(out_headers_buf, headers)) {
663*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(out_headers_buf);
664*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
665*3c7ae9deSAndroid Build Coastguard Worker }
666*3c7ae9deSAndroid Build Coastguard Worker
667*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_SUCCESS;
668*3c7ae9deSAndroid Build Coastguard Worker }
669*3c7ae9deSAndroid Build Coastguard Worker
s_on_s3_meta_request_headers_callback(struct aws_s3_meta_request * meta_request,const struct aws_http_headers * headers,int response_status,void * user_data)670*3c7ae9deSAndroid Build Coastguard Worker static int s_on_s3_meta_request_headers_callback(
671*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request,
672*3c7ae9deSAndroid Build Coastguard Worker const struct aws_http_headers *headers,
673*3c7ae9deSAndroid Build Coastguard Worker int response_status,
674*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
675*3c7ae9deSAndroid Build Coastguard Worker int return_value = AWS_OP_ERR;
676*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data *callback_data =
677*3c7ae9deSAndroid Build Coastguard Worker (struct s3_client_make_meta_request_callback_data *)user_data;
678*3c7ae9deSAndroid Build Coastguard Worker
679*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
680*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
681*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
682*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
683*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
684*3c7ae9deSAndroid Build Coastguard Worker }
685*3c7ae9deSAndroid Build Coastguard Worker
686*3c7ae9deSAndroid Build Coastguard Worker jobject java_headers_buffer = NULL;
687*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_buf headers_buf;
688*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(headers_buf);
689*3c7ae9deSAndroid Build Coastguard Worker
690*3c7ae9deSAndroid Build Coastguard Worker if (s_marshal_http_headers_to_buf(headers, &headers_buf)) {
691*3c7ae9deSAndroid Build Coastguard Worker goto cleanup;
692*3c7ae9deSAndroid Build Coastguard Worker }
693*3c7ae9deSAndroid Build Coastguard Worker
694*3c7ae9deSAndroid Build Coastguard Worker java_headers_buffer = aws_jni_direct_byte_buffer_from_raw_ptr(env, headers_buf.buffer, headers_buf.len);
695*3c7ae9deSAndroid Build Coastguard Worker if (java_headers_buffer == NULL) {
696*3c7ae9deSAndroid Build Coastguard Worker aws_jni_check_and_clear_exception(env);
697*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_JAVA_CRT_JVM_OUT_OF_MEMORY);
698*3c7ae9deSAndroid Build Coastguard Worker goto cleanup;
699*3c7ae9deSAndroid Build Coastguard Worker }
700*3c7ae9deSAndroid Build Coastguard Worker
701*3c7ae9deSAndroid Build Coastguard Worker if (callback_data->java_s3_meta_request_response_handler_native_adapter != NULL) {
702*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
703*3c7ae9deSAndroid Build Coastguard Worker env,
704*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3_meta_request_response_handler_native_adapter,
705*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_response_handler_native_adapter_properties.onResponseHeaders,
706*3c7ae9deSAndroid Build Coastguard Worker response_status,
707*3c7ae9deSAndroid Build Coastguard Worker java_headers_buffer);
708*3c7ae9deSAndroid Build Coastguard Worker
709*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_get_and_clear_exception(env, &(callback_data->java_exception))) {
710*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
711*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
712*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Exception thrown from S3MetaRequest.onResponseHeaders callback",
713*3c7ae9deSAndroid Build Coastguard Worker (void *)meta_request);
714*3c7ae9deSAndroid Build Coastguard Worker
715*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
716*3c7ae9deSAndroid Build Coastguard Worker goto cleanup;
717*3c7ae9deSAndroid Build Coastguard Worker }
718*3c7ae9deSAndroid Build Coastguard Worker }
719*3c7ae9deSAndroid Build Coastguard Worker return_value = AWS_OP_SUCCESS;
720*3c7ae9deSAndroid Build Coastguard Worker
721*3c7ae9deSAndroid Build Coastguard Worker cleanup:
722*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(&headers_buf);
723*3c7ae9deSAndroid Build Coastguard Worker if (java_headers_buffer) {
724*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, java_headers_buffer);
725*3c7ae9deSAndroid Build Coastguard Worker }
726*3c7ae9deSAndroid Build Coastguard Worker
727*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(callback_data->jvm, env);
728*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
729*3c7ae9deSAndroid Build Coastguard Worker
730*3c7ae9deSAndroid Build Coastguard Worker return return_value;
731*3c7ae9deSAndroid Build Coastguard Worker }
732*3c7ae9deSAndroid Build Coastguard Worker
s_on_s3_meta_request_finish_callback(struct aws_s3_meta_request * meta_request,const struct aws_s3_meta_request_result * meta_request_result,void * user_data)733*3c7ae9deSAndroid Build Coastguard Worker static void s_on_s3_meta_request_finish_callback(
734*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request,
735*3c7ae9deSAndroid Build Coastguard Worker const struct aws_s3_meta_request_result *meta_request_result,
736*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
737*3c7ae9deSAndroid Build Coastguard Worker
738*3c7ae9deSAndroid Build Coastguard Worker (void)meta_request;
739*3c7ae9deSAndroid Build Coastguard Worker
740*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data *callback_data =
741*3c7ae9deSAndroid Build Coastguard Worker (struct s3_client_make_meta_request_callback_data *)user_data;
742*3c7ae9deSAndroid Build Coastguard Worker
743*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
744*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
745*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
746*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
747*3c7ae9deSAndroid Build Coastguard Worker return;
748*3c7ae9deSAndroid Build Coastguard Worker }
749*3c7ae9deSAndroid Build Coastguard Worker
750*3c7ae9deSAndroid Build Coastguard Worker if (callback_data->java_s3_meta_request_response_handler_native_adapter != NULL) {
751*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_buf *error_response_body = meta_request_result->error_response_body;
752*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor error_response_cursor;
753*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(error_response_cursor);
754*3c7ae9deSAndroid Build Coastguard Worker if (error_response_body) {
755*3c7ae9deSAndroid Build Coastguard Worker error_response_cursor = aws_byte_cursor_from_buf(error_response_body);
756*3c7ae9deSAndroid Build Coastguard Worker }
757*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_payload = aws_jni_byte_array_from_cursor(env, &error_response_cursor);
758*3c7ae9deSAndroid Build Coastguard Worker /* Only propagate java_exception if crt error code is callback failure */
759*3c7ae9deSAndroid Build Coastguard Worker jthrowable java_exception =
760*3c7ae9deSAndroid Build Coastguard Worker meta_request_result->error_code == AWS_ERROR_HTTP_CALLBACK_FAILURE ? callback_data->java_exception : NULL;
761*3c7ae9deSAndroid Build Coastguard Worker
762*3c7ae9deSAndroid Build Coastguard Worker jobject java_error_headers_buffer = NULL;
763*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_buf headers_buf;
764*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(headers_buf);
765*3c7ae9deSAndroid Build Coastguard Worker if (meta_request_result->error_response_headers) {
766*3c7ae9deSAndroid Build Coastguard Worker /* Ignore any errors and just report the original error without headers */
767*3c7ae9deSAndroid Build Coastguard Worker if (s_marshal_http_headers_to_buf(meta_request_result->error_response_headers, &headers_buf) ==
768*3c7ae9deSAndroid Build Coastguard Worker AWS_OP_SUCCESS) {
769*3c7ae9deSAndroid Build Coastguard Worker java_error_headers_buffer =
770*3c7ae9deSAndroid Build Coastguard Worker aws_jni_direct_byte_buffer_from_raw_ptr(env, headers_buf.buffer, headers_buf.len);
771*3c7ae9deSAndroid Build Coastguard Worker if (java_error_headers_buffer == NULL) {
772*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
773*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
774*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Ignored Exception from "
775*3c7ae9deSAndroid Build Coastguard Worker "S3MetaRequest.onFinished.aws_jni_direct_byte_buffer_from_raw_ptr",
776*3c7ae9deSAndroid Build Coastguard Worker (void *)meta_request);
777*3c7ae9deSAndroid Build Coastguard Worker aws_jni_check_and_clear_exception(env);
778*3c7ae9deSAndroid Build Coastguard Worker }
779*3c7ae9deSAndroid Build Coastguard Worker } else {
780*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
781*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
782*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Ignored Exception from S3MetaRequest.onFinished.s_marshal_http_headers_to_buf",
783*3c7ae9deSAndroid Build Coastguard Worker (void *)meta_request);
784*3c7ae9deSAndroid Build Coastguard Worker }
785*3c7ae9deSAndroid Build Coastguard Worker }
786*3c7ae9deSAndroid Build Coastguard Worker
787*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
788*3c7ae9deSAndroid Build Coastguard Worker env,
789*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3_meta_request_response_handler_native_adapter,
790*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_response_handler_native_adapter_properties.onFinished,
791*3c7ae9deSAndroid Build Coastguard Worker meta_request_result->error_code,
792*3c7ae9deSAndroid Build Coastguard Worker meta_request_result->response_status,
793*3c7ae9deSAndroid Build Coastguard Worker jni_payload,
794*3c7ae9deSAndroid Build Coastguard Worker meta_request_result->validation_algorithm,
795*3c7ae9deSAndroid Build Coastguard Worker meta_request_result->did_validate,
796*3c7ae9deSAndroid Build Coastguard Worker java_exception,
797*3c7ae9deSAndroid Build Coastguard Worker java_error_headers_buffer);
798*3c7ae9deSAndroid Build Coastguard Worker
799*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
800*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
801*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
802*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Ignored Exception from S3MetaRequest.onFinished callback",
803*3c7ae9deSAndroid Build Coastguard Worker (void *)meta_request);
804*3c7ae9deSAndroid Build Coastguard Worker }
805*3c7ae9deSAndroid Build Coastguard Worker if (jni_payload) {
806*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_payload);
807*3c7ae9deSAndroid Build Coastguard Worker }
808*3c7ae9deSAndroid Build Coastguard Worker
809*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(&headers_buf);
810*3c7ae9deSAndroid Build Coastguard Worker if (java_error_headers_buffer) {
811*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, java_error_headers_buffer);
812*3c7ae9deSAndroid Build Coastguard Worker }
813*3c7ae9deSAndroid Build Coastguard Worker }
814*3c7ae9deSAndroid Build Coastguard Worker
815*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(callback_data->jvm, env);
816*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
817*3c7ae9deSAndroid Build Coastguard Worker }
818*3c7ae9deSAndroid Build Coastguard Worker
s_on_s3_meta_request_progress_callback(struct aws_s3_meta_request * meta_request,const struct aws_s3_meta_request_progress * progress,void * user_data)819*3c7ae9deSAndroid Build Coastguard Worker static void s_on_s3_meta_request_progress_callback(
820*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request,
821*3c7ae9deSAndroid Build Coastguard Worker const struct aws_s3_meta_request_progress *progress,
822*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
823*3c7ae9deSAndroid Build Coastguard Worker
824*3c7ae9deSAndroid Build Coastguard Worker (void)meta_request;
825*3c7ae9deSAndroid Build Coastguard Worker
826*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data *callback_data =
827*3c7ae9deSAndroid Build Coastguard Worker (struct s3_client_make_meta_request_callback_data *)user_data;
828*3c7ae9deSAndroid Build Coastguard Worker
829*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
830*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
831*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
832*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
833*3c7ae9deSAndroid Build Coastguard Worker return;
834*3c7ae9deSAndroid Build Coastguard Worker }
835*3c7ae9deSAndroid Build Coastguard Worker
836*3c7ae9deSAndroid Build Coastguard Worker jobject progress_object = (*env)->NewObject(
837*3c7ae9deSAndroid Build Coastguard Worker env,
838*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_progress_properties.s3_meta_request_progress_class,
839*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_progress_properties.s3_meta_request_progress_constructor_method_id);
840*3c7ae9deSAndroid Build Coastguard Worker if ((*env)->ExceptionCheck(env) || progress_object == NULL) {
841*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
842*3c7ae9deSAndroid Build Coastguard Worker env, "S3MetaRequestResponseHandler.onProgress: Failed to create S3MetaRequestProgress object.");
843*3c7ae9deSAndroid Build Coastguard Worker goto done;
844*3c7ae9deSAndroid Build Coastguard Worker }
845*3c7ae9deSAndroid Build Coastguard Worker
846*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetLongField(
847*3c7ae9deSAndroid Build Coastguard Worker env,
848*3c7ae9deSAndroid Build Coastguard Worker progress_object,
849*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_progress_properties.bytes_transferred_field_id,
850*3c7ae9deSAndroid Build Coastguard Worker progress->bytes_transferred);
851*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetLongField(
852*3c7ae9deSAndroid Build Coastguard Worker env, progress_object, s3_meta_request_progress_properties.content_length_field_id, progress->content_length);
853*3c7ae9deSAndroid Build Coastguard Worker
854*3c7ae9deSAndroid Build Coastguard Worker if (callback_data->java_s3_meta_request_response_handler_native_adapter != NULL) {
855*3c7ae9deSAndroid Build Coastguard Worker
856*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
857*3c7ae9deSAndroid Build Coastguard Worker env,
858*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3_meta_request_response_handler_native_adapter,
859*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_response_handler_native_adapter_properties.onProgress,
860*3c7ae9deSAndroid Build Coastguard Worker progress_object);
861*3c7ae9deSAndroid Build Coastguard Worker
862*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
863*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
864*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
865*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Ignored Exception from S3MetaRequest.onProgress callback",
866*3c7ae9deSAndroid Build Coastguard Worker (void *)meta_request);
867*3c7ae9deSAndroid Build Coastguard Worker }
868*3c7ae9deSAndroid Build Coastguard Worker }
869*3c7ae9deSAndroid Build Coastguard Worker
870*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, progress_object);
871*3c7ae9deSAndroid Build Coastguard Worker
872*3c7ae9deSAndroid Build Coastguard Worker done:
873*3c7ae9deSAndroid Build Coastguard Worker
874*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(callback_data->jvm, env);
875*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
876*3c7ae9deSAndroid Build Coastguard Worker }
877*3c7ae9deSAndroid Build Coastguard Worker
s_s3_meta_request_callback_cleanup(JNIEnv * env,struct s3_client_make_meta_request_callback_data * callback_data)878*3c7ae9deSAndroid Build Coastguard Worker static void s_s3_meta_request_callback_cleanup(
879*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
880*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data *callback_data) {
881*3c7ae9deSAndroid Build Coastguard Worker if (callback_data) {
882*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, callback_data->java_s3_meta_request);
883*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, callback_data->java_s3_meta_request_response_handler_native_adapter);
884*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, callback_data->java_exception);
885*3c7ae9deSAndroid Build Coastguard Worker aws_signing_config_data_clean_up(&callback_data->signing_config_data, env);
886*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), callback_data);
887*3c7ae9deSAndroid Build Coastguard Worker }
888*3c7ae9deSAndroid Build Coastguard Worker }
889*3c7ae9deSAndroid Build Coastguard Worker
s_native_resume_token_from_java_new(JNIEnv * env,jobject resume_token_jni)890*3c7ae9deSAndroid Build Coastguard Worker static struct aws_s3_meta_request_resume_token *s_native_resume_token_from_java_new(
891*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
892*3c7ae9deSAndroid Build Coastguard Worker jobject resume_token_jni) {
893*3c7ae9deSAndroid Build Coastguard Worker
894*3c7ae9deSAndroid Build Coastguard Worker if (resume_token_jni == NULL) {
895*3c7ae9deSAndroid Build Coastguard Worker return NULL;
896*3c7ae9deSAndroid Build Coastguard Worker }
897*3c7ae9deSAndroid Build Coastguard Worker
898*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
899*3c7ae9deSAndroid Build Coastguard Worker
900*3c7ae9deSAndroid Build Coastguard Worker jint native_type =
901*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetIntField(env, resume_token_jni, s3_meta_request_resume_token_properties.native_type_field_id);
902*3c7ae9deSAndroid Build Coastguard Worker
903*3c7ae9deSAndroid Build Coastguard Worker if (native_type != AWS_S3_META_REQUEST_TYPE_PUT_OBJECT) {
904*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(
905*3c7ae9deSAndroid Build Coastguard Worker env, "ResumeToken: Operations other than PutObject are not supported for resume.");
906*3c7ae9deSAndroid Build Coastguard Worker return NULL;
907*3c7ae9deSAndroid Build Coastguard Worker }
908*3c7ae9deSAndroid Build Coastguard Worker
909*3c7ae9deSAndroid Build Coastguard Worker jlong part_size_jni =
910*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetLongField(env, resume_token_jni, s3_meta_request_resume_token_properties.part_size_field_id);
911*3c7ae9deSAndroid Build Coastguard Worker jlong total_num_parts_jni =
912*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetLongField(env, resume_token_jni, s3_meta_request_resume_token_properties.total_num_parts_field_id);
913*3c7ae9deSAndroid Build Coastguard Worker jlong num_parts_completed_jni = (*env)->GetLongField(
914*3c7ae9deSAndroid Build Coastguard Worker env, resume_token_jni, s3_meta_request_resume_token_properties.num_parts_completed_field_id);
915*3c7ae9deSAndroid Build Coastguard Worker
916*3c7ae9deSAndroid Build Coastguard Worker jstring upload_id_jni =
917*3c7ae9deSAndroid Build Coastguard Worker (*env)->GetObjectField(env, resume_token_jni, s3_meta_request_resume_token_properties.upload_id_field_id);
918*3c7ae9deSAndroid Build Coastguard Worker if (upload_id_jni == NULL) {
919*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(env, "ResumeToken: UploadId must not be NULL.");
920*3c7ae9deSAndroid Build Coastguard Worker return NULL;
921*3c7ae9deSAndroid Build Coastguard Worker }
922*3c7ae9deSAndroid Build Coastguard Worker
923*3c7ae9deSAndroid Build Coastguard Worker struct aws_string *upload_id = aws_jni_new_string_from_jstring(env, upload_id_jni);
924*3c7ae9deSAndroid Build Coastguard Worker
925*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_upload_resume_token_options upload_options = {
926*3c7ae9deSAndroid Build Coastguard Worker .part_size = (uint64_t)part_size_jni,
927*3c7ae9deSAndroid Build Coastguard Worker .total_num_parts = (size_t)total_num_parts_jni,
928*3c7ae9deSAndroid Build Coastguard Worker .num_parts_completed = (size_t)num_parts_completed_jni,
929*3c7ae9deSAndroid Build Coastguard Worker .upload_id = aws_byte_cursor_from_string(upload_id),
930*3c7ae9deSAndroid Build Coastguard Worker };
931*3c7ae9deSAndroid Build Coastguard Worker
932*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request_resume_token *resume_token =
933*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_resume_token_new_upload(allocator, &upload_options);
934*3c7ae9deSAndroid Build Coastguard Worker aws_string_destroy(upload_id);
935*3c7ae9deSAndroid Build Coastguard Worker
936*3c7ae9deSAndroid Build Coastguard Worker return resume_token;
937*3c7ae9deSAndroid Build Coastguard Worker }
938*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_s3_S3Client_s3ClientMakeMetaRequest(JNIEnv * env,jclass jni_class,jlong jni_s3_client,jobject java_s3_meta_request_jobject,jbyteArray jni_region,jint meta_request_type,jint checksum_location,jint checksum_algorithm,jboolean validate_response,jintArray jni_marshalled_validate_algorithms,jbyteArray jni_marshalled_message_data,jobject jni_http_request_body_stream,jbyteArray jni_request_filepath,jobject java_signing_config,jobject java_response_handler_jobject,jbyteArray jni_endpoint,jobject java_resume_token_jobject)939*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jlong JNICALL Java_software_amazon_awssdk_crt_s3_S3Client_s3ClientMakeMetaRequest(
940*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
941*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
942*3c7ae9deSAndroid Build Coastguard Worker jlong jni_s3_client,
943*3c7ae9deSAndroid Build Coastguard Worker jobject java_s3_meta_request_jobject,
944*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_region,
945*3c7ae9deSAndroid Build Coastguard Worker jint meta_request_type,
946*3c7ae9deSAndroid Build Coastguard Worker jint checksum_location,
947*3c7ae9deSAndroid Build Coastguard Worker jint checksum_algorithm,
948*3c7ae9deSAndroid Build Coastguard Worker jboolean validate_response,
949*3c7ae9deSAndroid Build Coastguard Worker jintArray jni_marshalled_validate_algorithms,
950*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_marshalled_message_data,
951*3c7ae9deSAndroid Build Coastguard Worker jobject jni_http_request_body_stream,
952*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_request_filepath,
953*3c7ae9deSAndroid Build Coastguard Worker jobject java_signing_config,
954*3c7ae9deSAndroid Build Coastguard Worker jobject java_response_handler_jobject,
955*3c7ae9deSAndroid Build Coastguard Worker jbyteArray jni_endpoint,
956*3c7ae9deSAndroid Build Coastguard Worker jobject java_resume_token_jobject) {
957*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
958*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
959*3c7ae9deSAndroid Build Coastguard Worker
960*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
961*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_client *client = (struct aws_s3_client *)jni_s3_client;
962*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor request_filepath;
963*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(request_filepath);
964*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request_resume_token *resume_token =
965*3c7ae9deSAndroid Build Coastguard Worker s_native_resume_token_from_java_new(env, java_resume_token_jobject);
966*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request = NULL;
967*3c7ae9deSAndroid Build Coastguard Worker bool success = false;
968*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor region = aws_jni_byte_cursor_from_jbyteArray_acquire(env, jni_region);
969*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_message *request_message = NULL;
970*3c7ae9deSAndroid Build Coastguard Worker
971*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data *callback_data =
972*3c7ae9deSAndroid Build Coastguard Worker aws_mem_calloc(allocator, 1, sizeof(struct s3_client_make_meta_request_callback_data));
973*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(callback_data);
974*3c7ae9deSAndroid Build Coastguard Worker struct aws_signing_config_aws signing_config;
975*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(signing_config);
976*3c7ae9deSAndroid Build Coastguard Worker if (java_signing_config != NULL) {
977*3c7ae9deSAndroid Build Coastguard Worker if (aws_build_signing_config(env, java_signing_config, &callback_data->signing_config_data, &signing_config)) {
978*3c7ae9deSAndroid Build Coastguard Worker goto done;
979*3c7ae9deSAndroid Build Coastguard Worker }
980*3c7ae9deSAndroid Build Coastguard Worker }
981*3c7ae9deSAndroid Build Coastguard Worker
982*3c7ae9deSAndroid Build Coastguard Worker jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
983*3c7ae9deSAndroid Build Coastguard Worker (void)jvmresult;
984*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(jvmresult == 0);
985*3c7ae9deSAndroid Build Coastguard Worker
986*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3_meta_request = (*env)->NewGlobalRef(env, java_s3_meta_request_jobject);
987*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(callback_data->java_s3_meta_request != NULL);
988*3c7ae9deSAndroid Build Coastguard Worker
989*3c7ae9deSAndroid Build Coastguard Worker callback_data->java_s3_meta_request_response_handler_native_adapter =
990*3c7ae9deSAndroid Build Coastguard Worker (*env)->NewGlobalRef(env, java_response_handler_jobject);
991*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(callback_data->java_s3_meta_request_response_handler_native_adapter != NULL);
992*3c7ae9deSAndroid Build Coastguard Worker
993*3c7ae9deSAndroid Build Coastguard Worker request_message = aws_http_message_new_request(allocator);
994*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(request_message);
995*3c7ae9deSAndroid Build Coastguard Worker
996*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(
997*3c7ae9deSAndroid Build Coastguard Worker AWS_OP_SUCCESS == aws_apply_java_http_request_changes_to_native_request(
998*3c7ae9deSAndroid Build Coastguard Worker env, jni_marshalled_message_data, jni_http_request_body_stream, request_message));
999*3c7ae9deSAndroid Build Coastguard Worker
1000*3c7ae9deSAndroid Build Coastguard Worker if (jni_request_filepath) {
1001*3c7ae9deSAndroid Build Coastguard Worker request_filepath = aws_jni_byte_cursor_from_jbyteArray_acquire(env, jni_request_filepath);
1002*3c7ae9deSAndroid Build Coastguard Worker if (request_filepath.ptr == NULL) {
1003*3c7ae9deSAndroid Build Coastguard Worker goto done;
1004*3c7ae9deSAndroid Build Coastguard Worker }
1005*3c7ae9deSAndroid Build Coastguard Worker if (request_filepath.len == 0) {
1006*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(env, "Request file path cannot be empty");
1007*3c7ae9deSAndroid Build Coastguard Worker goto done;
1008*3c7ae9deSAndroid Build Coastguard Worker }
1009*3c7ae9deSAndroid Build Coastguard Worker }
1010*3c7ae9deSAndroid Build Coastguard Worker
1011*3c7ae9deSAndroid Build Coastguard Worker struct aws_uri endpoint;
1012*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(endpoint);
1013*3c7ae9deSAndroid Build Coastguard Worker if (jni_endpoint != NULL) {
1014*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor endpoint_str = aws_jni_byte_cursor_from_jbyteArray_acquire(env, jni_endpoint);
1015*3c7ae9deSAndroid Build Coastguard Worker int uri_parse = aws_uri_init_parse(&endpoint, allocator, &endpoint_str);
1016*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, jni_endpoint, endpoint_str);
1017*3c7ae9deSAndroid Build Coastguard Worker if (uri_parse) {
1018*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3Client.aws_s3_client_make_meta_request: failed to parse endpoint");
1019*3c7ae9deSAndroid Build Coastguard Worker goto done;
1020*3c7ae9deSAndroid Build Coastguard Worker }
1021*3c7ae9deSAndroid Build Coastguard Worker }
1022*3c7ae9deSAndroid Build Coastguard Worker
1023*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_checksum_config checksum_config = {
1024*3c7ae9deSAndroid Build Coastguard Worker .location = checksum_location,
1025*3c7ae9deSAndroid Build Coastguard Worker .checksum_algorithm = checksum_algorithm,
1026*3c7ae9deSAndroid Build Coastguard Worker .validate_response_checksum = validate_response,
1027*3c7ae9deSAndroid Build Coastguard Worker };
1028*3c7ae9deSAndroid Build Coastguard Worker
1029*3c7ae9deSAndroid Build Coastguard Worker struct aws_array_list response_checksum_list;
1030*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(response_checksum_list);
1031*3c7ae9deSAndroid Build Coastguard Worker if (jni_marshalled_validate_algorithms != NULL) {
1032*3c7ae9deSAndroid Build Coastguard Worker jint *marshalled_algorithms = (*env)->GetIntArrayElements(env, jni_marshalled_validate_algorithms, NULL);
1033*3c7ae9deSAndroid Build Coastguard Worker const size_t marshalled_len = (*env)->GetArrayLength(env, jni_marshalled_validate_algorithms);
1034*3c7ae9deSAndroid Build Coastguard Worker aws_array_list_init_dynamic(&response_checksum_list, allocator, marshalled_len, sizeof(int));
1035*3c7ae9deSAndroid Build Coastguard Worker for (size_t i = 0; i < marshalled_len; ++i) {
1036*3c7ae9deSAndroid Build Coastguard Worker enum aws_s3_checksum_algorithm algorithm = (int)marshalled_algorithms[i];
1037*3c7ae9deSAndroid Build Coastguard Worker aws_array_list_push_back(&response_checksum_list, &algorithm);
1038*3c7ae9deSAndroid Build Coastguard Worker }
1039*3c7ae9deSAndroid Build Coastguard Worker checksum_config.validate_checksum_algorithms = &response_checksum_list;
1040*3c7ae9deSAndroid Build Coastguard Worker }
1041*3c7ae9deSAndroid Build Coastguard Worker
1042*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request_options meta_request_options = {
1043*3c7ae9deSAndroid Build Coastguard Worker .type = meta_request_type,
1044*3c7ae9deSAndroid Build Coastguard Worker .checksum_config = &checksum_config,
1045*3c7ae9deSAndroid Build Coastguard Worker .message = request_message,
1046*3c7ae9deSAndroid Build Coastguard Worker .send_filepath = request_filepath,
1047*3c7ae9deSAndroid Build Coastguard Worker .user_data = callback_data,
1048*3c7ae9deSAndroid Build Coastguard Worker .signing_config = java_signing_config ? &signing_config : NULL,
1049*3c7ae9deSAndroid Build Coastguard Worker .headers_callback = s_on_s3_meta_request_headers_callback,
1050*3c7ae9deSAndroid Build Coastguard Worker .body_callback = s_on_s3_meta_request_body_callback,
1051*3c7ae9deSAndroid Build Coastguard Worker .finish_callback = s_on_s3_meta_request_finish_callback,
1052*3c7ae9deSAndroid Build Coastguard Worker .progress_callback = s_on_s3_meta_request_progress_callback,
1053*3c7ae9deSAndroid Build Coastguard Worker .shutdown_callback = s_on_s3_meta_request_shutdown_complete_callback,
1054*3c7ae9deSAndroid Build Coastguard Worker .endpoint = jni_endpoint != NULL ? &endpoint : NULL,
1055*3c7ae9deSAndroid Build Coastguard Worker .resume_token = resume_token,
1056*3c7ae9deSAndroid Build Coastguard Worker };
1057*3c7ae9deSAndroid Build Coastguard Worker
1058*3c7ae9deSAndroid Build Coastguard Worker meta_request = aws_s3_client_make_meta_request(client, &meta_request_options);
1059*3c7ae9deSAndroid Build Coastguard Worker /* We are done using the list, it can be safely cleaned up now. */
1060*3c7ae9deSAndroid Build Coastguard Worker aws_array_list_clean_up(&response_checksum_list);
1061*3c7ae9deSAndroid Build Coastguard Worker if (!meta_request) {
1062*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
1063*3c7ae9deSAndroid Build Coastguard Worker env, "S3Client.aws_s3_client_make_meta_request: creating aws_s3_meta_request failed");
1064*3c7ae9deSAndroid Build Coastguard Worker goto done;
1065*3c7ae9deSAndroid Build Coastguard Worker }
1066*3c7ae9deSAndroid Build Coastguard Worker
1067*3c7ae9deSAndroid Build Coastguard Worker success = true;
1068*3c7ae9deSAndroid Build Coastguard Worker
1069*3c7ae9deSAndroid Build Coastguard Worker done:
1070*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_resume_token_release(resume_token);
1071*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, jni_region, region);
1072*3c7ae9deSAndroid Build Coastguard Worker aws_http_message_release(request_message);
1073*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, jni_request_filepath, request_filepath);
1074*3c7ae9deSAndroid Build Coastguard Worker aws_uri_clean_up(&endpoint);
1075*3c7ae9deSAndroid Build Coastguard Worker if (success) {
1076*3c7ae9deSAndroid Build Coastguard Worker return (jlong)meta_request;
1077*3c7ae9deSAndroid Build Coastguard Worker }
1078*3c7ae9deSAndroid Build Coastguard Worker s_s3_meta_request_callback_cleanup(env, callback_data);
1079*3c7ae9deSAndroid Build Coastguard Worker return (jlong)0;
1080*3c7ae9deSAndroid Build Coastguard Worker }
1081*3c7ae9deSAndroid Build Coastguard Worker
s_on_s3_meta_request_shutdown_complete_callback(void * user_data)1082*3c7ae9deSAndroid Build Coastguard Worker static void s_on_s3_meta_request_shutdown_complete_callback(void *user_data) {
1083*3c7ae9deSAndroid Build Coastguard Worker struct s3_client_make_meta_request_callback_data *callback_data =
1084*3c7ae9deSAndroid Build Coastguard Worker (struct s3_client_make_meta_request_callback_data *)user_data;
1085*3c7ae9deSAndroid Build Coastguard Worker
1086*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
1087*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(callback_data->jvm);
1088*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
1089*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
1090*3c7ae9deSAndroid Build Coastguard Worker return;
1091*3c7ae9deSAndroid Build Coastguard Worker }
1092*3c7ae9deSAndroid Build Coastguard Worker
1093*3c7ae9deSAndroid Build Coastguard Worker if (callback_data->java_s3_meta_request != NULL) {
1094*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(env, callback_data->java_s3_meta_request, s3_meta_request_properties.onShutdownComplete);
1095*3c7ae9deSAndroid Build Coastguard Worker
1096*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
1097*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
1098*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_S3_META_REQUEST,
1099*3c7ae9deSAndroid Build Coastguard Worker "id=%p: Ignored Exception from S3MetaRequest.onShutdownCompete callback",
1100*3c7ae9deSAndroid Build Coastguard Worker (void *)callback_data->java_s3_meta_request);
1101*3c7ae9deSAndroid Build Coastguard Worker }
1102*3c7ae9deSAndroid Build Coastguard Worker }
1103*3c7ae9deSAndroid Build Coastguard Worker
1104*3c7ae9deSAndroid Build Coastguard Worker // We're done with this callback data, free it.
1105*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm = callback_data->jvm;
1106*3c7ae9deSAndroid Build Coastguard Worker s_s3_meta_request_callback_cleanup(env, callback_data);
1107*3c7ae9deSAndroid Build Coastguard Worker
1108*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(jvm, env);
1109*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
1110*3c7ae9deSAndroid Build Coastguard Worker }
1111*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestDestroy(JNIEnv * env,jclass jni_class,jlong jni_s3_meta_request)1112*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestDestroy(
1113*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
1114*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
1115*3c7ae9deSAndroid Build Coastguard Worker jlong jni_s3_meta_request) {
1116*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
1117*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
1118*3c7ae9deSAndroid Build Coastguard Worker
1119*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request = (struct aws_s3_meta_request *)jni_s3_meta_request;
1120*3c7ae9deSAndroid Build Coastguard Worker if (!meta_request) {
1121*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
1122*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3MetaRequest.s3MetaRequestDestroy: Invalid/null meta request");
1123*3c7ae9deSAndroid Build Coastguard Worker return;
1124*3c7ae9deSAndroid Build Coastguard Worker }
1125*3c7ae9deSAndroid Build Coastguard Worker
1126*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_release(meta_request);
1127*3c7ae9deSAndroid Build Coastguard Worker }
1128*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestCancel(JNIEnv * env,jclass jni_class,jlong jni_s3_meta_request)1129*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestCancel(
1130*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
1131*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
1132*3c7ae9deSAndroid Build Coastguard Worker jlong jni_s3_meta_request) {
1133*3c7ae9deSAndroid Build Coastguard Worker
1134*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
1135*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
1136*3c7ae9deSAndroid Build Coastguard Worker
1137*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request = (struct aws_s3_meta_request *)jni_s3_meta_request;
1138*3c7ae9deSAndroid Build Coastguard Worker if (!meta_request) {
1139*3c7ae9deSAndroid Build Coastguard Worker /* It's fine if this particular function does nothing when it's called
1140*3c7ae9deSAndroid Build Coastguard Worker * after CrtResource is closed and the handle is NULL */
1141*3c7ae9deSAndroid Build Coastguard Worker return;
1142*3c7ae9deSAndroid Build Coastguard Worker }
1143*3c7ae9deSAndroid Build Coastguard Worker
1144*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_cancel(meta_request);
1145*3c7ae9deSAndroid Build Coastguard Worker }
1146*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestPause(JNIEnv * env,jclass jni_class,jlong jni_s3_meta_request)1147*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jobject JNICALL Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestPause(
1148*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
1149*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
1150*3c7ae9deSAndroid Build Coastguard Worker jlong jni_s3_meta_request) {
1151*3c7ae9deSAndroid Build Coastguard Worker
1152*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
1153*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
1154*3c7ae9deSAndroid Build Coastguard Worker
1155*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request = (struct aws_s3_meta_request *)jni_s3_meta_request;
1156*3c7ae9deSAndroid Build Coastguard Worker if (!meta_request) {
1157*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_INVALID_ARGUMENT);
1158*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(env, "S3MetaRequest.s3MetaRequestPause: Invalid/null meta request");
1159*3c7ae9deSAndroid Build Coastguard Worker return NULL;
1160*3c7ae9deSAndroid Build Coastguard Worker }
1161*3c7ae9deSAndroid Build Coastguard Worker
1162*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request_resume_token *resume_token = NULL;
1163*3c7ae9deSAndroid Build Coastguard Worker
1164*3c7ae9deSAndroid Build Coastguard Worker if (aws_s3_meta_request_pause(meta_request, &resume_token)) {
1165*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3MetaRequest.s3MetaRequestPause: Failed to pause request");
1166*3c7ae9deSAndroid Build Coastguard Worker return NULL;
1167*3c7ae9deSAndroid Build Coastguard Worker }
1168*3c7ae9deSAndroid Build Coastguard Worker
1169*3c7ae9deSAndroid Build Coastguard Worker jobject resume_token_jni = NULL;
1170*3c7ae9deSAndroid Build Coastguard Worker if (resume_token != NULL) {
1171*3c7ae9deSAndroid Build Coastguard Worker resume_token_jni = (*env)->NewObject(
1172*3c7ae9deSAndroid Build Coastguard Worker env,
1173*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_resume_token_properties.s3_meta_request_resume_token_class,
1174*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_resume_token_properties.s3_meta_request_resume_token_constructor_method_id);
1175*3c7ae9deSAndroid Build Coastguard Worker if ((*env)->ExceptionCheck(env) || resume_token_jni == NULL) {
1176*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3MetaRequest.s3MetaRequestPause: Failed to create ResumeToken.");
1177*3c7ae9deSAndroid Build Coastguard Worker goto on_done;
1178*3c7ae9deSAndroid Build Coastguard Worker }
1179*3c7ae9deSAndroid Build Coastguard Worker
1180*3c7ae9deSAndroid Build Coastguard Worker enum aws_s3_meta_request_type type = aws_s3_meta_request_resume_token_type(resume_token);
1181*3c7ae9deSAndroid Build Coastguard Worker if (type != AWS_S3_META_REQUEST_TYPE_PUT_OBJECT) {
1182*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "S3MetaRequest.s3MetaRequestPause: Failed to convert resume token.");
1183*3c7ae9deSAndroid Build Coastguard Worker goto on_done;
1184*3c7ae9deSAndroid Build Coastguard Worker }
1185*3c7ae9deSAndroid Build Coastguard Worker
1186*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetIntField(env, resume_token_jni, s3_meta_request_resume_token_properties.native_type_field_id, type);
1187*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetLongField(
1188*3c7ae9deSAndroid Build Coastguard Worker env,
1189*3c7ae9deSAndroid Build Coastguard Worker resume_token_jni,
1190*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_resume_token_properties.part_size_field_id,
1191*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_resume_token_part_size(resume_token));
1192*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetLongField(
1193*3c7ae9deSAndroid Build Coastguard Worker env,
1194*3c7ae9deSAndroid Build Coastguard Worker resume_token_jni,
1195*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_resume_token_properties.total_num_parts_field_id,
1196*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_resume_token_total_num_parts(resume_token));
1197*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetLongField(
1198*3c7ae9deSAndroid Build Coastguard Worker env,
1199*3c7ae9deSAndroid Build Coastguard Worker resume_token_jni,
1200*3c7ae9deSAndroid Build Coastguard Worker s3_meta_request_resume_token_properties.num_parts_completed_field_id,
1201*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_resume_token_num_parts_completed(resume_token));
1202*3c7ae9deSAndroid Build Coastguard Worker
1203*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor upload_id_cur = aws_s3_meta_request_resume_token_upload_id(resume_token);
1204*3c7ae9deSAndroid Build Coastguard Worker jstring upload_id_jni = aws_jni_string_from_cursor(env, &upload_id_cur);
1205*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetObjectField(
1206*3c7ae9deSAndroid Build Coastguard Worker env, resume_token_jni, s3_meta_request_resume_token_properties.upload_id_field_id, upload_id_jni);
1207*3c7ae9deSAndroid Build Coastguard Worker
1208*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, upload_id_jni);
1209*3c7ae9deSAndroid Build Coastguard Worker }
1210*3c7ae9deSAndroid Build Coastguard Worker
1211*3c7ae9deSAndroid Build Coastguard Worker on_done:
1212*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_resume_token_release(resume_token);
1213*3c7ae9deSAndroid Build Coastguard Worker return resume_token_jni;
1214*3c7ae9deSAndroid Build Coastguard Worker }
1215*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestIncrementReadWindow(JNIEnv * env,jclass jni_class,jlong jni_s3_meta_request,jlong increment)1216*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_s3_S3MetaRequest_s3MetaRequestIncrementReadWindow(
1217*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
1218*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
1219*3c7ae9deSAndroid Build Coastguard Worker jlong jni_s3_meta_request,
1220*3c7ae9deSAndroid Build Coastguard Worker jlong increment) {
1221*3c7ae9deSAndroid Build Coastguard Worker
1222*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
1223*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
1224*3c7ae9deSAndroid Build Coastguard Worker
1225*3c7ae9deSAndroid Build Coastguard Worker struct aws_s3_meta_request *meta_request = (struct aws_s3_meta_request *)jni_s3_meta_request;
1226*3c7ae9deSAndroid Build Coastguard Worker if (!meta_request) {
1227*3c7ae9deSAndroid Build Coastguard Worker /* It's fine if this particular function does nothing when it's called
1228*3c7ae9deSAndroid Build Coastguard Worker * after CrtResource is closed and the handle is NULL */
1229*3c7ae9deSAndroid Build Coastguard Worker return;
1230*3c7ae9deSAndroid Build Coastguard Worker }
1231*3c7ae9deSAndroid Build Coastguard Worker
1232*3c7ae9deSAndroid Build Coastguard Worker if (increment < 0) {
1233*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(
1234*3c7ae9deSAndroid Build Coastguard Worker env, "S3MetaRequest.s3MetaRequestIncrementReadWindow: Number cannot be negative");
1235*3c7ae9deSAndroid Build Coastguard Worker return;
1236*3c7ae9deSAndroid Build Coastguard Worker }
1237*3c7ae9deSAndroid Build Coastguard Worker
1238*3c7ae9deSAndroid Build Coastguard Worker aws_s3_meta_request_increment_read_window(meta_request, (uint64_t)increment);
1239*3c7ae9deSAndroid Build Coastguard Worker }
1240*3c7ae9deSAndroid Build Coastguard Worker
1241*3c7ae9deSAndroid Build Coastguard Worker #if UINTPTR_MAX == 0xffffffff
1242*3c7ae9deSAndroid Build Coastguard Worker # if defined(_MSC_VER)
1243*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(pop)
1244*3c7ae9deSAndroid Build Coastguard Worker # else
1245*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic pop
1246*3c7ae9deSAndroid Build Coastguard Worker # endif
1247*3c7ae9deSAndroid Build Coastguard Worker #endif
1248