[libsoup/wip/http2] fixup! Add initial HTTP2 backend
- From: Patrick Griffis <pgriffis src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [libsoup/wip/http2] fixup! Add initial HTTP2 backend
- Date: Fri, 14 May 2021 16:16:07 +0000 (UTC)
commit 721c20cdc2bd9b58a9fb3f8f03814eac28ad6f9b
Author: Patrick Griffis <pgriffis igalia com>
Date: Fri May 14 11:16:02 2021 -0500
fixup! Add initial HTTP2 backend
libsoup/http2/soup-client-message-io-http2.c | 132 +++++++++++++++------------
1 file changed, 76 insertions(+), 56 deletions(-)
---
diff --git a/libsoup/http2/soup-client-message-io-http2.c b/libsoup/http2/soup-client-message-io-http2.c
index 7d9cc36c..63f69b73 100644
--- a/libsoup/http2/soup-client-message-io-http2.c
+++ b/libsoup/http2/soup-client-message-io-http2.c
@@ -48,6 +48,7 @@
#define FRAME_HEADER_SIZE 9
typedef enum {
+ STATE_ANY = -1,
STATE_NONE,
STATE_WRITE_HEADERS,
STATE_WRITE_DATA,
@@ -79,7 +80,7 @@ typedef struct {
gssize written_bytes;
gboolean is_shutdown;
-} SoupMessageIOHTTP2;
+} SoupClientMessageIOHTTP2;
typedef struct {
SoupMessageQueueItem *item;
@@ -104,7 +105,7 @@ typedef struct {
gboolean data_source_eof;
GSource *io_source;
- SoupMessageIOHTTP2 *io; /* Unowned */
+ SoupClientMessageIOHTTP2 *io; /* Unowned */
SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
SoupHTTP2IOState state;
@@ -113,7 +114,7 @@ typedef struct {
} SoupHTTP2MessageData;
static void soup_client_message_io_http2_finished (SoupClientMessageIO *, SoupMessage *);
-static gboolean io_read_or_write (SoupMessageIOHTTP2 *, gboolean, GCancellable *, GError **);
+static gboolean io_read_or_write (SoupClientMessageIOHTTP2 *, gboolean, GCancellable *, GError **);
static const char *
frame_type_to_string (nghttp2_frame_type type)
@@ -150,7 +151,7 @@ frame_type_to_string (nghttp2_frame_type type)
}
static void
-h2_debug (SoupMessageIOHTTP2 *io,
+h2_debug (SoupClientMessageIOHTTP2 *io,
SoupHTTP2MessageData *data,
const char *format,
...)
@@ -172,10 +173,10 @@ h2_debug (SoupMessageIOHTTP2 *io,
g_free (message);
}
-static SoupMessageIOHTTP2 *
+static SoupClientMessageIOHTTP2 *
get_io_data (SoupMessage *msg)
{
- return (SoupMessageIOHTTP2 *)soup_message_get_io_data (msg);
+ return (SoupClientMessageIOHTTP2 *)soup_message_get_io_data (msg);
}
static int
@@ -188,7 +189,7 @@ get_data_io_priority (SoupHTTP2MessageData *data)
}
static void
-set_error_for_data (SoupMessageIOHTTP2 *io,
+set_error_for_data (SoupClientMessageIOHTTP2 *io,
SoupHTTP2MessageData *data,
GError *error)
{
@@ -197,7 +198,7 @@ set_error_for_data (SoupMessageIOHTTP2 *io,
}
static GError *
-get_error_for_data (SoupMessageIOHTTP2 *io,
+get_error_for_data (SoupClientMessageIOHTTP2 *io,
SoupHTTP2MessageData *data)
{
GError *error = NULL;
@@ -207,6 +208,24 @@ get_error_for_data (SoupMessageIOHTTP2 *io,
return error;
}
+static void
+advance_state_from (SoupHTTP2MessageData *data,
+ SoupHTTP2IOState from,
+ SoupHTTP2IOState to)
+{
+ if (from != STATE_ANY)
+ g_warn_if_fail (data->state == from);
+
+ /* State never goes backwards */
+ if (to < data->state) {
+ g_warn_if_reached ();
+ return;
+ }
+
+ h2_debug (data->io, data, "STATE %d -> %d", data->state, to);
+ data->state = to;
+}
+
/* HTTP2 read callbacks */
static int
@@ -298,9 +317,9 @@ on_begin_frame_callback (nghttp2_session *session,
}
static void
-handle_goaway (SoupMessageIOHTTP2 *io,
- guint32 error_code,
- guint32 last_stream_id)
+handle_goaway (SoupClientMessageIOHTTP2 *io,
+ guint32 error_code,
+ guint32 last_stream_id)
{
GHashTableIter iter;
SoupHTTP2MessageData *data;
@@ -325,7 +344,7 @@ on_frame_recv_callback (nghttp2_session *session,
const nghttp2_frame *frame,
gpointer user_data)
{
- SoupMessageIOHTTP2 *io = user_data;
+ SoupClientMessageIOHTTP2 *io = user_data;
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, frame->hd.stream_id);
h2_debug (io, data, "[RECV] [%s] Recieved (%u)", frame_type_to_string (frame->hd.type),
frame->hd.flags);
@@ -353,10 +372,10 @@ on_frame_recv_callback (nghttp2_session *session,
soup_message_got_informational (data->msg);
soup_message_cleanup_response (data->msg);
soup_body_input_stream_http2_complete (SOUP_BODY_INPUT_STREAM_HTTP2
(data->body_istream));
- data->state = STATE_READ_DONE;
+ advance_state_from (data, STATE_READ_HEADERS, STATE_READ_DONE);
break;
} else if (soup_message_get_status (data->msg) == SOUP_STATUS_NO_CONTENT) {
- data->state = STATE_READ_DONE;
+ advance_state_from (data, STATE_READ_HEADERS, STATE_READ_DONE);
}
soup_message_got_headers (data->msg);
}
@@ -377,7 +396,7 @@ on_frame_recv_callback (nghttp2_session *session,
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
h2_debug (io, data, "Stream done");
- data->state = STATE_READ_DONE;
+ advance_state_from (data, STATE_ANY, STATE_READ_DONE);
if (frame->hd.type == NGHTTP2_DATA) {
soup_body_input_stream_http2_complete (SOUP_BODY_INPUT_STREAM_HTTP2
(data->body_istream));
soup_message_got_body (data->msg);
@@ -395,7 +414,7 @@ on_data_chunk_recv_callback (nghttp2_session *session,
size_t len,
void *user_data)
{
- SoupMessageIOHTTP2 *io = user_data;
+ SoupClientMessageIOHTTP2 *io = user_data;
SoupHTTP2MessageData *msgdata = nghttp2_session_get_stream_user_data (session, stream_id);
if (!msgdata)
@@ -414,11 +433,11 @@ on_data_chunk_recv_callback (nghttp2_session *session,
if (soup_message_get_content_sniffer (msg)) {
SoupContentSnifferStream *sniffer_stream = SOUP_CONTENT_SNIFFER_STREAM
(msgdata->decoded_data_istream);
GError *error = NULL;
- if (soup_content_sniffer_stream_is_ready (sniffer_stream, FALSE, NULL, &error)) {
+ if (soup_content_sniffer_stream_is_ready (sniffer_stream, FALSE,
msgdata->cancellable, &error)) {
GHashTable *params;
const char *content_type = soup_content_sniffer_stream_sniff
(sniffer_stream, ¶ms);
- msgdata->state = STATE_READ_DATA_SNIFFED;
+ advance_state_from (msgdata, STATE_READ_DATA, STATE_READ_DATA_SNIFFED);
soup_message_content_sniffed (msg, content_type, params);
h2_debug (io, msgdata, "[DATA] Sniffed %s", content_type);
} else {
@@ -427,7 +446,7 @@ on_data_chunk_recv_callback (nghttp2_session *session,
}
}
else
- msgdata->state = STATE_READ_DATA_SNIFFED;
+ advance_state_from (msgdata, STATE_READ_DATA, STATE_READ_DATA_SNIFFED);
}
return 0;
@@ -447,10 +466,10 @@ on_before_frame_send_callback (nghttp2_session *session,
switch (frame->hd.type) {
case NGHTTP2_HEADERS:
- data->state = STATE_WRITE_HEADERS;
+ advance_state_from (data, STATE_NONE, STATE_WRITE_HEADERS);
break;
case NGHTTP2_DATA:
- data->state = STATE_WRITE_DATA;
+ advance_state_from (data, STATE_WRITE_HEADERS, STATE_WRITE_DATA);
break;
}
@@ -479,7 +498,7 @@ on_frame_send_callback (nghttp2_session *session,
if (frame->hd.flags & NGHTTP2_FLAG_END_HEADERS) {
soup_message_wrote_headers (data->msg);
if (soup_message_get_request_body_stream (data->msg) == NULL) {
- data->state = STATE_WRITE_DONE;
+ advance_state_from (data, STATE_WRITE_HEADERS, STATE_WRITE_DONE);
soup_message_wrote_body (data->msg);
}
}
@@ -494,7 +513,7 @@ on_frame_send_callback (nghttp2_session *session,
if (frame->data.hd.length)
soup_message_wrote_body_data (data->msg, frame->data.hd.length);
if (frame->hd.flags & NGHTTP2_FLAG_END_STREAM) {
- data->state = STATE_WRITE_DONE;
+ advance_state_from (data, STATE_ANY, STATE_WRITE_DONE);
soup_message_wrote_body (data->msg);
}
break;
@@ -601,7 +620,7 @@ on_data_source_read_callback (nghttp2_session *session,
void *user_data)
{
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, stream_id);
- SoupMessageIOHTTP2 *io = get_io_data (data->msg);
+ SoupClientMessageIOHTTP2 *io = get_io_data (data->msg);
if (data->paused) {
g_debug ("[SEND_BODY] Paused");
@@ -697,7 +716,7 @@ on_data_source_read_callback (nghttp2_session *session,
/* HTTP2 IO functions */
static SoupHTTP2MessageData *
-add_message_to_io_data (SoupMessageIOHTTP2 *io,
+add_message_to_io_data (SoupClientMessageIOHTTP2 *io,
SoupMessageQueueItem *item,
SoupMessageIOCompletionFn completion_cb,
gpointer completion_data)
@@ -766,7 +785,7 @@ soup_http2_message_data_free (SoupHTTP2MessageData *data)
static void
send_message_request (SoupMessage *msg,
- SoupMessageIOHTTP2 *io,
+ SoupClientMessageIOHTTP2 *io,
SoupHTTP2MessageData *data)
{
GArray *headers = g_array_new (FALSE, FALSE, sizeof (nghttp2_nv));
@@ -834,15 +853,15 @@ soup_client_message_io_http2_send_item (SoupClientMessageIO *iface,
SoupMessageIOCompletionFn completion_cb,
gpointer user_data)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = add_message_to_io_data (io, item, completion_cb, user_data);
send_message_request (item->msg, io, data);
}
static SoupHTTP2MessageData *
-get_data_for_message (SoupMessageIOHTTP2 *io,
- SoupMessage *msg)
+get_data_for_message (SoupClientMessageIOHTTP2 *io,
+ SoupMessage *msg)
{
SoupHTTP2MessageData *data = g_hash_table_lookup (io->messages, msg);
@@ -855,7 +874,7 @@ static void
soup_client_message_io_http2_finished (SoupClientMessageIO *iface,
SoupMessage *msg)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data;
SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
@@ -891,7 +910,7 @@ static void
soup_client_message_io_http2_pause (SoupClientMessageIO *iface,
SoupMessage *msg)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
g_debug ("soup_client_message_io_http2_pause");
@@ -906,7 +925,7 @@ static void
soup_client_message_io_http2_unpause (SoupClientMessageIO *iface,
SoupMessage *msg)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
g_debug ("soup_client_message_io_http2_unpause");
@@ -927,7 +946,7 @@ static gboolean
soup_client_message_io_http2_in_progress (SoupClientMessageIO *iface,
SoupMessage *msg)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
return data->state < STATE_WRITE_DONE;
@@ -937,7 +956,7 @@ static gboolean
soup_client_message_io_http2_is_paused (SoupClientMessageIO *iface,
SoupMessage *msg)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
return data->paused;
@@ -946,7 +965,7 @@ soup_client_message_io_http2_is_paused (SoupClientMessageIO *iface,
static gboolean
soup_client_message_io_http2_is_reusable (SoupClientMessageIO *iface)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
/* TODO: This logic is probably incomplete */
return !io->is_shutdown;
@@ -957,7 +976,7 @@ message_source_check (GSource *source)
{
SoupMessageIOSource *message_source = (SoupMessageIOSource *)source;
SoupMessage *msg = SOUP_MESSAGE (message_source->msg);
- SoupMessageIOHTTP2 *io = get_io_data (msg);
+ SoupClientMessageIOHTTP2 *io = get_io_data (msg);
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
/* QUESTION: What is the point of message_source->paused */
@@ -971,7 +990,7 @@ soup_client_message_io_http2_get_source (SoupMessage *msg,
SoupMessageIOSourceFunc callback,
gpointer user_data)
{
- SoupMessageIOHTTP2 *io = get_io_data (msg);
+ SoupClientMessageIOHTTP2 *io = get_io_data (msg);
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
GSource *base_source;
@@ -995,7 +1014,7 @@ client_stream_eof (SoupClientInputStream *stream,
gpointer user_data)
{
SoupMessage *msg = user_data;
- SoupMessageIOHTTP2 *io = get_io_data (msg);
+ SoupClientMessageIOHTTP2 *io = get_io_data (msg);
if (!io) {
g_warn_if_reached ();
@@ -1003,7 +1022,8 @@ client_stream_eof (SoupClientInputStream *stream,
}
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
- data->state = STATE_READ_DONE;
+ if (data->state < STATE_READ_DONE)
+ data->state = STATE_READ_DONE;
}
static GInputStream *
@@ -1011,7 +1031,7 @@ soup_client_message_io_http2_get_response_istream (SoupClientMessageIO *iface,
SoupMessage *msg,
GError **error)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
GInputStream *client_stream, *base_stream;
@@ -1031,7 +1051,7 @@ soup_client_message_io_http2_get_response_istream (SoupClientMessageIO *iface,
}
static gboolean
-io_read (SoupMessageIOHTTP2 *io,
+io_read (SoupClientMessageIOHTTP2 *io,
gboolean blocking,
GCancellable *cancellable,
GError **error)
@@ -1049,10 +1069,10 @@ io_read (SoupMessageIOHTTP2 *io,
}
static gboolean
-io_write (SoupMessageIOHTTP2 *io,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
+io_write (SoupClientMessageIOHTTP2 *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
/* We must write all of nghttp2's buffer before we ask for more */
@@ -1081,10 +1101,10 @@ io_write (SoupMessageIOHTTP2 *io,
}
static gboolean
-io_read_or_write (SoupMessageIOHTTP2 *io,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
+io_read_or_write (SoupClientMessageIOHTTP2 *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
/* TODO: This can possibly more inteligent about what actually needs
writing so we can prioritize better. */
@@ -1100,7 +1120,7 @@ io_run_until (SoupMessage *msg,
GCancellable *cancellable,
GError **error)
{
- SoupMessageIOHTTP2 *io = get_io_data (msg);
+ SoupClientMessageIOHTTP2 *io = get_io_data (msg);
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
gboolean progress = TRUE, done;
GError *my_error = NULL;
@@ -1153,7 +1173,7 @@ soup_client_message_io_http2_run_until_read (SoupClientMessageIO *iface,
GCancellable *cancellable,
GError **error)
{
- return io_run_until (msg, TRUE, STATE_READ_DATA, cancellable, error);
+ return io_run_until (msg, TRUE, STATE_READ_DATA_SNIFFED, cancellable, error);
}
static gboolean
@@ -1192,7 +1212,7 @@ static void
io_run_until_read_async (SoupMessage *msg,
GTask *task)
{
- SoupMessageIOHTTP2 *io = get_io_data (msg);
+ SoupClientMessageIOHTTP2 *io = get_io_data (msg);
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
GError *error = NULL;
@@ -1247,7 +1267,7 @@ soup_client_message_io_http2_run_until_read_async (SoupClientMessageIO *iface,
static gboolean
soup_client_message_io_http2_is_open (SoupClientMessageIO *iface)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
gboolean ret = TRUE;
GError *error = NULL;
@@ -1266,7 +1286,7 @@ soup_client_message_io_http2_is_open (SoupClientMessageIO *iface)
static void
soup_client_message_io_http2_destroy (SoupClientMessageIO *iface)
{
- SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
+ SoupClientMessageIOHTTP2 *io = (SoupClientMessageIOHTTP2 *)iface;
g_debug ("soup_client_message_io_http2_destroy");
@@ -1298,7 +1318,7 @@ static const SoupClientMessageIOFuncs io_funcs = {
};
static void
-soup_client_message_io_http2_init (SoupMessageIOHTTP2 *io)
+soup_client_message_io_http2_init (SoupClientMessageIOHTTP2 *io)
{
/* FIXME: Abort on out of memory errors */
nghttp2_session_callbacks *callbacks;
@@ -1328,7 +1348,7 @@ soup_client_message_io_http2_init (SoupMessageIOHTTP2 *io)
SoupClientMessageIO *
soup_client_message_io_http2_new (GIOStream *stream)
{
- SoupMessageIOHTTP2 *io = g_new0 (SoupMessageIOHTTP2, 1);
+ SoupClientMessageIOHTTP2 *io = g_new0 (SoupClientMessageIOHTTP2, 1);
soup_client_message_io_http2_init (io);
io->stream = g_object_ref (stream);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]