[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: Mon, 10 May 2021 18:17:25 +0000 (UTC)
commit de4d446d5b2af3a2ae2734e328c0e534b984661b
Author: Patrick Griffis <pgriffis igalia com>
Date: Mon May 10 13:17:22 2021 -0500
fixup! Add initial HTTP2 backend
libsoup/http2/soup-client-message-io-http2.c | 348 +++++++++++++++------------
libsoup/http2/soup-client-message-io-http2.h | 2 +-
libsoup/soup-client-message-io.c | 12 +-
libsoup/soup-connection.c | 40 ++-
tests/http2-test.c | 22 +-
5 files changed, 236 insertions(+), 188 deletions(-)
---
diff --git a/libsoup/http2/soup-client-message-io-http2.c b/libsoup/http2/soup-client-message-io-http2.c
index 5e50d8f1..613f5dc0 100644
--- a/libsoup/http2/soup-client-message-io-http2.c
+++ b/libsoup/http2/soup-client-message-io-http2.c
@@ -73,7 +73,7 @@ typedef struct {
nghttp2_session *session;
- // Owned by nghttp2
+ /* Owned by nghttp2 */
guint8 *write_buffer;
gssize write_buffer_size;
gssize written_bytes;
@@ -89,22 +89,22 @@ typedef struct {
GInputStream *decoded_data_istream;
GInputStream *memory_data_istream;
- // Request body logger
+ /* Request body logger */
SoupLogger *logger;
- // Both data sources
+ /* Both data sources */
GCancellable *data_source_cancellable;
- // Pollable data sources
+ /* Pollable data sources */
GSource *data_source_poll;
- // Non-pollable data sources
+ /* Non-pollable data sources */
GByteArray *data_source_buffer;
GError *data_source_error;
gboolean data_source_eof;
GSource *io_source;
- SoupMessageIOHTTP2 *io; // Unowned
+ SoupMessageIOHTTP2 *io; /* Unowned */
SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
SoupHTTP2IOState state;
@@ -112,7 +112,7 @@ typedef struct {
guint32 stream_id;
} SoupHTTP2MessageData;
-static void soup_message_io_http2_finished (SoupClientMessageIO *, SoupMessage *);
+static void soup_client_message_io_http2_finished (SoupClientMessageIO *, SoupMessage *);
static gboolean io_read_or_write (SoupMessageIOHTTP2 *, gboolean, GCancellable *, GError **);
static const char *
@@ -150,7 +150,10 @@ frame_type_to_string (nghttp2_frame_type type)
}
static void
-h2_debug (SoupMessageIOHTTP2 *io, SoupHTTP2MessageData *data, const char *format, ...)
+h2_debug (SoupMessageIOHTTP2 *io,
+ SoupHTTP2MessageData *data,
+ const char *format,
+ ...)
{
va_list args;
char *message;
@@ -185,14 +188,17 @@ get_data_io_priority (SoupHTTP2MessageData *data)
}
static void
-set_error_for_data (SoupMessageIOHTTP2 *io, SoupHTTP2MessageData *data, GError *error)
+set_error_for_data (SoupMessageIOHTTP2 *io,
+ SoupHTTP2MessageData *data,
+ GError *error)
{
g_debug ("set_error_for_data: %s", error->message);
g_hash_table_replace (io->message_errors, data, error);
}
static GError *
-get_error_for_data (SoupMessageIOHTTP2 *io, SoupHTTP2MessageData *data)
+get_error_for_data (SoupMessageIOHTTP2 *io,
+ SoupHTTP2MessageData *data)
{
GError *error = NULL;
@@ -204,7 +210,14 @@ get_error_for_data (SoupMessageIOHTTP2 *io, SoupHTTP2MessageData *data)
/* HTTP2 read callbacks */
static int
-on_header_callback (nghttp2_session *session, const nghttp2_frame *frame, const uint8_t *name, size_t
namelen, const uint8_t *value, size_t valuelen, uint8_t flags, void *user_data)
+on_header_callback (nghttp2_session *session,
+ const nghttp2_frame *frame,
+ const uint8_t *name,
+ size_t namelen,
+ const uint8_t *value,
+ size_t valuelen,
+ uint8_t flags,
+ void *user_data)
{
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, frame->hd.stream_id);
@@ -233,7 +246,10 @@ on_header_callback (nghttp2_session *session, const nghttp2_frame *frame, const
}
static GError *
-memory_stream_want_read_callback (SoupMemoryInputStream *stream, GCancellable *cancellable, gboolean
blocking, gpointer user_data)
+memory_stream_want_read_callback (SoupMemoryInputStream *stream,
+ GCancellable *cancellable,
+ gboolean blocking,
+ gpointer user_data)
{
SoupHTTP2MessageData *data = (SoupHTTP2MessageData*)user_data;
GError *error = NULL;
@@ -246,9 +262,10 @@ memory_stream_want_read_callback (SoupMemoryInputStream *stream, GCancellable *c
}
static int
-on_begin_frame_callback (nghttp2_session *session, const nghttp2_frame_hd *hd, void *user_data)
+on_begin_frame_callback (nghttp2_session *session,
+ const nghttp2_frame_hd *hd,
+ void *user_data)
{
- // SoupMessageIOHTTP2 *io = user_data;
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, hd->stream_id);
h2_debug (user_data, data, "[RECV] [%s] Beginning", frame_type_to_string (hd->type));
@@ -262,7 +279,7 @@ on_begin_frame_callback (nghttp2_session *session, const nghttp2_frame_hd *hd, v
data->state = STATE_READ_HEADERS;
break;
case NGHTTP2_DATA: {
- // We may have sniffed a previous DATA frame
+ /* We may have sniffed a previous DATA frame */
if (data->state < STATE_READ_DATA)
data->state = STATE_READ_DATA;
if (!data->memory_data_istream) {
@@ -281,7 +298,9 @@ on_begin_frame_callback (nghttp2_session *session, const nghttp2_frame_hd *hd, v
}
static void
-handle_goaway (SoupMessageIOHTTP2 *io, guint32 error_code, guint32 last_stream_id)
+handle_goaway (SoupMessageIOHTTP2 *io,
+ guint32 error_code,
+ guint32 last_stream_id)
{
GHashTableIter iter;
SoupHTTP2MessageData *data;
@@ -294,7 +313,7 @@ handle_goaway (SoupMessageIOHTTP2 *io, guint32 error_code, guint32 last_stream_i
data->state < STATE_READ_DONE) {
h2_debug (io, data, "[GOAWAY] Error: %s", nghttp2_http2_strerror (error_code));
data->state = STATE_ERROR;
- // TODO: We can restart unfinished messages
+ /* TODO: We can restart unfinished messages */
set_error_for_data (io, data, g_error_new (G_IO_ERROR, G_IO_ERROR_FAILED,
"HTTP/2 Error: %s", nghttp2_http2_strerror (error_code)));
}
@@ -302,7 +321,9 @@ handle_goaway (SoupMessageIOHTTP2 *io, guint32 error_code, guint32 last_stream_i
}
static int
-on_frame_recv_callback (nghttp2_session *session, const nghttp2_frame *frame, gpointer user_data)
+on_frame_recv_callback (nghttp2_session *session,
+ const nghttp2_frame *frame,
+ gpointer user_data)
{
SoupMessageIOHTTP2 *io = user_data;
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, frame->hd.stream_id);
@@ -361,16 +382,18 @@ on_frame_recv_callback (nghttp2_session *session, const nghttp2_frame *frame, gp
soup_memory_input_stream_complete (SOUP_MEMORY_INPUT_STREAM
(data->memory_data_istream));
soup_message_got_body (data->msg);
}
-
- // soup_message_io_http2_finished (data->msg);
- // nghttp2_submit_rst_stream (session, NGHTTP2_FLAG_NONE, frame->hd.stream_id,
NGHTTP2_STREAM_CLOSED);
}
return 0;
}
static int
-on_data_chunk_recv_callback (nghttp2_session *session, uint8_t flags, int32_t stream_id, const uint8_t
*data, size_t len, void *user_data)
+on_data_chunk_recv_callback (nghttp2_session *session,
+ uint8_t flags,
+ int32_t stream_id,
+ const uint8_t *data,
+ size_t len,
+ void *user_data)
{
SoupMessageIOHTTP2 *io = user_data;
SoupHTTP2MessageData *msgdata = nghttp2_session_get_stream_user_data (session, stream_id);
@@ -415,12 +438,12 @@ on_data_chunk_recv_callback (nghttp2_session *session, uint8_t flags, int32_t st
/* HTTP2 write callbacks */
static int
-on_before_frame_send_callback (nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
+on_before_frame_send_callback (nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *user_data)
{
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, frame->hd.stream_id);
- // h2_debug (user_data, data, "[SEND] [%s] Before", frame_type_to_string (frame->hd.type));
-
if (!data)
return 0;
@@ -437,7 +460,9 @@ on_before_frame_send_callback (nghttp2_session *session, const nghttp2_frame *fr
}
static int
-on_frame_send_callback (nghttp2_session *session, const nghttp2_frame *frame, void *user_data)
+on_frame_send_callback (nghttp2_session *session,
+ const nghttp2_frame *frame,
+ void *user_data)
{
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, frame->hd.stream_id);
@@ -484,11 +509,15 @@ on_frame_send_callback (nghttp2_session *session, const nghttp2_frame *frame, vo
}
static int
-on_frame_not_send_callback (nghttp2_session *session, const nghttp2_frame *frame, int lib_error_code, void
*user_data)
+on_frame_not_send_callback (nghttp2_session *session,
+ const nghttp2_frame *frame,
+ int lib_error_code,
+ void *user_data)
{
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, frame->hd.stream_id);
- h2_debug (user_data, data, "[SEND] [%s] Failed", frame_type_to_string (frame->hd.type));
+ h2_debug (user_data, data, "[SEND] [%s] Failed: %s", frame_type_to_string (frame->hd.type),
+ nghttp2_strerror (lib_error_code));
if (!data)
return 0;
@@ -499,14 +528,18 @@ on_frame_not_send_callback (nghttp2_session *session, const nghttp2_frame *frame
}
static int
-on_stream_close_callback (nghttp2_session *session, int32_t stream_id, uint32_t error_code, void *user_data)
+on_stream_close_callback (nghttp2_session *session,
+ int32_t stream_id,
+ uint32_t error_code,
+ void *user_data)
{
- g_debug ("on_stream_close %d", stream_id);
+ g_debug ("[%d] Stream Closed: %s", stream_id, nghttp2_http2_strerror (error_code));
return 0;
}
static gboolean
-on_data_readable (GInputStream *stream, gpointer user_data)
+on_data_readable (GInputStream *stream,
+ gpointer user_data)
{
SoupHTTP2MessageData *data = (SoupHTTP2MessageData*)user_data;
@@ -517,7 +550,9 @@ on_data_readable (GInputStream *stream, gpointer user_data)
}
static void
-on_data_read (GInputStream *source, GAsyncResult *res, gpointer user_data)
+on_data_read (GInputStream *source,
+ GAsyncResult *res,
+ gpointer user_data)
{
SoupHTTP2MessageData *data = user_data;
GError *error = NULL;
@@ -525,8 +560,8 @@ on_data_read (GInputStream *source, GAsyncResult *res, gpointer user_data)
g_debug ("[SEND_BODY] Read %zu", read);
- // This operation may have outlived the message data in which
- // case this will have been cancelled.
+ /* This operation may have outlived the message data in which
+ case this will have been cancelled. */
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
g_error_free (error);
return;
@@ -545,19 +580,27 @@ on_data_read (GInputStream *source, GAsyncResult *res, gpointer user_data)
}
static void
-log_request_data (SoupHTTP2MessageData *data, const guint8 *buffer, gsize len)
+log_request_data (SoupHTTP2MessageData *data,
+ const guint8 *buffer,
+ gsize len)
{
if (!data->logger)
return;
- // NOTE: This doesn't exactly log data as it hits the network but
- // rather as soon as we read it from our source which is as good
- // as we can do since nghttp handles the actual io.
+ /* NOTE: This doesn't exactly log data as it hits the network but
+ rather as soon as we read it from our source which is as good
+ as we can do since nghttp handles the actual io. */
soup_logger_log_request_data (data->logger, data->msg, (const char *)buffer, len);
}
static ssize_t
-on_data_source_read_callback (nghttp2_session *session, int32_t stream_id, uint8_t *buf, size_t length,
uint32_t *data_flags, nghttp2_data_source *source, void *user_data)
+on_data_source_read_callback (nghttp2_session *session,
+ int32_t stream_id,
+ uint8_t *buf,
+ size_t length,
+ uint32_t *data_flags,
+ nghttp2_data_source *source,
+ void *user_data)
{
SoupHTTP2MessageData *data = nghttp2_session_get_stream_user_data (session, stream_id);
SoupMessageIOHTTP2 *io = get_io_data (data->msg);
@@ -625,7 +668,7 @@ on_data_source_read_callback (nghttp2_session *session, int32_t stream_id, uint8
gsize buffer_len = data->data_source_buffer->len;
if (buffer_len) {
g_debug ("[SEND_BODY] Sending %zu", buffer_len);
- g_assert (buffer_len <= length); // QUESTION: Maybe not reliable
+ g_assert (buffer_len <= length); /* QUESTION: Maybe not reliable */
memcpy (buf, data->data_source_buffer->data, buffer_len);
log_request_data (data, buf, buffer_len);
g_byte_array_set_size (data->data_source_buffer, 0);
@@ -656,10 +699,10 @@ on_data_source_read_callback (nghttp2_session *session, int32_t stream_id, uint8
/* HTTP2 IO functions */
static SoupHTTP2MessageData *
-add_message_to_io_data (SoupMessageIOHTTP2 *io,
- SoupMessageQueueItem *item,
- SoupMessageIOCompletionFn completion_cb,
- gpointer completion_data)
+add_message_to_io_data (SoupMessageIOHTTP2 *io,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer completion_data)
{
SoupHTTP2MessageData *data = g_new0 (SoupHTTP2MessageData, 1);
@@ -669,7 +712,7 @@ add_message_to_io_data (SoupMessageIOHTTP2 *io,
data->cancellable = item->cancellable;
data->completion_cb = completion_cb;
data->completion_data = completion_data;
- data->stream_id = 0; // Will be overwritten
+ data->stream_id = 0;
data->io = io;
if (!g_hash_table_insert (io->messages, item->msg, data))
@@ -724,7 +767,9 @@ soup_http2_message_data_free (SoupHTTP2MessageData *data)
}
static void
-send_message_request (SoupMessage *msg, SoupMessageIOHTTP2 *io, SoupHTTP2MessageData *data)
+send_message_request (SoupMessage *msg,
+ SoupMessageIOHTTP2 *io,
+ SoupHTTP2MessageData *data)
{
GArray *headers = g_array_new (FALSE, FALSE, sizeof (nghttp2_nv));
@@ -786,10 +831,10 @@ send_message_request (SoupMessage *msg, SoupMessageIOHTTP2 *io, SoupHTTP2Message
static void
-soup_message_io_http2_send_item (SoupClientMessageIO *iface,
- SoupMessageQueueItem *item,
- SoupMessageIOCompletionFn completion_cb,
- gpointer user_data)
+soup_client_message_io_http2_send_item (SoupClientMessageIO *iface,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = add_message_to_io_data (io, item, completion_cb, user_data);
@@ -798,7 +843,8 @@ soup_message_io_http2_send_item (SoupClientMessageIO *iface,
}
static SoupHTTP2MessageData *
-get_data_for_message (SoupMessageIOHTTP2 *io, SoupMessage *msg)
+get_data_for_message (SoupMessageIOHTTP2 *io,
+ SoupMessage *msg)
{
SoupHTTP2MessageData *data = g_hash_table_lookup (io->messages, msg);
@@ -808,8 +854,8 @@ get_data_for_message (SoupMessageIOHTTP2 *io, SoupMessage *msg)
}
static void
-soup_message_io_http2_finished (SoupClientMessageIO *iface,
- SoupMessage *msg)
+soup_client_message_io_http2_finished (SoupClientMessageIO *iface,
+ SoupMessage *msg)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data;
@@ -844,13 +890,13 @@ soup_message_io_http2_finished (SoupClientMessageIO *iface,
}
static void
-soup_message_io_http2_pause (SoupClientMessageIO *iface,
- SoupMessage *msg)
+soup_client_message_io_http2_pause (SoupClientMessageIO *iface,
+ SoupMessage *msg)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
- g_debug ("soup_message_io_http2_pause");
+ g_debug ("soup_client_message_io_http2_pause");
if (data->paused)
g_warn_if_reached ();
@@ -859,13 +905,13 @@ soup_message_io_http2_pause (SoupClientMessageIO *iface,
}
static void
-soup_message_io_http2_unpause (SoupClientMessageIO *iface,
- SoupMessage *msg)
+soup_client_message_io_http2_unpause (SoupClientMessageIO *iface,
+ SoupMessage *msg)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
- g_debug ("soup_message_io_http2_unpause");
+ g_debug ("soup_client_message_io_http2_unpause");
if (!data->paused)
g_warn_if_reached ();
@@ -874,14 +920,14 @@ soup_message_io_http2_unpause (SoupClientMessageIO *iface,
}
static void
-soup_message_io_http2_stolen (SoupClientMessageIO *iface)
+soup_client_message_io_http2_stolen (SoupClientMessageIO *iface)
{
g_assert_not_reached ();
}
static gboolean
-soup_message_io_http2_in_progress (SoupClientMessageIO *iface,
- SoupMessage *msg)
+soup_client_message_io_http2_in_progress (SoupClientMessageIO *iface,
+ SoupMessage *msg)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
@@ -890,8 +936,8 @@ soup_message_io_http2_in_progress (SoupClientMessageIO *iface,
}
static gboolean
-soup_message_io_http2_is_paused (SoupClientMessageIO *iface,
- SoupMessage *msg)
+soup_client_message_io_http2_is_paused (SoupClientMessageIO *iface,
+ SoupMessage *msg)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
@@ -900,11 +946,11 @@ soup_message_io_http2_is_paused (SoupClientMessageIO *iface,
}
static gboolean
-soup_message_io_http2_is_reusable (SoupClientMessageIO *iface)
+soup_client_message_io_http2_is_reusable (SoupClientMessageIO *iface)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
- // TODO: This logic is probably incomplete
+ /* TODO: This logic is probably incomplete */
return !io->is_shutdown;
}
@@ -916,27 +962,22 @@ message_source_check (GSource *source)
SoupMessageIOHTTP2 *io = get_io_data (msg);
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
- //QUESTION: What is the point of message_source->paused
+ /* QUESTION: What is the point of message_source->paused */
return !data->paused;
}
static GSource *
-soup_message_io_http2_get_source (SoupMessage *msg,
- GCancellable *cancellable,
- SoupMessageIOSourceFunc callback,
- gpointer user_data)
+soup_client_message_io_http2_get_source (SoupMessage *msg,
+ GCancellable *cancellable,
+ SoupMessageIOSourceFunc callback,
+ gpointer user_data)
{
SoupMessageIOHTTP2 *io = get_io_data (msg);
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
- //GPollableInputStream *istream;
-
- //g_debug ("soup_message_io_http2_get_source state=%u, paused=%d", data->state, data->paused);
-
- //g_debug ("Queue %lu", nghttp2_session_get_outbound_queue_size (io->session));
-
GSource *base_source;
- // TODO: Handle mixing writes in
+
+ /* TODO: Handle mixing writes in? */
if (data->paused)
base_source = cancellable ? g_cancellable_source_new (cancellable) : NULL;
else if (data->state < STATE_WRITE_DONE)
@@ -952,13 +993,13 @@ soup_message_io_http2_get_source (SoupMessage *msg,
}
static void
-soup_message_io_http2_skip_body (SoupClientMessageIO *iface,
- SoupMessage *msg)
+soup_client_message_io_http2_skip_body (SoupClientMessageIO *iface,
+ SoupMessage *msg)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
- g_debug ("soup_message_io_http2_skip_body");
+ g_debug ("soup_client_message_io_http2_skip_body");
g_assert (data->memory_data_istream);
@@ -968,36 +1009,31 @@ soup_message_io_http2_skip_body (SoupClientMessageIO *iface,
}
static void
-client_stream_eof (SoupClientInputStream *stream, gpointer user_data)
+client_stream_eof (SoupClientInputStream *stream,
+ gpointer user_data)
{
SoupMessage *msg = user_data;
SoupMessageIOHTTP2 *io = get_io_data (msg);
if (!io) {
- g_warn_if_reached (); // QUESTION: Probably fine
+ g_warn_if_reached ();
return;
}
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
-
- g_debug ("client_stream_eof %d", SOUP_STATUS_IS_REDIRECTION (soup_message_get_status (data->msg)));
-
data->state = STATE_READ_DONE;
- // data->item->state = SOUP_MESSAGE_FINISHED;
- // soup_message_io_http2_finished (msg);
- // g_idle_add (idle_finish, msg); // TODO
}
static GInputStream *
-soup_message_io_http2_get_response_istream (SoupClientMessageIO *iface,
- SoupMessage *msg,
- GError **error)
+soup_client_message_io_http2_get_response_istream (SoupClientMessageIO *iface,
+ SoupMessage *msg,
+ GError **error)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
GInputStream *client_stream, *base_stream;
- g_debug ("soup_message_io_http2_get_response_istream paused=%d", data->paused);
+ g_debug ("soup_client_message_io_http2_get_response_istream paused=%d", data->paused);
if (data->decoded_data_istream)
base_stream = g_object_ref (data->decoded_data_istream);
@@ -1013,10 +1049,10 @@ soup_message_io_http2_get_response_istream (SoupClientMessageIO *iface,
}
static gboolean
-io_read (SoupMessageIOHTTP2 *io,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
+io_read (SoupMessageIOHTTP2 *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
guint8 buffer[8192];
gssize read;
@@ -1032,9 +1068,9 @@ io_read (SoupMessageIOHTTP2 *io,
static gboolean
io_write (SoupMessageIOHTTP2 *io,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
/* We must write all of nghttp2's buffer before we ask for more */
@@ -1064,23 +1100,23 @@ io_write (SoupMessageIOHTTP2 *io,
static gboolean
io_read_or_write (SoupMessageIOHTTP2 *io,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
- // TODO: This can possibly more inteligent about what actually needs
- // writing so we can prioritize better.
+ /* TODO: This can possibly more inteligent about what actually needs
+ writing so we can prioritize better. */
if (nghttp2_session_want_write (io->session))
return io_write (io, blocking, cancellable, error);
return io_read (io, blocking, cancellable, error);
}
static gboolean
-io_run_until (SoupMessage *msg,
- gboolean blocking,
- SoupHTTP2IOState state,
- GCancellable *cancellable,
- GError **error)
+io_run_until (SoupMessage *msg,
+ gboolean blocking,
+ SoupHTTP2IOState state,
+ GCancellable *cancellable,
+ GError **error)
{
SoupMessageIOHTTP2 *io = get_io_data (msg);
SoupHTTP2MessageData *data = get_data_for_message (io, msg);
@@ -1130,35 +1166,28 @@ io_run_until (SoupMessage *msg,
static gboolean
-soup_message_io_http2_run_until_read (SoupClientMessageIO *iface,
- SoupMessage *msg,
- GCancellable *cancellable,
- GError **error)
+soup_client_message_io_http2_run_until_read (SoupClientMessageIO *iface,
+ SoupMessage *msg,
+ GCancellable *cancellable,
+ GError **error)
{
- //SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
return io_run_until (msg, TRUE, STATE_READ_DATA, cancellable, error);
}
static gboolean
-soup_message_io_http2_run_until_finish (SoupClientMessageIO *iface,
- SoupMessage *msg,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
+soup_client_message_io_http2_run_until_finish (SoupClientMessageIO *iface,
+ SoupMessage *msg,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
{
-
- g_debug ("soup_message_io_http2_run_until_finish");
-
- //QUESTION: Prematurely end the stream, we don't need more than what we are getting
- //nghttp2_submit_rst_stream (io->session, NGHTTP2_FLAG_NONE, data->stream_id, NGHTTP2_STREAM_CLOSED);
-
return io_run_until (msg, blocking, STATE_READ_DONE, cancellable, error);
}
static void
-soup_message_io_http2_run (SoupClientMessageIO *iface,
- SoupMessage *msg,
- gboolean blocking)
+soup_client_message_io_http2_run (SoupClientMessageIO *iface,
+ SoupMessage *msg,
+ gboolean blocking)
{
g_assert_not_reached ();
}
@@ -1201,7 +1230,7 @@ io_run_until_read_async (SoupMessage *msg,
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
g_error_free (error);
- data->io_source = soup_message_io_http2_get_source (msg, g_task_get_cancellable (task),
+ data->io_source = soup_client_message_io_http2_get_source (msg, g_task_get_cancellable
(task),
(SoupMessageIOSourceFunc)io_run_until_read_ready,
task);
g_source_set_priority (data->io_source, g_task_get_priority (task));
@@ -1210,7 +1239,7 @@ io_run_until_read_async (SoupMessage *msg,
}
if (get_io_data (msg) == io)
- soup_message_io_http2_finished ((SoupClientMessageIO *)io, msg);
+ soup_client_message_io_http2_finished ((SoupClientMessageIO *)io, msg);
else
g_warn_if_reached ();
@@ -1219,12 +1248,12 @@ io_run_until_read_async (SoupMessage *msg,
}
static void
-soup_message_io_http2_run_until_read_async (SoupClientMessageIO *iface,
- SoupMessage *msg,
- int io_priority,
- GCancellable *cancellable,
- GAsyncReadyCallback callback,
- gpointer user_data)
+soup_client_message_io_http2_run_until_read_async (SoupClientMessageIO *iface,
+ SoupMessage *msg,
+ int io_priority,
+ GCancellable *cancellable,
+ GAsyncReadyCallback callback,
+ gpointer user_data)
{
GTask *task;
@@ -1234,7 +1263,7 @@ soup_message_io_http2_run_until_read_async (SoupClientMessageIO *iface,
}
static gboolean
-soup_message_io_http2_is_open (SoupClientMessageIO *iface)
+soup_client_message_io_http2_is_open (SoupClientMessageIO *iface)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
gboolean ret = TRUE;
@@ -1253,11 +1282,11 @@ soup_message_io_http2_is_open (SoupClientMessageIO *iface)
}
static void
-soup_message_io_http2_destroy (SoupClientMessageIO *iface)
+soup_client_message_io_http2_destroy (SoupClientMessageIO *iface)
{
SoupMessageIOHTTP2 *io = (SoupMessageIOHTTP2 *)iface;
- g_debug ("soup_message_io_http2_destroy");
+ g_debug ("soup_client_message_io_http2_destroy");
g_clear_object (&io->stream);
g_clear_pointer (&io->async_context, g_main_context_unref);
@@ -1269,29 +1298,28 @@ soup_message_io_http2_destroy (SoupClientMessageIO *iface)
}
static const SoupClientMessageIOFuncs io_funcs = {
- soup_message_io_http2_destroy,
- soup_message_io_http2_finished,
- soup_message_io_http2_stolen,
- soup_message_io_http2_send_item,
- soup_message_io_http2_get_response_istream,
- soup_message_io_http2_pause,
- soup_message_io_http2_unpause,
- soup_message_io_http2_is_paused,
- soup_message_io_http2_run,
- soup_message_io_http2_run_until_read,
- soup_message_io_http2_run_until_read_async,
- soup_message_io_http2_run_until_finish,
- soup_message_io_http2_in_progress,
- soup_message_io_http2_skip_body,
- soup_message_io_http2_is_open,
- soup_message_io_http2_is_reusable
- // soup_message_io_http2_get_source
+ soup_client_message_io_http2_destroy,
+ soup_client_message_io_http2_finished,
+ soup_client_message_io_http2_stolen,
+ soup_client_message_io_http2_send_item,
+ soup_client_message_io_http2_get_response_istream,
+ soup_client_message_io_http2_pause,
+ soup_client_message_io_http2_unpause,
+ soup_client_message_io_http2_is_paused,
+ soup_client_message_io_http2_run,
+ soup_client_message_io_http2_run_until_read,
+ soup_client_message_io_http2_run_until_read_async,
+ soup_client_message_io_http2_run_until_finish,
+ soup_client_message_io_http2_in_progress,
+ soup_client_message_io_http2_skip_body,
+ soup_client_message_io_http2_is_open,
+ soup_client_message_io_http2_is_reusable
};
static void
soup_client_message_io_http2_init (SoupMessageIOHTTP2 *io)
{
- // FIXME: Abort on out of memory errors
+ /* FIXME: Abort on out of memory errors */
nghttp2_session_callbacks *callbacks;
nghttp2_session_callbacks_new (&callbacks);
nghttp2_session_callbacks_set_on_header_callback (callbacks, on_header_callback);
@@ -1313,8 +1341,8 @@ soup_client_message_io_http2_init (SoupMessageIOHTTP2 *io)
io->iface.funcs = &io_funcs;
}
-#define INITIAL_WINDOW_SIZE (32 * 1024 * 1024) // 32MB matches other implementations
-#define MAX_HEADER_TABLE_SIZE 65536 // Match size used by Chromium/Firefox
+#define INITIAL_WINDOW_SIZE (32 * 1024 * 1024) /* 32MB matches other implementations */
+#define MAX_HEADER_TABLE_SIZE 65536 /* Match size used by Chromium/Firefox */
SoupClientMessageIO *
soup_client_message_io_http2_new (GIOStream *stream)
diff --git a/libsoup/http2/soup-client-message-io-http2.h b/libsoup/http2/soup-client-message-io-http2.h
index e96934ac..dc6b284b 100644
--- a/libsoup/http2/soup-client-message-io-http2.h
+++ b/libsoup/http2/soup-client-message-io-http2.h
@@ -9,6 +9,6 @@
G_BEGIN_DECLS
-SoupClientMessageIO * soup_client_message_io_http2_new (GIOStream *stream);
+SoupClientMessageIO *soup_client_message_io_http2_new (GIOStream *stream);
G_END_DECLS
diff --git a/libsoup/soup-client-message-io.c b/libsoup/soup-client-message-io.c
index 3537469d..97acdf17 100644
--- a/libsoup/soup-client-message-io.c
+++ b/libsoup/soup-client-message-io.c
@@ -108,27 +108,27 @@ soup_client_message_io_get_response_stream (SoupClientMessageIO *io,
}
gboolean
-soup_client_message_io_in_progress (SoupClientMessageIO *io,
- SoupMessage *msg)
+soup_client_message_io_in_progress (SoupClientMessageIO *io,
+ SoupMessage *msg)
{
return io->funcs->in_progress (io, msg);
}
gboolean
-soup_client_message_io_is_open (SoupClientMessageIO *io)
+soup_client_message_io_is_open (SoupClientMessageIO *io)
{
return io->funcs->is_open (io);
}
gboolean
-soup_client_message_io_is_reusable (SoupClientMessageIO *io)
+soup_client_message_io_is_reusable (SoupClientMessageIO *io)
{
return io->funcs->is_reusable (io);
}
void
-soup_client_message_io_skip_body (SoupClientMessageIO *io,
- SoupMessage *msg)
+soup_client_message_io_skip_body (SoupClientMessageIO *io,
+ SoupMessage *msg)
{
io->funcs->skip_body (io, msg);
}
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index 74c04b8c..a5f33934 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -392,9 +392,13 @@ set_current_msg (SoupConnection *conn, SoupMessage *msg)
* with keep-alive. With HTTP/2 we don't support proxying and
* we assume its reusable by default and detect a closed connection
* elsewhere */
- if (priv->http_version >= SOUP_HTTP_2_0) {
- priv->reusable = TRUE;
+ switch (priv->http_version) {
+ case SOUP_HTTP_1_0:
+ case SOUP_HTTP_1_1:
+ break;
+ case SOUP_HTTP_2_0:
// FIXME: stop_idle_timer() needs to be handled
+ priv->reusable = TRUE;
return;
}
@@ -592,7 +596,8 @@ soup_connection_complete (SoupConnection *conn)
priv->http_version = SOUP_HTTP_2_0;
else if (g_strcmp0 (protocol, "http/1.0") == 0)
priv->http_version = SOUP_HTTP_1_0;
- // Default is 1.1
+ else if (g_strcmp0 (protocol, "http/1.1") == 0)
+ priv->http_version = SOUP_HTTP_1_1;
}
if (!priv->ssl || !priv->proxy_uri) {
@@ -997,13 +1002,9 @@ is_idle_connection_disconnected (SoupConnection *conn)
if (priv->unused_timeout && priv->unused_timeout < time (NULL))
return TRUE;
- if (priv->http_version == SOUP_HTTP_2_0) {
- /* We need the HTTP2 backend to maintain its read state.
- * It does exactly what below does in practice */
- if (!priv->io_data)
- return TRUE;
- return !soup_client_message_io_is_open (priv->io_data);
- } else {
+ switch (priv->http_version) {
+ case SOUP_HTTP_1_0:
+ case SOUP_HTTP_1_1: {
GInputStream *istream = g_io_stream_get_input_stream (priv->iostream);
GError *error = NULL;
@@ -1025,9 +1026,17 @@ is_idle_connection_disconnected (SoupConnection *conn)
}
g_error_free (error);
+ return FALSE;
+ }
+ case SOUP_HTTP_2_0:
+ /* We need the HTTP2 backend to maintain its read state.
+ * It does exactly what above does in practice */
+ if (!priv->io_data)
+ return TRUE;
+ return !soup_client_message_io_is_open (priv->io_data);
}
- return FALSE;
+ return FALSE;
}
SoupConnectionState
@@ -1136,10 +1145,15 @@ soup_connection_message_io_finished (SoupConnection *conn,
{
SoupConnectionPrivate *priv = soup_connection_get_instance_private (conn);
- if (priv->http_version < SOUP_HTTP_2_0) {
- // FIXME: Leak
+ switch (priv->http_version) {
+ case SOUP_HTTP_1_0:
+ case SOUP_HTTP_1_1:
g_assert (priv->current_msg == msg);
g_clear_pointer (&priv->io_data, soup_client_message_io_destroy);
+ break;
+ case SOUP_HTTP_2_0:
+ /* SoupConnection retains ownership of io data */
+ break;
}
}
diff --git a/tests/http2-test.c b/tests/http2-test.c
index 5e60a564..09104ebb 100644
--- a/tests/http2-test.c
+++ b/tests/http2-test.c
@@ -36,11 +36,6 @@ setup_session (Test *test, gconstpointer data)
static void
teardown_session (Test *test, gconstpointer data)
{
- if (test->msg) {
- g_assert_cmpuint (soup_message_get_http_version (test->msg), ==, SOUP_HTTP_2_0);
- g_object_unref (test->msg);
- }
-
soup_test_session_abort_unref (test->session);
}
@@ -55,6 +50,7 @@ do_basic_async_test (Test *test, gconstpointer data)
g_assert_cmpstr (g_bytes_get_data (response, NULL), ==, "Hello world");
g_bytes_unref (response);
+ g_object_unref (test->msg);
}
static void
@@ -69,6 +65,7 @@ do_basic_sync_test (Test *test, gconstpointer data)
g_assert_cmpstr (g_bytes_get_data (response, NULL), ==, "Hello world");
g_bytes_unref (response);
+ g_object_unref (test->msg);
}
static void
@@ -84,6 +81,7 @@ do_no_content_async_test (Test *test, gconstpointer data)
g_assert_cmpuint (g_bytes_get_size (response), ==, 0);
g_bytes_unref (response);
+ g_object_unref (test->msg);
}
static void
@@ -96,10 +94,11 @@ do_large_async_test (Test *test, gconstpointer data)
GBytes *response = soup_test_session_async_send (test->session, test->msg, NULL, &error);
g_assert_no_error (error);
- // Size hardcoded to match http2-server.py's response
+ /* Size hardcoded to match http2-server.py's response */
g_assert_cmpuint (g_bytes_get_size (response), ==, (1024 * 24) + 1);
g_bytes_unref (response);
+ g_object_unref (test->msg);
}
static GBytes *
@@ -191,6 +190,7 @@ do_post_sync_test (Test *test, gconstpointer data)
g_bytes_unref (response_bytes);
g_object_unref (response);
g_bytes_unref (bytes);
+ g_object_unref (test->msg);
}
@@ -218,6 +218,7 @@ do_post_async_test (Test *test, gconstpointer data)
g_bytes_unref (response);
g_bytes_unref (bytes);
g_main_context_unref (async_context);
+ g_object_unref (test->msg);
}
static void
@@ -256,6 +257,7 @@ do_post_blocked_async_test (Test *test, gconstpointer data)
g_bytes_unref (response);
g_object_unref (in_stream);
g_main_context_unref (async_context);
+ g_object_unref (test->msg);
}
static void
@@ -285,6 +287,7 @@ do_post_file_async_test (Test *test, gconstpointer data)
g_object_unref (in_stream);
g_object_unref (in_file);
g_main_context_unref (async_context);
+ g_object_unref (test->msg);
}
static gboolean
@@ -318,6 +321,7 @@ do_paused_async_test (Test *test, gconstpointer data)
g_assert_cmpstr (g_bytes_get_data (response, NULL), ==, "Authenticated");
g_bytes_unref (response);
+ g_object_unref (test->msg);
}
static SoupConnection *last_connection;
@@ -398,6 +402,7 @@ do_misdirected_request_test (Test *test, gconstpointer data)
g_assert_cmpstr (g_bytes_get_data (response, NULL), ==, "Success!");
g_bytes_unref (response);
+ g_object_unref (test->msg);
}
static void
@@ -436,6 +441,7 @@ do_logging_test (Test *test, gconstpointer data)
g_assert_true (has_logged_body);
g_bytes_unref (response);
+ g_object_unref (test->msg);
}
static void
@@ -464,10 +470,10 @@ do_metrics_test (Test *test, gconstpointer data)
g_assert_cmpuint (soup_message_metrics_get_response_body_bytes_received (metrics), >,
soup_message_metrics_get_response_body_size (metrics));
g_bytes_unref (response);
- g_bytes_unref (bytes);
+ g_bytes_unref (bytes);
+ g_object_unref (test->msg);
}
-
int
main (int argc, char **argv)
{
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]