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
6*3c7ae9deSAndroid Build Coastguard Worker #include <jni.h>
7*3c7ae9deSAndroid Build Coastguard Worker
8*3c7ae9deSAndroid Build Coastguard Worker #include "crt.h"
9*3c7ae9deSAndroid Build Coastguard Worker #include "http_connection_manager.h"
10*3c7ae9deSAndroid Build Coastguard Worker #include "http_request_response.h"
11*3c7ae9deSAndroid Build Coastguard Worker #include "http_request_utils.h"
12*3c7ae9deSAndroid Build Coastguard Worker #include "java_class_ids.h"
13*3c7ae9deSAndroid Build Coastguard Worker
14*3c7ae9deSAndroid Build Coastguard Worker #include <aws/common/atomics.h>
15*3c7ae9deSAndroid Build Coastguard Worker #include <aws/common/mutex.h>
16*3c7ae9deSAndroid Build Coastguard Worker #include <aws/http/connection.h>
17*3c7ae9deSAndroid Build Coastguard Worker #include <aws/http/http.h>
18*3c7ae9deSAndroid Build Coastguard Worker #include <aws/http/request_response.h>
19*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/logging.h>
20*3c7ae9deSAndroid Build Coastguard Worker #include <aws/io/stream.h>
21*3c7ae9deSAndroid Build Coastguard Worker
22*3c7ae9deSAndroid Build Coastguard Worker #if _MSC_VER
23*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(disable : 4204) /* non-constant aggregate initializer */
24*3c7ae9deSAndroid Build Coastguard Worker #endif
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 # else
32*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic push
33*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wpointer-to-int-cast"
34*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic ignored "-Wint-to-pointer-cast"
35*3c7ae9deSAndroid Build Coastguard Worker # endif
36*3c7ae9deSAndroid Build Coastguard Worker #endif
37*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_from_native_new(JNIEnv * env,void * opaque,int version)38*3c7ae9deSAndroid Build Coastguard Worker jobject aws_java_http_stream_from_native_new(JNIEnv *env, void *opaque, int version) {
39*3c7ae9deSAndroid Build Coastguard Worker jlong jni_native_ptr = (jlong)opaque;
40*3c7ae9deSAndroid Build Coastguard Worker AWS_ASSERT(jni_native_ptr);
41*3c7ae9deSAndroid Build Coastguard Worker jobject stream = NULL;
42*3c7ae9deSAndroid Build Coastguard Worker switch (version) {
43*3c7ae9deSAndroid Build Coastguard Worker case AWS_HTTP_VERSION_2:
44*3c7ae9deSAndroid Build Coastguard Worker stream = (*env)->NewObject(
45*3c7ae9deSAndroid Build Coastguard Worker env, http2_stream_properties.stream_class, http2_stream_properties.constructor, jni_native_ptr);
46*3c7ae9deSAndroid Build Coastguard Worker break;
47*3c7ae9deSAndroid Build Coastguard Worker case AWS_HTTP_VERSION_1_0:
48*3c7ae9deSAndroid Build Coastguard Worker case AWS_HTTP_VERSION_1_1:
49*3c7ae9deSAndroid Build Coastguard Worker stream = (*env)->NewObject(
50*3c7ae9deSAndroid Build Coastguard Worker env, http_stream_properties.stream_class, http_stream_properties.constructor, jni_native_ptr);
51*3c7ae9deSAndroid Build Coastguard Worker break;
52*3c7ae9deSAndroid Build Coastguard Worker default:
53*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Unsupported HTTP protocol.");
54*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_UNIMPLEMENTED);
55*3c7ae9deSAndroid Build Coastguard Worker }
56*3c7ae9deSAndroid Build Coastguard Worker return stream;
57*3c7ae9deSAndroid Build Coastguard Worker }
58*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_from_native_delete(JNIEnv * env,jobject jHttpStream)59*3c7ae9deSAndroid Build Coastguard Worker void aws_java_http_stream_from_native_delete(JNIEnv *env, jobject jHttpStream) {
60*3c7ae9deSAndroid Build Coastguard Worker /* Delete our reference to the HttpStream Object from the JVM. */
61*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, jHttpStream);
62*3c7ae9deSAndroid Build Coastguard Worker }
63*3c7ae9deSAndroid Build Coastguard Worker
64*3c7ae9deSAndroid Build Coastguard Worker /*******************************************************************************
65*3c7ae9deSAndroid Build Coastguard Worker * http_stream_binding - Jni native represent of the Java HTTP stream object
66*3c7ae9deSAndroid Build Coastguard Worker ******************************************************************************/
67*3c7ae9deSAndroid Build Coastguard Worker
s_http_stream_binding_destroy(JNIEnv * env,struct http_stream_binding * binding)68*3c7ae9deSAndroid Build Coastguard Worker static void s_http_stream_binding_destroy(JNIEnv *env, struct http_stream_binding *binding) {
69*3c7ae9deSAndroid Build Coastguard Worker
70*3c7ae9deSAndroid Build Coastguard Worker if (binding->java_http_stream_base) {
71*3c7ae9deSAndroid Build Coastguard Worker aws_java_http_stream_from_native_delete(env, binding->java_http_stream_base);
72*3c7ae9deSAndroid Build Coastguard Worker }
73*3c7ae9deSAndroid Build Coastguard Worker
74*3c7ae9deSAndroid Build Coastguard Worker if (binding->java_http_response_stream_handler != NULL) {
75*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, binding->java_http_response_stream_handler);
76*3c7ae9deSAndroid Build Coastguard Worker }
77*3c7ae9deSAndroid Build Coastguard Worker
78*3c7ae9deSAndroid Build Coastguard Worker if (binding->native_request) {
79*3c7ae9deSAndroid Build Coastguard Worker aws_http_message_release(binding->native_request);
80*3c7ae9deSAndroid Build Coastguard Worker }
81*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(&binding->headers_buf);
82*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), binding);
83*3c7ae9deSAndroid Build Coastguard Worker }
84*3c7ae9deSAndroid Build Coastguard Worker
aws_http_stream_binding_acquire(struct http_stream_binding * binding)85*3c7ae9deSAndroid Build Coastguard Worker void *aws_http_stream_binding_acquire(struct http_stream_binding *binding) {
86*3c7ae9deSAndroid Build Coastguard Worker if (binding == NULL) {
87*3c7ae9deSAndroid Build Coastguard Worker return NULL;
88*3c7ae9deSAndroid Build Coastguard Worker }
89*3c7ae9deSAndroid Build Coastguard Worker aws_atomic_fetch_add(&binding->ref, 1);
90*3c7ae9deSAndroid Build Coastguard Worker return binding;
91*3c7ae9deSAndroid Build Coastguard Worker }
92*3c7ae9deSAndroid Build Coastguard Worker
aws_http_stream_binding_release(JNIEnv * env,struct http_stream_binding * binding)93*3c7ae9deSAndroid Build Coastguard Worker void *aws_http_stream_binding_release(JNIEnv *env, struct http_stream_binding *binding) {
94*3c7ae9deSAndroid Build Coastguard Worker if (binding == NULL) {
95*3c7ae9deSAndroid Build Coastguard Worker return NULL;
96*3c7ae9deSAndroid Build Coastguard Worker }
97*3c7ae9deSAndroid Build Coastguard Worker size_t pre_ref = aws_atomic_fetch_sub(&binding->ref, 1);
98*3c7ae9deSAndroid Build Coastguard Worker AWS_ASSERT(pre_ref > 0 && "stream binding refcount has gone negative");
99*3c7ae9deSAndroid Build Coastguard Worker if (pre_ref == 1) {
100*3c7ae9deSAndroid Build Coastguard Worker s_http_stream_binding_destroy(env, binding);
101*3c7ae9deSAndroid Build Coastguard Worker }
102*3c7ae9deSAndroid Build Coastguard Worker return NULL;
103*3c7ae9deSAndroid Build Coastguard Worker }
104*3c7ae9deSAndroid Build Coastguard Worker
105*3c7ae9deSAndroid Build Coastguard Worker // If error occurs, A Java exception is thrown and NULL is returned.
aws_http_stream_binding_new(JNIEnv * env,jobject java_callback_handler)106*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *aws_http_stream_binding_new(JNIEnv *env, jobject java_callback_handler) {
107*3c7ae9deSAndroid Build Coastguard Worker
108*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
109*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = aws_mem_calloc(allocator, 1, sizeof(struct http_stream_binding));
110*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(binding);
111*3c7ae9deSAndroid Build Coastguard Worker
112*3c7ae9deSAndroid Build Coastguard Worker // GetJavaVM() reference doesn't need a NewGlobalRef() call since it's global by default
113*3c7ae9deSAndroid Build Coastguard Worker jint jvmresult = (*env)->GetJavaVM(env, &binding->jvm);
114*3c7ae9deSAndroid Build Coastguard Worker (void)jvmresult;
115*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(jvmresult == 0);
116*3c7ae9deSAndroid Build Coastguard Worker
117*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_response_stream_handler = (*env)->NewGlobalRef(env, java_callback_handler);
118*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(binding->java_http_response_stream_handler);
119*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(!aws_byte_buf_init(&binding->headers_buf, allocator, 1024));
120*3c7ae9deSAndroid Build Coastguard Worker
121*3c7ae9deSAndroid Build Coastguard Worker aws_atomic_init_int(&binding->ref, 1);
122*3c7ae9deSAndroid Build Coastguard Worker
123*3c7ae9deSAndroid Build Coastguard Worker return binding;
124*3c7ae9deSAndroid Build Coastguard Worker }
125*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_on_incoming_headers_fn(struct aws_http_stream * stream,enum aws_http_header_block block_type,const struct aws_http_header * header_array,size_t num_headers,void * user_data)126*3c7ae9deSAndroid Build Coastguard Worker int aws_java_http_stream_on_incoming_headers_fn(
127*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream,
128*3c7ae9deSAndroid Build Coastguard Worker enum aws_http_header_block block_type,
129*3c7ae9deSAndroid Build Coastguard Worker const struct aws_http_header *header_array,
130*3c7ae9deSAndroid Build Coastguard Worker size_t num_headers,
131*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
132*3c7ae9deSAndroid Build Coastguard Worker (void)block_type;
133*3c7ae9deSAndroid Build Coastguard Worker
134*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)user_data;
135*3c7ae9deSAndroid Build Coastguard Worker int resp_status = -1;
136*3c7ae9deSAndroid Build Coastguard Worker int err_code = aws_http_stream_get_incoming_response_status(stream, &resp_status);
137*3c7ae9deSAndroid Build Coastguard Worker if (err_code != AWS_OP_SUCCESS) {
138*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=%p: Invalid Incoming Response Status", (void *)stream);
139*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
140*3c7ae9deSAndroid Build Coastguard Worker }
141*3c7ae9deSAndroid Build Coastguard Worker
142*3c7ae9deSAndroid Build Coastguard Worker binding->response_status = resp_status;
143*3c7ae9deSAndroid Build Coastguard Worker
144*3c7ae9deSAndroid Build Coastguard Worker if (aws_marshal_http_headers_array_to_dynamic_buffer(&binding->headers_buf, header_array, num_headers)) {
145*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(
146*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_HTTP_STREAM, "id=%p: Failed to allocate buffer space for incoming headers", (void *)stream);
147*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
148*3c7ae9deSAndroid Build Coastguard Worker }
149*3c7ae9deSAndroid Build Coastguard Worker
150*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_SUCCESS;
151*3c7ae9deSAndroid Build Coastguard Worker }
152*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_on_incoming_header_block_done_fn(struct aws_http_stream * stream,enum aws_http_header_block block_type,void * user_data)153*3c7ae9deSAndroid Build Coastguard Worker int aws_java_http_stream_on_incoming_header_block_done_fn(
154*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream,
155*3c7ae9deSAndroid Build Coastguard Worker enum aws_http_header_block block_type,
156*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
157*3c7ae9deSAndroid Build Coastguard Worker (void)stream;
158*3c7ae9deSAndroid Build Coastguard Worker
159*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)user_data;
160*3c7ae9deSAndroid Build Coastguard Worker
161*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
162*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm);
163*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
164*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
165*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
166*3c7ae9deSAndroid Build Coastguard Worker }
167*3c7ae9deSAndroid Build Coastguard Worker
168*3c7ae9deSAndroid Build Coastguard Worker int result = AWS_OP_ERR;
169*3c7ae9deSAndroid Build Coastguard Worker jint jni_block_type = block_type;
170*3c7ae9deSAndroid Build Coastguard Worker
171*3c7ae9deSAndroid Build Coastguard Worker jobject jni_headers_buf =
172*3c7ae9deSAndroid Build Coastguard Worker aws_jni_direct_byte_buffer_from_raw_ptr(env, binding->headers_buf.buffer, binding->headers_buf.len);
173*3c7ae9deSAndroid Build Coastguard Worker
174*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
175*3c7ae9deSAndroid Build Coastguard Worker env,
176*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_response_stream_handler,
177*3c7ae9deSAndroid Build Coastguard Worker http_stream_response_handler_properties.onResponseHeaders,
178*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_stream_base,
179*3c7ae9deSAndroid Build Coastguard Worker (jint)binding->response_status,
180*3c7ae9deSAndroid Build Coastguard Worker (jint)block_type,
181*3c7ae9deSAndroid Build Coastguard Worker jni_headers_buf);
182*3c7ae9deSAndroid Build Coastguard Worker
183*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
184*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_headers_buf);
185*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
186*3c7ae9deSAndroid Build Coastguard Worker goto done;
187*3c7ae9deSAndroid Build Coastguard Worker }
188*3c7ae9deSAndroid Build Coastguard Worker
189*3c7ae9deSAndroid Build Coastguard Worker /* instead of cleaning it up here, reset it in case another block is encountered */
190*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_reset(&binding->headers_buf, false);
191*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_headers_buf);
192*3c7ae9deSAndroid Build Coastguard Worker
193*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
194*3c7ae9deSAndroid Build Coastguard Worker env,
195*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_response_stream_handler,
196*3c7ae9deSAndroid Build Coastguard Worker http_stream_response_handler_properties.onResponseHeadersDone,
197*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_stream_base,
198*3c7ae9deSAndroid Build Coastguard Worker jni_block_type);
199*3c7ae9deSAndroid Build Coastguard Worker
200*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
201*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
202*3c7ae9deSAndroid Build Coastguard Worker goto done;
203*3c7ae9deSAndroid Build Coastguard Worker }
204*3c7ae9deSAndroid Build Coastguard Worker
205*3c7ae9deSAndroid Build Coastguard Worker result = AWS_OP_SUCCESS;
206*3c7ae9deSAndroid Build Coastguard Worker
207*3c7ae9deSAndroid Build Coastguard Worker done:
208*3c7ae9deSAndroid Build Coastguard Worker
209*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(binding->jvm, env);
210*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
211*3c7ae9deSAndroid Build Coastguard Worker
212*3c7ae9deSAndroid Build Coastguard Worker return result;
213*3c7ae9deSAndroid Build Coastguard Worker }
214*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_on_incoming_body_fn(struct aws_http_stream * stream,const struct aws_byte_cursor * data,void * user_data)215*3c7ae9deSAndroid Build Coastguard Worker int aws_java_http_stream_on_incoming_body_fn(
216*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream,
217*3c7ae9deSAndroid Build Coastguard Worker const struct aws_byte_cursor *data,
218*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
219*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)user_data;
220*3c7ae9deSAndroid Build Coastguard Worker
221*3c7ae9deSAndroid Build Coastguard Worker size_t total_window_increment = 0;
222*3c7ae9deSAndroid Build Coastguard Worker
223*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
224*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm);
225*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
226*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
227*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
228*3c7ae9deSAndroid Build Coastguard Worker }
229*3c7ae9deSAndroid Build Coastguard Worker
230*3c7ae9deSAndroid Build Coastguard Worker int result = AWS_OP_ERR;
231*3c7ae9deSAndroid Build Coastguard Worker
232*3c7ae9deSAndroid Build Coastguard Worker jobject jni_payload = aws_jni_direct_byte_buffer_from_raw_ptr(env, data->ptr, data->len);
233*3c7ae9deSAndroid Build Coastguard Worker
234*3c7ae9deSAndroid Build Coastguard Worker jint window_increment = (*env)->CallIntMethod(
235*3c7ae9deSAndroid Build Coastguard Worker env,
236*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_response_stream_handler,
237*3c7ae9deSAndroid Build Coastguard Worker http_stream_response_handler_properties.onResponseBody,
238*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_stream_base,
239*3c7ae9deSAndroid Build Coastguard Worker jni_payload);
240*3c7ae9deSAndroid Build Coastguard Worker
241*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_payload);
242*3c7ae9deSAndroid Build Coastguard Worker
243*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
244*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=%p: Received Exception from onResponseBody", (void *)stream);
245*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
246*3c7ae9deSAndroid Build Coastguard Worker goto done;
247*3c7ae9deSAndroid Build Coastguard Worker }
248*3c7ae9deSAndroid Build Coastguard Worker
249*3c7ae9deSAndroid Build Coastguard Worker if (window_increment < 0) {
250*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=%p: Window Increment from onResponseBody < 0", (void *)stream);
251*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
252*3c7ae9deSAndroid Build Coastguard Worker goto done;
253*3c7ae9deSAndroid Build Coastguard Worker }
254*3c7ae9deSAndroid Build Coastguard Worker
255*3c7ae9deSAndroid Build Coastguard Worker total_window_increment += window_increment;
256*3c7ae9deSAndroid Build Coastguard Worker
257*3c7ae9deSAndroid Build Coastguard Worker if (total_window_increment > 0) {
258*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_update_window(stream, total_window_increment);
259*3c7ae9deSAndroid Build Coastguard Worker }
260*3c7ae9deSAndroid Build Coastguard Worker
261*3c7ae9deSAndroid Build Coastguard Worker result = AWS_OP_SUCCESS;
262*3c7ae9deSAndroid Build Coastguard Worker
263*3c7ae9deSAndroid Build Coastguard Worker done:
264*3c7ae9deSAndroid Build Coastguard Worker
265*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(binding->jvm, env);
266*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
267*3c7ae9deSAndroid Build Coastguard Worker
268*3c7ae9deSAndroid Build Coastguard Worker return result;
269*3c7ae9deSAndroid Build Coastguard Worker }
270*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_on_stream_complete_fn(struct aws_http_stream * stream,int error_code,void * user_data)271*3c7ae9deSAndroid Build Coastguard Worker void aws_java_http_stream_on_stream_complete_fn(struct aws_http_stream *stream, int error_code, void *user_data) {
272*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)user_data;
273*3c7ae9deSAndroid Build Coastguard Worker
274*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
275*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm);
276*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
277*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
278*3c7ae9deSAndroid Build Coastguard Worker return;
279*3c7ae9deSAndroid Build Coastguard Worker }
280*3c7ae9deSAndroid Build Coastguard Worker
281*3c7ae9deSAndroid Build Coastguard Worker /* Don't invoke Java callbacks if Java HttpStream failed to completely setup */
282*3c7ae9deSAndroid Build Coastguard Worker jint jErrorCode = error_code;
283*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
284*3c7ae9deSAndroid Build Coastguard Worker env,
285*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_response_stream_handler,
286*3c7ae9deSAndroid Build Coastguard Worker http_stream_response_handler_properties.onResponseComplete,
287*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_stream_base,
288*3c7ae9deSAndroid Build Coastguard Worker jErrorCode);
289*3c7ae9deSAndroid Build Coastguard Worker
290*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
291*3c7ae9deSAndroid Build Coastguard Worker /* Close the Connection if the Java Callback throws an Exception */
292*3c7ae9deSAndroid Build Coastguard Worker aws_http_connection_close(aws_http_stream_get_connection(stream));
293*3c7ae9deSAndroid Build Coastguard Worker }
294*3c7ae9deSAndroid Build Coastguard Worker
295*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(binding->jvm, env);
296*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
297*3c7ae9deSAndroid Build Coastguard Worker }
298*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_on_stream_destroy_fn(void * user_data)299*3c7ae9deSAndroid Build Coastguard Worker void aws_java_http_stream_on_stream_destroy_fn(void *user_data) {
300*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)user_data;
301*3c7ae9deSAndroid Build Coastguard Worker
302*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
303*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm);
304*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
305*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
306*3c7ae9deSAndroid Build Coastguard Worker return;
307*3c7ae9deSAndroid Build Coastguard Worker }
308*3c7ae9deSAndroid Build Coastguard Worker /* Native stream destroyed, release the binding. */
309*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_binding_release(env, binding);
310*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(binding->jvm, env);
311*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
312*3c7ae9deSAndroid Build Coastguard Worker }
313*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_stream_on_stream_metrics_fn(struct aws_http_stream * stream,const struct aws_http_stream_metrics * metrics,void * user_data)314*3c7ae9deSAndroid Build Coastguard Worker void aws_java_http_stream_on_stream_metrics_fn(
315*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream,
316*3c7ae9deSAndroid Build Coastguard Worker const struct aws_http_stream_metrics *metrics,
317*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
318*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)user_data;
319*3c7ae9deSAndroid Build Coastguard Worker
320*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
321*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(binding->jvm);
322*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
323*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
324*3c7ae9deSAndroid Build Coastguard Worker return;
325*3c7ae9deSAndroid Build Coastguard Worker }
326*3c7ae9deSAndroid Build Coastguard Worker
327*3c7ae9deSAndroid Build Coastguard Worker /* Convert metrics to Java HttpStreamMetrics obj */
328*3c7ae9deSAndroid Build Coastguard Worker jobject jni_metrics = (*env)->NewObject(
329*3c7ae9deSAndroid Build Coastguard Worker env,
330*3c7ae9deSAndroid Build Coastguard Worker http_stream_metrics_properties.http_stream_metrics_class,
331*3c7ae9deSAndroid Build Coastguard Worker http_stream_metrics_properties.constructor_id,
332*3c7ae9deSAndroid Build Coastguard Worker (jlong)metrics->send_start_timestamp_ns,
333*3c7ae9deSAndroid Build Coastguard Worker (jlong)metrics->send_end_timestamp_ns,
334*3c7ae9deSAndroid Build Coastguard Worker (jlong)metrics->sending_duration_ns,
335*3c7ae9deSAndroid Build Coastguard Worker (jlong)metrics->receive_start_timestamp_ns,
336*3c7ae9deSAndroid Build Coastguard Worker (jlong)metrics->receive_end_timestamp_ns,
337*3c7ae9deSAndroid Build Coastguard Worker (jlong)metrics->receiving_duration_ns,
338*3c7ae9deSAndroid Build Coastguard Worker
339*3c7ae9deSAndroid Build Coastguard Worker /* Stream IDs are 31-bit unsigned integers, which fits into Java's regular (signed) 32-bit int */
340*3c7ae9deSAndroid Build Coastguard Worker (jint)metrics->stream_id);
341*3c7ae9deSAndroid Build Coastguard Worker
342*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
343*3c7ae9deSAndroid Build Coastguard Worker env,
344*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_response_stream_handler,
345*3c7ae9deSAndroid Build Coastguard Worker http_stream_response_handler_properties.onMetrics,
346*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_stream_base,
347*3c7ae9deSAndroid Build Coastguard Worker jni_metrics);
348*3c7ae9deSAndroid Build Coastguard Worker
349*3c7ae9deSAndroid Build Coastguard Worker /* Delete local reference to metrics object */
350*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, jni_metrics);
351*3c7ae9deSAndroid Build Coastguard Worker
352*3c7ae9deSAndroid Build Coastguard Worker if (aws_jni_check_and_clear_exception(env)) {
353*3c7ae9deSAndroid Build Coastguard Worker /* Close the Connection if the Java Callback throws an Exception */
354*3c7ae9deSAndroid Build Coastguard Worker aws_http_connection_close(aws_http_stream_get_connection(stream));
355*3c7ae9deSAndroid Build Coastguard Worker
356*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(AWS_LS_HTTP_STREAM, "id=%p: Received Exception from onMetrics", (void *)stream);
357*3c7ae9deSAndroid Build Coastguard Worker aws_raise_error(AWS_ERROR_HTTP_CALLBACK_FAILURE);
358*3c7ae9deSAndroid Build Coastguard Worker }
359*3c7ae9deSAndroid Build Coastguard Worker
360*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(binding->jvm, env);
361*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
362*3c7ae9deSAndroid Build Coastguard Worker }
363*3c7ae9deSAndroid Build Coastguard Worker
aws_java_http_headers_from_native(JNIEnv * env,struct aws_http_headers * headers)364*3c7ae9deSAndroid Build Coastguard Worker jobjectArray aws_java_http_headers_from_native(JNIEnv *env, struct aws_http_headers *headers) {
365*3c7ae9deSAndroid Build Coastguard Worker (void)headers;
366*3c7ae9deSAndroid Build Coastguard Worker jobjectArray ret;
367*3c7ae9deSAndroid Build Coastguard Worker const size_t header_count = aws_http_headers_count(headers);
368*3c7ae9deSAndroid Build Coastguard Worker
369*3c7ae9deSAndroid Build Coastguard Worker ret = (jobjectArray)(*env)->NewObjectArray(
370*3c7ae9deSAndroid Build Coastguard Worker env, (jsize)header_count, http_header_properties.http_header_class, (void *)NULL);
371*3c7ae9deSAndroid Build Coastguard Worker
372*3c7ae9deSAndroid Build Coastguard Worker for (size_t index = 0; index < header_count; index += 1) {
373*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_header header;
374*3c7ae9deSAndroid Build Coastguard Worker aws_http_headers_get_index(headers, index, &header);
375*3c7ae9deSAndroid Build Coastguard Worker jbyteArray header_name = aws_jni_byte_array_from_cursor(env, &header.name);
376*3c7ae9deSAndroid Build Coastguard Worker jbyteArray header_value = aws_jni_byte_array_from_cursor(env, &header.value);
377*3c7ae9deSAndroid Build Coastguard Worker
378*3c7ae9deSAndroid Build Coastguard Worker jobject java_http_header = (*env)->NewObject(
379*3c7ae9deSAndroid Build Coastguard Worker env,
380*3c7ae9deSAndroid Build Coastguard Worker http_header_properties.http_header_class,
381*3c7ae9deSAndroid Build Coastguard Worker http_header_properties.constructor_method_id,
382*3c7ae9deSAndroid Build Coastguard Worker header_name,
383*3c7ae9deSAndroid Build Coastguard Worker header_value);
384*3c7ae9deSAndroid Build Coastguard Worker
385*3c7ae9deSAndroid Build Coastguard Worker (*env)->SetObjectArrayElement(env, ret, (jsize)index, java_http_header);
386*3c7ae9deSAndroid Build Coastguard Worker }
387*3c7ae9deSAndroid Build Coastguard Worker
388*3c7ae9deSAndroid Build Coastguard Worker return (ret);
389*3c7ae9deSAndroid Build Coastguard Worker }
390*3c7ae9deSAndroid Build Coastguard Worker
s_make_request_general(JNIEnv * env,jlong jni_connection,jbyteArray marshalled_request,jobject jni_http_request_body_stream,jobject jni_http_response_callback_handler,enum aws_http_version version)391*3c7ae9deSAndroid Build Coastguard Worker static jobject s_make_request_general(
392*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
393*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection,
394*3c7ae9deSAndroid Build Coastguard Worker jbyteArray marshalled_request,
395*3c7ae9deSAndroid Build Coastguard Worker jobject jni_http_request_body_stream,
396*3c7ae9deSAndroid Build Coastguard Worker jobject jni_http_response_callback_handler,
397*3c7ae9deSAndroid Build Coastguard Worker enum aws_http_version version) {
398*3c7ae9deSAndroid Build Coastguard Worker
399*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
400*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
401*3c7ae9deSAndroid Build Coastguard Worker
402*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
403*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_null_pointer_exception(env, "HttpClientConnection.MakeRequest: Invalid aws_http_connection");
404*3c7ae9deSAndroid Build Coastguard Worker return (jobject)NULL;
405*3c7ae9deSAndroid Build Coastguard Worker }
406*3c7ae9deSAndroid Build Coastguard Worker
407*3c7ae9deSAndroid Build Coastguard Worker if (!jni_http_response_callback_handler) {
408*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(
409*3c7ae9deSAndroid Build Coastguard Worker env, "HttpClientConnection.MakeRequest: Invalid jni_http_response_callback_handler");
410*3c7ae9deSAndroid Build Coastguard Worker return (jobject)NULL;
411*3c7ae9deSAndroid Build Coastguard Worker }
412*3c7ae9deSAndroid Build Coastguard Worker
413*3c7ae9deSAndroid Build Coastguard Worker /* initial refcount created for the Java object */
414*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *stream_binding = aws_http_stream_binding_new(env, jni_http_response_callback_handler);
415*3c7ae9deSAndroid Build Coastguard Worker if (!stream_binding) {
416*3c7ae9deSAndroid Build Coastguard Worker /* Exception already thrown */
417*3c7ae9deSAndroid Build Coastguard Worker return (jobject)NULL;
418*3c7ae9deSAndroid Build Coastguard Worker }
419*3c7ae9deSAndroid Build Coastguard Worker
420*3c7ae9deSAndroid Build Coastguard Worker stream_binding->native_request =
421*3c7ae9deSAndroid Build Coastguard Worker aws_http_request_new_from_java_http_request(env, marshalled_request, jni_http_request_body_stream);
422*3c7ae9deSAndroid Build Coastguard Worker if (stream_binding->native_request == NULL) {
423*3c7ae9deSAndroid Build Coastguard Worker /* Exception already thrown */
424*3c7ae9deSAndroid Build Coastguard Worker goto error;
425*3c7ae9deSAndroid Build Coastguard Worker }
426*3c7ae9deSAndroid Build Coastguard Worker
427*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_make_request_options request_options = {
428*3c7ae9deSAndroid Build Coastguard Worker .self_size = sizeof(request_options),
429*3c7ae9deSAndroid Build Coastguard Worker .request = stream_binding->native_request,
430*3c7ae9deSAndroid Build Coastguard Worker /* Set Callbacks */
431*3c7ae9deSAndroid Build Coastguard Worker .on_response_headers = aws_java_http_stream_on_incoming_headers_fn,
432*3c7ae9deSAndroid Build Coastguard Worker .on_response_header_block_done = aws_java_http_stream_on_incoming_header_block_done_fn,
433*3c7ae9deSAndroid Build Coastguard Worker .on_response_body = aws_java_http_stream_on_incoming_body_fn,
434*3c7ae9deSAndroid Build Coastguard Worker .on_complete = aws_java_http_stream_on_stream_complete_fn,
435*3c7ae9deSAndroid Build Coastguard Worker .on_destroy = aws_java_http_stream_on_stream_destroy_fn,
436*3c7ae9deSAndroid Build Coastguard Worker .on_metrics = aws_java_http_stream_on_stream_metrics_fn,
437*3c7ae9deSAndroid Build Coastguard Worker .user_data = stream_binding,
438*3c7ae9deSAndroid Build Coastguard Worker };
439*3c7ae9deSAndroid Build Coastguard Worker
440*3c7ae9deSAndroid Build Coastguard Worker stream_binding->native_stream = aws_http_connection_make_request(native_conn, &request_options);
441*3c7ae9deSAndroid Build Coastguard Worker if (stream_binding->native_stream == NULL) {
442*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_ERROR(AWS_LS_HTTP_CONNECTION, "Stream Request Failed. conn: %p", (void *)native_conn);
443*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpClientConnection.MakeRequest: Unable to Execute Request");
444*3c7ae9deSAndroid Build Coastguard Worker goto error;
445*3c7ae9deSAndroid Build Coastguard Worker }
446*3c7ae9deSAndroid Build Coastguard Worker
447*3c7ae9deSAndroid Build Coastguard Worker /* Stream created successfully, acquire on binding for the native stream lifetime. */
448*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_binding_acquire(stream_binding);
449*3c7ae9deSAndroid Build Coastguard Worker
450*3c7ae9deSAndroid Build Coastguard Worker jobject jHttpStreamBase = aws_java_http_stream_from_native_new(env, stream_binding, version);
451*3c7ae9deSAndroid Build Coastguard Worker if (jHttpStreamBase == NULL) {
452*3c7ae9deSAndroid Build Coastguard Worker goto error;
453*3c7ae9deSAndroid Build Coastguard Worker }
454*3c7ae9deSAndroid Build Coastguard Worker
455*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_TRACE(
456*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_HTTP_CONNECTION,
457*3c7ae9deSAndroid Build Coastguard Worker "Opened new Stream on Connection. conn: %p, stream: %p",
458*3c7ae9deSAndroid Build Coastguard Worker (void *)native_conn,
459*3c7ae9deSAndroid Build Coastguard Worker (void *)stream_binding->native_stream);
460*3c7ae9deSAndroid Build Coastguard Worker
461*3c7ae9deSAndroid Build Coastguard Worker return jHttpStreamBase;
462*3c7ae9deSAndroid Build Coastguard Worker
463*3c7ae9deSAndroid Build Coastguard Worker error:
464*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_release(stream_binding->native_stream);
465*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_binding_release(env, stream_binding);
466*3c7ae9deSAndroid Build Coastguard Worker return NULL;
467*3c7ae9deSAndroid Build Coastguard Worker }
468*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionMakeRequest(JNIEnv * env,jclass jni_class,jlong jni_connection,jbyteArray marshalled_request,jobject jni_http_request_body_stream,jobject jni_http_response_callback_handler)469*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jobject JNICALL Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionMakeRequest(
470*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
471*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
472*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection,
473*3c7ae9deSAndroid Build Coastguard Worker jbyteArray marshalled_request,
474*3c7ae9deSAndroid Build Coastguard Worker jobject jni_http_request_body_stream,
475*3c7ae9deSAndroid Build Coastguard Worker jobject jni_http_response_callback_handler) {
476*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
477*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
478*3c7ae9deSAndroid Build Coastguard Worker
479*3c7ae9deSAndroid Build Coastguard Worker return s_make_request_general(
480*3c7ae9deSAndroid Build Coastguard Worker env,
481*3c7ae9deSAndroid Build Coastguard Worker jni_connection,
482*3c7ae9deSAndroid Build Coastguard Worker marshalled_request,
483*3c7ae9deSAndroid Build Coastguard Worker jni_http_request_body_stream,
484*3c7ae9deSAndroid Build Coastguard Worker jni_http_response_callback_handler,
485*3c7ae9deSAndroid Build Coastguard Worker AWS_HTTP_VERSION_1_1);
486*3c7ae9deSAndroid Build Coastguard Worker }
487*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionMakeRequest(JNIEnv * env,jclass jni_class,jlong jni_connection,jbyteArray marshalled_request,jobject jni_http_request_body_stream,jobject jni_http_response_callback_handler)488*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jobject JNICALL Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionMakeRequest(
489*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
490*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
491*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection,
492*3c7ae9deSAndroid Build Coastguard Worker jbyteArray marshalled_request,
493*3c7ae9deSAndroid Build Coastguard Worker jobject jni_http_request_body_stream,
494*3c7ae9deSAndroid Build Coastguard Worker jobject jni_http_response_callback_handler) {
495*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
496*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
497*3c7ae9deSAndroid Build Coastguard Worker
498*3c7ae9deSAndroid Build Coastguard Worker return s_make_request_general(
499*3c7ae9deSAndroid Build Coastguard Worker env,
500*3c7ae9deSAndroid Build Coastguard Worker jni_connection,
501*3c7ae9deSAndroid Build Coastguard Worker marshalled_request,
502*3c7ae9deSAndroid Build Coastguard Worker jni_http_request_body_stream,
503*3c7ae9deSAndroid Build Coastguard Worker jni_http_response_callback_handler,
504*3c7ae9deSAndroid Build Coastguard Worker AWS_HTTP_VERSION_2);
505*3c7ae9deSAndroid Build Coastguard Worker }
506*3c7ae9deSAndroid Build Coastguard Worker
507*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_chunked_callback_data {
508*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *stream_cb_data;
509*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_buf chunk_data;
510*3c7ae9deSAndroid Build Coastguard Worker struct aws_input_stream *chunk_stream;
511*3c7ae9deSAndroid Build Coastguard Worker jobject completion_callback;
512*3c7ae9deSAndroid Build Coastguard Worker };
513*3c7ae9deSAndroid Build Coastguard Worker
s_cleanup_chunked_callback_data(JNIEnv * env,struct http_stream_chunked_callback_data * chunked_callback_data)514*3c7ae9deSAndroid Build Coastguard Worker static void s_cleanup_chunked_callback_data(
515*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
516*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_chunked_callback_data *chunked_callback_data) {
517*3c7ae9deSAndroid Build Coastguard Worker aws_input_stream_destroy(chunked_callback_data->chunk_stream);
518*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_clean_up(&chunked_callback_data->chunk_data);
519*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, chunked_callback_data->completion_callback);
520*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), chunked_callback_data);
521*3c7ae9deSAndroid Build Coastguard Worker }
522*3c7ae9deSAndroid Build Coastguard Worker
s_write_chunk_complete(struct aws_http_stream * stream,int error_code,void * user_data)523*3c7ae9deSAndroid Build Coastguard Worker static void s_write_chunk_complete(struct aws_http_stream *stream, int error_code, void *user_data) {
524*3c7ae9deSAndroid Build Coastguard Worker (void)stream;
525*3c7ae9deSAndroid Build Coastguard Worker
526*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_chunked_callback_data *chunked_callback_data = user_data;
527*3c7ae9deSAndroid Build Coastguard Worker
528*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
529*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(chunked_callback_data->stream_cb_data->jvm);
530*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
531*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
532*3c7ae9deSAndroid Build Coastguard Worker return;
533*3c7ae9deSAndroid Build Coastguard Worker }
534*3c7ae9deSAndroid Build Coastguard Worker
535*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
536*3c7ae9deSAndroid Build Coastguard Worker env,
537*3c7ae9deSAndroid Build Coastguard Worker chunked_callback_data->completion_callback,
538*3c7ae9deSAndroid Build Coastguard Worker http_stream_write_chunk_completion_properties.callback,
539*3c7ae9deSAndroid Build Coastguard Worker error_code);
540*3c7ae9deSAndroid Build Coastguard Worker aws_jni_check_and_clear_exception(env);
541*3c7ae9deSAndroid Build Coastguard Worker
542*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm = chunked_callback_data->stream_cb_data->jvm;
543*3c7ae9deSAndroid Build Coastguard Worker s_cleanup_chunked_callback_data(env, chunked_callback_data);
544*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(jvm, env);
545*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
546*3c7ae9deSAndroid Build Coastguard Worker }
547*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpStream_httpStreamWriteChunk(JNIEnv * env,jclass jni_class,jlong jni_cb_data,jbyteArray chunk_data,jboolean is_final_chunk,jobject completion_callback)548*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jint JNICALL Java_software_amazon_awssdk_crt_http_HttpStream_httpStreamWriteChunk(
549*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
550*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
551*3c7ae9deSAndroid Build Coastguard Worker jlong jni_cb_data,
552*3c7ae9deSAndroid Build Coastguard Worker jbyteArray chunk_data,
553*3c7ae9deSAndroid Build Coastguard Worker jboolean is_final_chunk,
554*3c7ae9deSAndroid Build Coastguard Worker jobject completion_callback) {
555*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
556*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
557*3c7ae9deSAndroid Build Coastguard Worker
558*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *cb_data = (struct http_stream_binding *)jni_cb_data;
559*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream = cb_data->native_stream;
560*3c7ae9deSAndroid Build Coastguard Worker
561*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_chunked_callback_data *chunked_callback_data =
562*3c7ae9deSAndroid Build Coastguard Worker aws_mem_calloc(aws_jni_get_allocator(), 1, sizeof(struct http_stream_chunked_callback_data));
563*3c7ae9deSAndroid Build Coastguard Worker
564*3c7ae9deSAndroid Build Coastguard Worker chunked_callback_data->stream_cb_data = cb_data;
565*3c7ae9deSAndroid Build Coastguard Worker chunked_callback_data->completion_callback = (*env)->NewGlobalRef(env, completion_callback);
566*3c7ae9deSAndroid Build Coastguard Worker
567*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor chunk_cur = aws_jni_byte_cursor_from_jbyteArray_acquire(env, chunk_data);
568*3c7ae9deSAndroid Build Coastguard Worker aws_byte_buf_init_copy_from_cursor(&chunked_callback_data->chunk_data, aws_jni_get_allocator(), chunk_cur);
569*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, chunk_data, chunk_cur);
570*3c7ae9deSAndroid Build Coastguard Worker
571*3c7ae9deSAndroid Build Coastguard Worker struct aws_http1_chunk_options chunk_options = {
572*3c7ae9deSAndroid Build Coastguard Worker .chunk_data_size = chunked_callback_data->chunk_data.len,
573*3c7ae9deSAndroid Build Coastguard Worker .user_data = chunked_callback_data,
574*3c7ae9deSAndroid Build Coastguard Worker .on_complete = s_write_chunk_complete,
575*3c7ae9deSAndroid Build Coastguard Worker };
576*3c7ae9deSAndroid Build Coastguard Worker
577*3c7ae9deSAndroid Build Coastguard Worker chunk_cur = aws_byte_cursor_from_buf(&chunked_callback_data->chunk_data);
578*3c7ae9deSAndroid Build Coastguard Worker chunked_callback_data->chunk_stream = aws_input_stream_new_from_cursor(aws_jni_get_allocator(), &chunk_cur);
579*3c7ae9deSAndroid Build Coastguard Worker chunk_options.chunk_data = chunked_callback_data->chunk_stream;
580*3c7ae9deSAndroid Build Coastguard Worker
581*3c7ae9deSAndroid Build Coastguard Worker if (aws_http1_stream_write_chunk(stream, &chunk_options)) {
582*3c7ae9deSAndroid Build Coastguard Worker s_cleanup_chunked_callback_data(env, chunked_callback_data);
583*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
584*3c7ae9deSAndroid Build Coastguard Worker }
585*3c7ae9deSAndroid Build Coastguard Worker
586*3c7ae9deSAndroid Build Coastguard Worker if (is_final_chunk) {
587*3c7ae9deSAndroid Build Coastguard Worker struct aws_http1_chunk_options final_chunk_options = {
588*3c7ae9deSAndroid Build Coastguard Worker .chunk_data_size = 0,
589*3c7ae9deSAndroid Build Coastguard Worker };
590*3c7ae9deSAndroid Build Coastguard Worker
591*3c7ae9deSAndroid Build Coastguard Worker if (aws_http1_stream_write_chunk(stream, &final_chunk_options)) {
592*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_ERR;
593*3c7ae9deSAndroid Build Coastguard Worker }
594*3c7ae9deSAndroid Build Coastguard Worker }
595*3c7ae9deSAndroid Build Coastguard Worker
596*3c7ae9deSAndroid Build Coastguard Worker return AWS_OP_SUCCESS;
597*3c7ae9deSAndroid Build Coastguard Worker }
598*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseActivate(JNIEnv * env,jclass jni_class,jlong jni_stream_binding,jobject j_http_stream_base)599*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseActivate(
600*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
601*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
602*3c7ae9deSAndroid Build Coastguard Worker jlong jni_stream_binding,
603*3c7ae9deSAndroid Build Coastguard Worker jobject j_http_stream_base) {
604*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
605*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
606*3c7ae9deSAndroid Build Coastguard Worker
607*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)jni_stream_binding;
608*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream = binding->native_stream;
609*3c7ae9deSAndroid Build Coastguard Worker
610*3c7ae9deSAndroid Build Coastguard Worker if (stream == NULL) {
611*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpStream is null.");
612*3c7ae9deSAndroid Build Coastguard Worker return;
613*3c7ae9deSAndroid Build Coastguard Worker }
614*3c7ae9deSAndroid Build Coastguard Worker
615*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_TRACE(AWS_LS_HTTP_STREAM, "Activating Stream. stream: %p", (void *)stream);
616*3c7ae9deSAndroid Build Coastguard Worker
617*3c7ae9deSAndroid Build Coastguard Worker /* global ref this because now the callbacks will be firing, and they will release their reference when the
618*3c7ae9deSAndroid Build Coastguard Worker * stream callback sequence completes. */
619*3c7ae9deSAndroid Build Coastguard Worker binding->java_http_stream_base = (*env)->NewGlobalRef(env, j_http_stream_base);
620*3c7ae9deSAndroid Build Coastguard Worker if (aws_http_stream_activate(stream)) {
621*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, binding->java_http_stream_base);
622*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
623*3c7ae9deSAndroid Build Coastguard Worker env, "HttpStream activate failed with error %s\n", aws_error_str(aws_last_error()));
624*3c7ae9deSAndroid Build Coastguard Worker }
625*3c7ae9deSAndroid Build Coastguard Worker }
626*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseRelease(JNIEnv * env,jclass jni_class,jlong jni_binding)627*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseRelease(
628*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
629*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
630*3c7ae9deSAndroid Build Coastguard Worker jlong jni_binding) {
631*3c7ae9deSAndroid Build Coastguard Worker
632*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
633*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
634*3c7ae9deSAndroid Build Coastguard Worker
635*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)jni_binding;
636*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream = binding->native_stream;
637*3c7ae9deSAndroid Build Coastguard Worker
638*3c7ae9deSAndroid Build Coastguard Worker if (stream == NULL) {
639*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpStream is null.");
640*3c7ae9deSAndroid Build Coastguard Worker return;
641*3c7ae9deSAndroid Build Coastguard Worker }
642*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_TRACE(AWS_LS_HTTP_STREAM, "Releasing Stream. stream: %p", (void *)stream);
643*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_release(stream);
644*3c7ae9deSAndroid Build Coastguard Worker
645*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_binding_release(env, binding);
646*3c7ae9deSAndroid Build Coastguard Worker }
647*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseGetResponseStatusCode(JNIEnv * env,jclass jni_class,jlong jni_binding)648*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jint JNICALL Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseGetResponseStatusCode(
649*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
650*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
651*3c7ae9deSAndroid Build Coastguard Worker jlong jni_binding) {
652*3c7ae9deSAndroid Build Coastguard Worker
653*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
654*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
655*3c7ae9deSAndroid Build Coastguard Worker
656*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)jni_binding;
657*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream = binding->native_stream;
658*3c7ae9deSAndroid Build Coastguard Worker
659*3c7ae9deSAndroid Build Coastguard Worker if (stream == NULL) {
660*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpStream is null.");
661*3c7ae9deSAndroid Build Coastguard Worker return -1;
662*3c7ae9deSAndroid Build Coastguard Worker }
663*3c7ae9deSAndroid Build Coastguard Worker
664*3c7ae9deSAndroid Build Coastguard Worker int status = -1;
665*3c7ae9deSAndroid Build Coastguard Worker int err_code = aws_http_stream_get_incoming_response_status(stream, &status);
666*3c7ae9deSAndroid Build Coastguard Worker
667*3c7ae9deSAndroid Build Coastguard Worker if (err_code != AWS_OP_SUCCESS) {
668*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Error Getting Response Status Code from HttpStream.");
669*3c7ae9deSAndroid Build Coastguard Worker return -1;
670*3c7ae9deSAndroid Build Coastguard Worker }
671*3c7ae9deSAndroid Build Coastguard Worker
672*3c7ae9deSAndroid Build Coastguard Worker return (jint)status;
673*3c7ae9deSAndroid Build Coastguard Worker }
674*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseIncrementWindow(JNIEnv * env,jclass jni_class,jlong jni_binding,jint window_update)675*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_HttpStreamBase_httpStreamBaseIncrementWindow(
676*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
677*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
678*3c7ae9deSAndroid Build Coastguard Worker jlong jni_binding,
679*3c7ae9deSAndroid Build Coastguard Worker jint window_update) {
680*3c7ae9deSAndroid Build Coastguard Worker
681*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
682*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
683*3c7ae9deSAndroid Build Coastguard Worker
684*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)jni_binding;
685*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream = binding->native_stream;
686*3c7ae9deSAndroid Build Coastguard Worker
687*3c7ae9deSAndroid Build Coastguard Worker if (stream == NULL) {
688*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpStream is null.");
689*3c7ae9deSAndroid Build Coastguard Worker return;
690*3c7ae9deSAndroid Build Coastguard Worker }
691*3c7ae9deSAndroid Build Coastguard Worker
692*3c7ae9deSAndroid Build Coastguard Worker if (window_update < 0) {
693*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Window Update is < 0");
694*3c7ae9deSAndroid Build Coastguard Worker return;
695*3c7ae9deSAndroid Build Coastguard Worker }
696*3c7ae9deSAndroid Build Coastguard Worker
697*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_TRACE(
698*3c7ae9deSAndroid Build Coastguard Worker AWS_LS_HTTP_STREAM, "Updating Stream Window. stream: %p, update: %d", (void *)stream, (int)window_update);
699*3c7ae9deSAndroid Build Coastguard Worker aws_http_stream_update_window(stream, window_update);
700*3c7ae9deSAndroid Build Coastguard Worker }
701*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_Http2Stream_http2StreamResetStream(JNIEnv * env,jclass jni_class,jlong jni_cb_data,jint error_code)702*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_Http2Stream_http2StreamResetStream(
703*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
704*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
705*3c7ae9deSAndroid Build Coastguard Worker jlong jni_cb_data,
706*3c7ae9deSAndroid Build Coastguard Worker jint error_code) {
707*3c7ae9deSAndroid Build Coastguard Worker
708*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
709*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
710*3c7ae9deSAndroid Build Coastguard Worker
711*3c7ae9deSAndroid Build Coastguard Worker struct http_stream_binding *binding = (struct http_stream_binding *)jni_cb_data;
712*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_stream *stream = binding->native_stream;
713*3c7ae9deSAndroid Build Coastguard Worker
714*3c7ae9deSAndroid Build Coastguard Worker if (stream == NULL) {
715*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_null_pointer_exception(env, "Http2Stream is null.");
716*3c7ae9deSAndroid Build Coastguard Worker return;
717*3c7ae9deSAndroid Build Coastguard Worker }
718*3c7ae9deSAndroid Build Coastguard Worker
719*3c7ae9deSAndroid Build Coastguard Worker AWS_LOGF_TRACE(AWS_LS_HTTP_STREAM, "Resetting Stream. stream: %p", (void *)stream);
720*3c7ae9deSAndroid Build Coastguard Worker if (aws_http2_stream_reset(stream, error_code)) {
721*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
722*3c7ae9deSAndroid Build Coastguard Worker env, "reset stream failed with error %d(%s).", aws_last_error(), aws_error_debug_str(aws_last_error()));
723*3c7ae9deSAndroid Build Coastguard Worker return;
724*3c7ae9deSAndroid Build Coastguard Worker }
725*3c7ae9deSAndroid Build Coastguard Worker }
726*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionShutdown(JNIEnv * env,jclass jni_class,jlong jni_connection)727*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionShutdown(
728*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
729*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
730*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection) {
731*3c7ae9deSAndroid Build Coastguard Worker
732*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
733*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
734*3c7ae9deSAndroid Build Coastguard Worker
735*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
736*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
737*3c7ae9deSAndroid Build Coastguard Worker
738*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
739*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpClientConnection.Shutdown: Invalid aws_http_connection");
740*3c7ae9deSAndroid Build Coastguard Worker return;
741*3c7ae9deSAndroid Build Coastguard Worker }
742*3c7ae9deSAndroid Build Coastguard Worker
743*3c7ae9deSAndroid Build Coastguard Worker aws_http_connection_close(native_conn);
744*3c7ae9deSAndroid Build Coastguard Worker }
745*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionIsOpen(JNIEnv * env,jclass jni_class,jlong jni_connection)746*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jboolean JNICALL Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionIsOpen(
747*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
748*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
749*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection) {
750*3c7ae9deSAndroid Build Coastguard Worker
751*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
752*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
753*3c7ae9deSAndroid Build Coastguard Worker
754*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
755*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
756*3c7ae9deSAndroid Build Coastguard Worker
757*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
758*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpClientConnection.isOpen: Invalid aws_http_connection");
759*3c7ae9deSAndroid Build Coastguard Worker return false;
760*3c7ae9deSAndroid Build Coastguard Worker }
761*3c7ae9deSAndroid Build Coastguard Worker
762*3c7ae9deSAndroid Build Coastguard Worker return aws_http_connection_is_open(native_conn);
763*3c7ae9deSAndroid Build Coastguard Worker }
764*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionGetVersion(JNIEnv * env,jclass jni_class,jlong jni_connection)765*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jshort JNICALL Java_software_amazon_awssdk_crt_http_HttpClientConnection_httpClientConnectionGetVersion(
766*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
767*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
768*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection) {
769*3c7ae9deSAndroid Build Coastguard Worker
770*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
771*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
772*3c7ae9deSAndroid Build Coastguard Worker
773*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
774*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
775*3c7ae9deSAndroid Build Coastguard Worker
776*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
777*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "HttpClientConnection.getVersion: Invalid aws_http_connection");
778*3c7ae9deSAndroid Build Coastguard Worker return 0;
779*3c7ae9deSAndroid Build Coastguard Worker }
780*3c7ae9deSAndroid Build Coastguard Worker return (jshort)aws_http_connection_get_version(native_conn);
781*3c7ae9deSAndroid Build Coastguard Worker }
782*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_HttpClientConnection_isErrorRetryable(JNIEnv * env,jclass jni_class,jint error_code)783*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT jboolean JNICALL Java_software_amazon_awssdk_crt_http_HttpClientConnection_isErrorRetryable(
784*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
785*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
786*3c7ae9deSAndroid Build Coastguard Worker jint error_code) {
787*3c7ae9deSAndroid Build Coastguard Worker
788*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
789*3c7ae9deSAndroid Build Coastguard Worker (void)env;
790*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
791*3c7ae9deSAndroid Build Coastguard Worker
792*3c7ae9deSAndroid Build Coastguard Worker switch (error_code) {
793*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_HEADER_NOT_FOUND:
794*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_INVALID_HEADER_FIELD:
795*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_INVALID_HEADER_NAME:
796*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_INVALID_HEADER_VALUE:
797*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_INVALID_METHOD:
798*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_INVALID_PATH:
799*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_INVALID_STATUS_CODE:
800*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_MISSING_BODY_STREAM:
801*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_INVALID_BODY_STREAM:
802*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_OUTGOING_STREAM_LENGTH_INCORRECT:
803*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_CALLBACK_FAILURE:
804*3c7ae9deSAndroid Build Coastguard Worker case AWS_ERROR_HTTP_STREAM_MANAGER_SHUTTING_DOWN:
805*3c7ae9deSAndroid Build Coastguard Worker case AWS_HTTP2_ERR_CANCEL:
806*3c7ae9deSAndroid Build Coastguard Worker return false;
807*3c7ae9deSAndroid Build Coastguard Worker default:
808*3c7ae9deSAndroid Build Coastguard Worker return true;
809*3c7ae9deSAndroid Build Coastguard Worker }
810*3c7ae9deSAndroid Build Coastguard Worker }
811*3c7ae9deSAndroid Build Coastguard Worker
812*3c7ae9deSAndroid Build Coastguard Worker struct aws_http2_callback_data {
813*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm;
814*3c7ae9deSAndroid Build Coastguard Worker jobject async_callback;
815*3c7ae9deSAndroid Build Coastguard Worker };
816*3c7ae9deSAndroid Build Coastguard Worker
s_cleanup_http2_callback_data(struct aws_http2_callback_data * callback_data,JNIEnv * env)817*3c7ae9deSAndroid Build Coastguard Worker static void s_cleanup_http2_callback_data(struct aws_http2_callback_data *callback_data, JNIEnv *env) {
818*3c7ae9deSAndroid Build Coastguard Worker if (callback_data == NULL || env == NULL) {
819*3c7ae9deSAndroid Build Coastguard Worker return;
820*3c7ae9deSAndroid Build Coastguard Worker }
821*3c7ae9deSAndroid Build Coastguard Worker
822*3c7ae9deSAndroid Build Coastguard Worker if (callback_data->async_callback) {
823*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteGlobalRef(env, callback_data->async_callback);
824*3c7ae9deSAndroid Build Coastguard Worker }
825*3c7ae9deSAndroid Build Coastguard Worker
826*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(aws_jni_get_allocator(), callback_data);
827*3c7ae9deSAndroid Build Coastguard Worker }
828*3c7ae9deSAndroid Build Coastguard Worker
s_new_http2_callback_data(JNIEnv * env,struct aws_allocator * allocator,jobject async_callback)829*3c7ae9deSAndroid Build Coastguard Worker static struct aws_http2_callback_data *s_new_http2_callback_data(
830*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
831*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator,
832*3c7ae9deSAndroid Build Coastguard Worker jobject async_callback) {
833*3c7ae9deSAndroid Build Coastguard Worker struct aws_http2_callback_data *callback_data =
834*3c7ae9deSAndroid Build Coastguard Worker aws_mem_calloc(allocator, 1, sizeof(struct aws_http2_callback_data));
835*3c7ae9deSAndroid Build Coastguard Worker
836*3c7ae9deSAndroid Build Coastguard Worker jint jvmresult = (*env)->GetJavaVM(env, &callback_data->jvm);
837*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(jvmresult == 0);
838*3c7ae9deSAndroid Build Coastguard Worker callback_data->async_callback = async_callback ? (*env)->NewGlobalRef(env, async_callback) : NULL;
839*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(callback_data->async_callback != NULL);
840*3c7ae9deSAndroid Build Coastguard Worker
841*3c7ae9deSAndroid Build Coastguard Worker return callback_data;
842*3c7ae9deSAndroid Build Coastguard Worker }
843*3c7ae9deSAndroid Build Coastguard Worker
s_on_settings_completed(struct aws_http_connection * http2_connection,int error_code,void * user_data)844*3c7ae9deSAndroid Build Coastguard Worker static void s_on_settings_completed(struct aws_http_connection *http2_connection, int error_code, void *user_data) {
845*3c7ae9deSAndroid Build Coastguard Worker (void)http2_connection;
846*3c7ae9deSAndroid Build Coastguard Worker struct aws_http2_callback_data *callback_data = user_data;
847*3c7ae9deSAndroid Build Coastguard Worker
848*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
849*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm = callback_data->jvm;
850*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(jvm);
851*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
852*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
853*3c7ae9deSAndroid Build Coastguard Worker return;
854*3c7ae9deSAndroid Build Coastguard Worker }
855*3c7ae9deSAndroid Build Coastguard Worker
856*3c7ae9deSAndroid Build Coastguard Worker if (error_code) {
857*3c7ae9deSAndroid Build Coastguard Worker jobject crt_exception = aws_jni_new_crt_exception_from_error_code(env, error_code);
858*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(env, callback_data->async_callback, async_callback_properties.on_failure, crt_exception);
859*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, crt_exception);
860*3c7ae9deSAndroid Build Coastguard Worker } else {
861*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(env, callback_data->async_callback, async_callback_properties.on_success);
862*3c7ae9deSAndroid Build Coastguard Worker }
863*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env));
864*3c7ae9deSAndroid Build Coastguard Worker s_cleanup_http2_callback_data(callback_data, env);
865*3c7ae9deSAndroid Build Coastguard Worker
866*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(jvm, env);
867*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
868*3c7ae9deSAndroid Build Coastguard Worker }
869*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionUpdateSettings(JNIEnv * env,jclass jni_class,jlong jni_connection,jobject java_async_callback,jlongArray java_marshalled_settings)870*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionUpdateSettings(
871*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
872*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
873*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection,
874*3c7ae9deSAndroid Build Coastguard Worker jobject java_async_callback,
875*3c7ae9deSAndroid Build Coastguard Worker jlongArray java_marshalled_settings) {
876*3c7ae9deSAndroid Build Coastguard Worker
877*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
878*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
879*3c7ae9deSAndroid Build Coastguard Worker
880*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
881*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
882*3c7ae9deSAndroid Build Coastguard Worker
883*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
884*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_null_pointer_exception(
885*3c7ae9deSAndroid Build Coastguard Worker env, "Http2ClientConnection.http2ClientConnectionUpdateSettings: Invalid aws_http_connection");
886*3c7ae9deSAndroid Build Coastguard Worker return;
887*3c7ae9deSAndroid Build Coastguard Worker }
888*3c7ae9deSAndroid Build Coastguard Worker if (!java_async_callback) {
889*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(
890*3c7ae9deSAndroid Build Coastguard Worker env, "Http2ClientConnection.http2ClientConnectionUpdateSettings: Invalid async callback");
891*3c7ae9deSAndroid Build Coastguard Worker return;
892*3c7ae9deSAndroid Build Coastguard Worker }
893*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
894*3c7ae9deSAndroid Build Coastguard Worker struct aws_http2_callback_data *callback_data = s_new_http2_callback_data(env, allocator, java_async_callback);
895*3c7ae9deSAndroid Build Coastguard Worker
896*3c7ae9deSAndroid Build Coastguard Worker /* We marshalled each setting to two long integers, the long list will be number of settings times two */
897*3c7ae9deSAndroid Build Coastguard Worker const size_t len = (*env)->GetArrayLength(env, java_marshalled_settings);
898*3c7ae9deSAndroid Build Coastguard Worker AWS_ASSERT(len % 2 == 0);
899*3c7ae9deSAndroid Build Coastguard Worker const size_t settings_len = len / 2;
900*3c7ae9deSAndroid Build Coastguard Worker struct aws_http2_setting *settings =
901*3c7ae9deSAndroid Build Coastguard Worker settings_len ? aws_mem_calloc(allocator, settings_len, sizeof(struct aws_http2_setting)) : NULL;
902*3c7ae9deSAndroid Build Coastguard Worker int success = false;
903*3c7ae9deSAndroid Build Coastguard Worker jlong *marshalled_settings = (*env)->GetLongArrayElements(env, java_marshalled_settings, NULL);
904*3c7ae9deSAndroid Build Coastguard Worker for (size_t i = 0; i < settings_len; i++) {
905*3c7ae9deSAndroid Build Coastguard Worker jlong id = marshalled_settings[i * 2];
906*3c7ae9deSAndroid Build Coastguard Worker settings[i].id = id;
907*3c7ae9deSAndroid Build Coastguard Worker jlong value = marshalled_settings[i * 2 + 1];
908*3c7ae9deSAndroid Build Coastguard Worker settings[i].value = (uint32_t)value;
909*3c7ae9deSAndroid Build Coastguard Worker }
910*3c7ae9deSAndroid Build Coastguard Worker
911*3c7ae9deSAndroid Build Coastguard Worker if (aws_http2_connection_change_settings(
912*3c7ae9deSAndroid Build Coastguard Worker native_conn, settings, settings_len, s_on_settings_completed, callback_data)) {
913*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
914*3c7ae9deSAndroid Build Coastguard Worker env, "Http2ClientConnection.http2ClientConnectionUpdateSettings: failed to change settings");
915*3c7ae9deSAndroid Build Coastguard Worker goto done;
916*3c7ae9deSAndroid Build Coastguard Worker }
917*3c7ae9deSAndroid Build Coastguard Worker success = true;
918*3c7ae9deSAndroid Build Coastguard Worker done:
919*3c7ae9deSAndroid Build Coastguard Worker aws_mem_release(allocator, settings);
920*3c7ae9deSAndroid Build Coastguard Worker (*env)->ReleaseLongArrayElements(env, java_marshalled_settings, (jlong *)marshalled_settings, JNI_ABORT);
921*3c7ae9deSAndroid Build Coastguard Worker if (!success) {
922*3c7ae9deSAndroid Build Coastguard Worker s_cleanup_http2_callback_data(callback_data, env);
923*3c7ae9deSAndroid Build Coastguard Worker }
924*3c7ae9deSAndroid Build Coastguard Worker return;
925*3c7ae9deSAndroid Build Coastguard Worker }
926*3c7ae9deSAndroid Build Coastguard Worker
s_on_ping_completed(struct aws_http_connection * http2_connection,uint64_t round_trip_time_ns,int error_code,void * user_data)927*3c7ae9deSAndroid Build Coastguard Worker static void s_on_ping_completed(
928*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *http2_connection,
929*3c7ae9deSAndroid Build Coastguard Worker uint64_t round_trip_time_ns,
930*3c7ae9deSAndroid Build Coastguard Worker int error_code,
931*3c7ae9deSAndroid Build Coastguard Worker void *user_data) {
932*3c7ae9deSAndroid Build Coastguard Worker (void)http2_connection;
933*3c7ae9deSAndroid Build Coastguard Worker struct aws_http2_callback_data *callback_data = user_data;
934*3c7ae9deSAndroid Build Coastguard Worker
935*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV ACQUIRE **********/
936*3c7ae9deSAndroid Build Coastguard Worker JavaVM *jvm = callback_data->jvm;
937*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env = aws_jni_acquire_thread_env(jvm);
938*3c7ae9deSAndroid Build Coastguard Worker if (env == NULL) {
939*3c7ae9deSAndroid Build Coastguard Worker /* If we can't get an environment, then the JVM is probably shutting down. Don't crash. */
940*3c7ae9deSAndroid Build Coastguard Worker return;
941*3c7ae9deSAndroid Build Coastguard Worker }
942*3c7ae9deSAndroid Build Coastguard Worker
943*3c7ae9deSAndroid Build Coastguard Worker if (error_code) {
944*3c7ae9deSAndroid Build Coastguard Worker jobject crt_exception = aws_jni_new_crt_exception_from_error_code(env, error_code);
945*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(env, callback_data->async_callback, async_callback_properties.on_failure, crt_exception);
946*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, crt_exception);
947*3c7ae9deSAndroid Build Coastguard Worker } else {
948*3c7ae9deSAndroid Build Coastguard Worker jobject java_round_trip_time_ns = (*env)->NewObject(
949*3c7ae9deSAndroid Build Coastguard Worker env, boxed_long_properties.long_class, boxed_long_properties.constructor, (jlong)round_trip_time_ns);
950*3c7ae9deSAndroid Build Coastguard Worker (*env)->CallVoidMethod(
951*3c7ae9deSAndroid Build Coastguard Worker env,
952*3c7ae9deSAndroid Build Coastguard Worker callback_data->async_callback,
953*3c7ae9deSAndroid Build Coastguard Worker async_callback_properties.on_success_with_object,
954*3c7ae9deSAndroid Build Coastguard Worker java_round_trip_time_ns);
955*3c7ae9deSAndroid Build Coastguard Worker (*env)->DeleteLocalRef(env, java_round_trip_time_ns);
956*3c7ae9deSAndroid Build Coastguard Worker }
957*3c7ae9deSAndroid Build Coastguard Worker AWS_FATAL_ASSERT(!aws_jni_check_and_clear_exception(env));
958*3c7ae9deSAndroid Build Coastguard Worker s_cleanup_http2_callback_data(callback_data, env);
959*3c7ae9deSAndroid Build Coastguard Worker
960*3c7ae9deSAndroid Build Coastguard Worker aws_jni_release_thread_env(jvm, env);
961*3c7ae9deSAndroid Build Coastguard Worker /********** JNI ENV RELEASE **********/
962*3c7ae9deSAndroid Build Coastguard Worker }
963*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionSendPing(JNIEnv * env,jclass jni_class,jlong jni_connection,jobject java_async_callback,jbyteArray ping_data)964*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionSendPing(
965*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
966*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
967*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection,
968*3c7ae9deSAndroid Build Coastguard Worker jobject java_async_callback,
969*3c7ae9deSAndroid Build Coastguard Worker jbyteArray ping_data) {
970*3c7ae9deSAndroid Build Coastguard Worker
971*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
972*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
973*3c7ae9deSAndroid Build Coastguard Worker
974*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
975*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
976*3c7ae9deSAndroid Build Coastguard Worker
977*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
978*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_null_pointer_exception(
979*3c7ae9deSAndroid Build Coastguard Worker env, "Http2ClientConnection.http2ClientConnectionSendPing: Invalid aws_http_connection");
980*3c7ae9deSAndroid Build Coastguard Worker return;
981*3c7ae9deSAndroid Build Coastguard Worker }
982*3c7ae9deSAndroid Build Coastguard Worker if (!java_async_callback) {
983*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_illegal_argument_exception(
984*3c7ae9deSAndroid Build Coastguard Worker env, "Http2ClientConnection.http2ClientConnectionSendPing: Invalid async callback");
985*3c7ae9deSAndroid Build Coastguard Worker return;
986*3c7ae9deSAndroid Build Coastguard Worker }
987*3c7ae9deSAndroid Build Coastguard Worker bool success = false;
988*3c7ae9deSAndroid Build Coastguard Worker struct aws_allocator *allocator = aws_jni_get_allocator();
989*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor *ping_cur_pointer = NULL;
990*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor ping_cur;
991*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(ping_cur);
992*3c7ae9deSAndroid Build Coastguard Worker struct aws_http2_callback_data *callback_data = s_new_http2_callback_data(env, allocator, java_async_callback);
993*3c7ae9deSAndroid Build Coastguard Worker
994*3c7ae9deSAndroid Build Coastguard Worker if (ping_data) {
995*3c7ae9deSAndroid Build Coastguard Worker ping_cur = aws_jni_byte_cursor_from_jbyteArray_acquire(env, ping_data);
996*3c7ae9deSAndroid Build Coastguard Worker ping_cur_pointer = &ping_cur;
997*3c7ae9deSAndroid Build Coastguard Worker }
998*3c7ae9deSAndroid Build Coastguard Worker if (aws_http2_connection_ping(native_conn, ping_cur_pointer, s_on_ping_completed, callback_data)) {
999*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(env, "Failed to send ping");
1000*3c7ae9deSAndroid Build Coastguard Worker goto done;
1001*3c7ae9deSAndroid Build Coastguard Worker }
1002*3c7ae9deSAndroid Build Coastguard Worker success = true;
1003*3c7ae9deSAndroid Build Coastguard Worker done:
1004*3c7ae9deSAndroid Build Coastguard Worker if (ping_cur_pointer) {
1005*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, ping_data, ping_cur);
1006*3c7ae9deSAndroid Build Coastguard Worker }
1007*3c7ae9deSAndroid Build Coastguard Worker if (!success) {
1008*3c7ae9deSAndroid Build Coastguard Worker s_cleanup_http2_callback_data(callback_data, env);
1009*3c7ae9deSAndroid Build Coastguard Worker }
1010*3c7ae9deSAndroid Build Coastguard Worker return;
1011*3c7ae9deSAndroid Build Coastguard Worker }
1012*3c7ae9deSAndroid Build Coastguard Worker
Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionSendGoAway(JNIEnv * env,jclass jni_class,jlong jni_connection,jlong h2_error_code,jboolean allow_more_streams,jbyteArray debug_data)1013*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionSendGoAway(
1014*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
1015*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
1016*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection,
1017*3c7ae9deSAndroid Build Coastguard Worker jlong h2_error_code,
1018*3c7ae9deSAndroid Build Coastguard Worker jboolean allow_more_streams,
1019*3c7ae9deSAndroid Build Coastguard Worker jbyteArray debug_data) {
1020*3c7ae9deSAndroid Build Coastguard Worker
1021*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
1022*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
1023*3c7ae9deSAndroid Build Coastguard Worker
1024*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
1025*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
1026*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor *debug_cur_pointer = NULL;
1027*3c7ae9deSAndroid Build Coastguard Worker struct aws_byte_cursor debug_cur;
1028*3c7ae9deSAndroid Build Coastguard Worker AWS_ZERO_STRUCT(debug_cur);
1029*3c7ae9deSAndroid Build Coastguard Worker
1030*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
1031*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
1032*3c7ae9deSAndroid Build Coastguard Worker env, "Http2ClientConnection.http2ClientConnectionSendGoAway: Invalid aws_http_connection");
1033*3c7ae9deSAndroid Build Coastguard Worker return;
1034*3c7ae9deSAndroid Build Coastguard Worker }
1035*3c7ae9deSAndroid Build Coastguard Worker if (debug_data) {
1036*3c7ae9deSAndroid Build Coastguard Worker debug_cur = aws_jni_byte_cursor_from_jbyteArray_acquire(env, debug_data);
1037*3c7ae9deSAndroid Build Coastguard Worker debug_cur_pointer = &debug_cur;
1038*3c7ae9deSAndroid Build Coastguard Worker }
1039*3c7ae9deSAndroid Build Coastguard Worker aws_http2_connection_send_goaway(native_conn, (uint32_t)h2_error_code, allow_more_streams, debug_cur_pointer);
1040*3c7ae9deSAndroid Build Coastguard Worker if (debug_cur_pointer) {
1041*3c7ae9deSAndroid Build Coastguard Worker aws_jni_byte_cursor_from_jbyteArray_release(env, debug_data, debug_cur);
1042*3c7ae9deSAndroid Build Coastguard Worker }
1043*3c7ae9deSAndroid Build Coastguard Worker return;
1044*3c7ae9deSAndroid Build Coastguard Worker }
1045*3c7ae9deSAndroid Build Coastguard Worker
1046*3c7ae9deSAndroid Build Coastguard Worker JNIEXPORT void JNICALL
Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionUpdateConnectionWindow(JNIEnv * env,jclass jni_class,jlong jni_connection,jlong increment_size)1047*3c7ae9deSAndroid Build Coastguard Worker Java_software_amazon_awssdk_crt_http_Http2ClientConnection_http2ClientConnectionUpdateConnectionWindow(
1048*3c7ae9deSAndroid Build Coastguard Worker JNIEnv *env,
1049*3c7ae9deSAndroid Build Coastguard Worker jclass jni_class,
1050*3c7ae9deSAndroid Build Coastguard Worker jlong jni_connection,
1051*3c7ae9deSAndroid Build Coastguard Worker jlong increment_size) {
1052*3c7ae9deSAndroid Build Coastguard Worker
1053*3c7ae9deSAndroid Build Coastguard Worker (void)jni_class;
1054*3c7ae9deSAndroid Build Coastguard Worker aws_cache_jni_ids(env);
1055*3c7ae9deSAndroid Build Coastguard Worker
1056*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection_binding *connection_binding = (struct aws_http_connection_binding *)jni_connection;
1057*3c7ae9deSAndroid Build Coastguard Worker struct aws_http_connection *native_conn = connection_binding->connection;
1058*3c7ae9deSAndroid Build Coastguard Worker
1059*3c7ae9deSAndroid Build Coastguard Worker if (!native_conn) {
1060*3c7ae9deSAndroid Build Coastguard Worker aws_jni_throw_runtime_exception(
1061*3c7ae9deSAndroid Build Coastguard Worker env, "Http2ClientConnection.http2ClientConnectionUpdateConnectionWindow: Invalid aws_http_connection");
1062*3c7ae9deSAndroid Build Coastguard Worker return;
1063*3c7ae9deSAndroid Build Coastguard Worker }
1064*3c7ae9deSAndroid Build Coastguard Worker /* We did range check in Java already. */
1065*3c7ae9deSAndroid Build Coastguard Worker aws_http2_connection_update_window(native_conn, (uint32_t)increment_size);
1066*3c7ae9deSAndroid Build Coastguard Worker return;
1067*3c7ae9deSAndroid Build Coastguard Worker }
1068*3c7ae9deSAndroid Build Coastguard Worker
1069*3c7ae9deSAndroid Build Coastguard Worker #if UINTPTR_MAX == 0xffffffff
1070*3c7ae9deSAndroid Build Coastguard Worker # if defined(_MSC_VER)
1071*3c7ae9deSAndroid Build Coastguard Worker # pragma warning(pop)
1072*3c7ae9deSAndroid Build Coastguard Worker # else
1073*3c7ae9deSAndroid Build Coastguard Worker # pragma GCC diagnostic pop
1074*3c7ae9deSAndroid Build Coastguard Worker # endif
1075*3c7ae9deSAndroid Build Coastguard Worker #endif
1076