in source/http_stream.c [69:145]
static int s_on_incoming_header_block_done(
struct aws_http_stream *native_stream,
enum aws_http_header_block header_block,
void *user_data) {
struct http_stream_binding *stream = user_data;
int response_code = 0;
if (aws_http_stream_get_incoming_response_status(native_stream, &response_code)) {
return AWS_OP_ERR;
}
if (stream->received_headers_count > PY_SSIZE_T_MAX) {
return aws_raise_error(AWS_ERROR_OVERFLOW_DETECTED);
}
Py_ssize_t num_headers = (Py_ssize_t)stream->received_headers_count;
int aws_result = AWS_OP_SUCCESS;
/*************** GIL ACQUIRE ***************/
PyGILState_STATE state;
if (aws_py_gilstate_ensure(&state)) {
return AWS_OP_ERR; /* Python has shut down. Nothing matters anymore, but don't crash */
}
/* Build up a list of (name,value) tuples,
* extracting values from buffer of [name,value,name,value,...] null-terminated strings */
PyObject *header_list = PyList_New(num_headers);
if (!header_list) {
aws_result = aws_py_raise_error();
goto done;
}
struct aws_byte_cursor string_cursor = aws_byte_cursor_from_buf(&stream->received_headers);
for (Py_ssize_t i = 0; i < num_headers; ++i) {
const char *name_str = (const char *)string_cursor.ptr;
size_t name_len = strlen((const char *)string_cursor.ptr);
aws_byte_cursor_advance(&string_cursor, name_len + 1);
const char *value_str = (const char *)string_cursor.ptr;
size_t value_len = strlen((const char *)string_cursor.ptr);
aws_byte_cursor_advance(&string_cursor, value_len + 1);
PyObject *tuple = Py_BuildValue("(s#s#)", name_str, name_len, value_str, value_len);
if (!tuple) {
aws_result = aws_py_raise_error();
goto done;
}
PyList_SET_ITEM(header_list, i, tuple); /* steals reference to tuple */
}
/* TODO: handle informational and trailing headers */
if (header_block == AWS_HTTP_HEADER_BLOCK_MAIN) {
/* Deliver the built up list of (name,value) tuples */
PyObject *result = PyObject_CallMethod(stream->self_proxy, "_on_response", "(iO)", response_code, header_list);
if (!result) {
aws_result = aws_py_raise_error();
goto done;
}
Py_DECREF(result);
}
/* Clear the buffer so we're ready for next header block */
stream->received_headers.len = 0;
stream->received_headers_count = 0;
done:
Py_XDECREF(header_list);
PyGILState_Release(state);
/*************** GIL RELEASE ***************/
return aws_result;
}