1616static const char * s_websocket_capsule_name = "aws_websocket" ;
1717
1818static void s_websocket_on_connection_setup (
19- struct aws_websocket * websocket ,
20- int error_code ,
21- int handshake_response_status ,
22- const struct aws_http_header * handshake_response_header_array ,
23- size_t num_handshake_response_headers ,
19+ const struct aws_websocket_on_connection_setup_data * setup ,
2420 void * user_data );
2521
2622static void s_websocket_on_connection_shutdown (struct aws_websocket * websocket , int error_code , void * user_data );
@@ -177,15 +173,11 @@ PyObject *aws_py_websocket_client_connect(PyObject *self, PyObject *args) {
177173 * that we can't actually check (and so may not actually work).
178174 */
179175static void s_websocket_on_connection_setup (
180- struct aws_websocket * websocket ,
181- int error_code ,
182- int handshake_response_status ,
183- const struct aws_http_header * handshake_response_header_array ,
184- size_t num_handshake_response_headers ,
176+ const struct aws_websocket_on_connection_setup_data * setup ,
185177 void * user_data ) {
186178
187179 /* sanity check: websocket XOR error_code is set. both cannot be set. both cannot be unset */
188- AWS_FATAL_ASSERT ((websocket != NULL ) ^ (error_code != 0 ));
180+ AWS_FATAL_ASSERT ((setup -> websocket != NULL ) ^ (setup -> error_code != 0 ));
189181
190182 /* userdata is _WebSocketCore */
191183 PyObject * websocket_core_py = user_data ;
@@ -194,17 +186,26 @@ static void s_websocket_on_connection_setup(
194186 PyGILState_STATE state = PyGILState_Ensure ();
195187
196188 PyObject * websocket_binding_py = NULL ;
197- if (websocket ) {
198- websocket_binding_py = PyCapsule_New (websocket , s_websocket_capsule_name , s_websocket_capsule_destructor );
189+ if (setup -> websocket ) {
190+ websocket_binding_py =
191+ PyCapsule_New (setup -> websocket , s_websocket_capsule_name , s_websocket_capsule_destructor );
199192 AWS_FATAL_ASSERT (websocket_binding_py && "capsule allocation failed" );
200193 }
201194
195+ /* Any of the handshake_response variables could be NULL */
196+
197+ PyObject * status_code_py = NULL ;
198+ if (setup -> handshake_response_status != NULL ) {
199+ status_code_py = PyLong_FromLong (* setup -> handshake_response_status );
200+ AWS_FATAL_ASSERT (status_code_py && "status code allocation failed" );
201+ }
202+
202203 PyObject * headers_py = NULL ;
203- if (num_handshake_response_headers > 0 ) {
204- headers_py = PyList_New ((Py_ssize_t )num_handshake_response_headers );
204+ if (setup -> handshake_response_header_array != NULL ) {
205+ headers_py = PyList_New ((Py_ssize_t )setup -> num_handshake_response_headers );
205206 AWS_FATAL_ASSERT (headers_py && "header list allocation failed" );
206- for (size_t i = 0 ; i < num_handshake_response_headers ; ++ i ) {
207- const struct aws_http_header * header_i = & handshake_response_header_array [i ];
207+ for (size_t i = 0 ; i < setup -> num_handshake_response_headers ; ++ i ) {
208+ const struct aws_http_header * header_i = & setup -> handshake_response_header_array [i ];
208209 PyObject * tuple_py = PyTuple_New (2 );
209210 AWS_FATAL_ASSERT (tuple_py && "header tuple allocation failed" );
210211
@@ -220,14 +221,24 @@ static void s_websocket_on_connection_setup(
220221 }
221222 }
222223
224+ PyObject * body_py = NULL ;
225+ if (setup -> handshake_response_body != NULL ) {
226+ /* AWS APIs are fine with NULL as the address of a 0-length array,
227+ * but python APIs requires that it be non-NULL */
228+ const char * ptr = setup -> handshake_response_body -> ptr ? (const char * )setup -> handshake_response_body -> ptr : "" ;
229+ body_py = PyBytes_FromStringAndSize (ptr , (Py_ssize_t )setup -> handshake_response_body -> len );
230+ AWS_FATAL_ASSERT (body_py && "response body allocation failed" );
231+ }
232+
223233 PyObject * result = PyObject_CallMethod (
224234 websocket_core_py ,
225235 "_on_connection_setup" ,
226- "(iOiO)" ,
227- error_code ,
228- websocket_binding_py ? websocket_binding_py : Py_None ,
229- handshake_response_status ,
230- headers_py ? headers_py : Py_None );
236+ "(iOOOO)" ,
237+ /* i */ setup -> error_code ,
238+ /* O */ websocket_binding_py ? websocket_binding_py : Py_None ,
239+ /* O */ status_code_py ? status_code_py : Py_None ,
240+ /* O */ headers_py ? headers_py : Py_None ,
241+ /* O */ body_py ? body_py : Py_None );
231242
232243 if (result ) {
233244 Py_DECREF (result );
@@ -240,10 +251,12 @@ static void s_websocket_on_connection_setup(
240251 }
241252
242253 Py_XDECREF (websocket_binding_py );
254+ Py_XDECREF (status_code_py );
243255 Py_XDECREF (headers_py );
256+ Py_XDECREF (body_py );
244257
245258 /* If setup failed, there will be no further callbacks, so release _WebSocketCore */
246- if (error_code != 0 ) {
259+ if (setup -> error_code != 0 ) {
247260 Py_DECREF (websocket_core_py );
248261 }
249262
0 commit comments