[libsoup/wip/http2] fixup! Add initial HTTP2 backend



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, &params);
 
-                                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]