diff options
author | Ignacio Casal Quinteiro <icq@gnome.org> | 2016-08-17 09:17:49 +0200 |
---|---|---|
committer | Ignacio Casal Quinteiro <icq@gnome.org> | 2016-08-22 15:46:16 +0200 |
commit | 476e317219592ba15552097963d2042fd259f562 (patch) | |
tree | 949fc8b331323145ed75c9c0945ee86d05c21bdf | |
parent | cec6e7344c8eb407f8e75d4b39bddcc36457c5b8 (diff) | |
download | libsoup-476e317219592ba15552097963d2042fd259f562.tar.gz |
Add max-payload-size property to the websocket connection.wip/max-payload-size
This allows to change the limit for the payload of websocket packets.
Also add the corresponding unit test.
https://bugzilla.gnome.org/show_bug.cgi?id=770022
-rw-r--r-- | libsoup/soup-websocket-connection.c | 84 | ||||
-rw-r--r-- | libsoup/soup-websocket-connection.h | 7 | ||||
-rw-r--r-- | tests/websocket-test.c | 13 |
3 files changed, 100 insertions, 4 deletions
diff --git a/libsoup/soup-websocket-connection.c b/libsoup/soup-websocket-connection.c index 622aa689..0c767cb7 100644 --- a/libsoup/soup-websocket-connection.c +++ b/libsoup/soup-websocket-connection.c @@ -80,6 +80,7 @@ enum { PROP_ORIGIN, PROP_PROTOCOL, PROP_STATE, + PROP_MAX_PAYLOAD_SIZE, }; enum { @@ -105,6 +106,7 @@ struct _SoupWebsocketConnectionPrivate { SoupURI *uri; char *origin; char *protocol; + guint64 max_payload_size; gushort peer_close_code; char *peer_close_data; @@ -131,7 +133,7 @@ struct _SoupWebsocketConnectionPrivate { GByteArray *message_data; }; -#define MAX_PAYLOAD 128 * 1024 +#define MAX_PAYLOAD_SIZE_DEFAULT 128 * 1024 G_DEFINE_TYPE (SoupWebsocketConnection, soup_websocket_connection, G_TYPE_OBJECT) @@ -500,9 +502,9 @@ too_big_error_and_close (SoupWebsocketConnection *self, self->pv->connection_type == SOUP_WEBSOCKET_CONNECTION_SERVER ? "Received extremely large WebSocket data from the client" : "Received extremely large WebSocket data from the server"); - g_debug ("%s is trying to frame of size %" G_GUINT64_FORMAT " or greater, but max supported size is 128KiB", + g_debug ("%s is trying to frame of size %" G_GUINT64_FORMAT " or greater, but max supported size is %" G_GUINT64_FORMAT, self->pv->connection_type == SOUP_WEBSOCKET_CONNECTION_SERVER ? "server" : "client", - payload_len); + payload_len, self->pv->max_payload_size); emit_error_and_close (self, error, TRUE); /* The input is in an invalid state now */ @@ -728,7 +730,8 @@ process_frame (SoupWebsocketConnection *self) } /* Safety valve */ - if (payload_len >= MAX_PAYLOAD) { + if (self->pv->max_payload_size > 0 && + payload_len >= self->pv->max_payload_size) { too_big_error_and_close (self, payload_len); return FALSE; } @@ -963,6 +966,7 @@ soup_websocket_connection_get_property (GObject *object, GParamSpec *pspec) { SoupWebsocketConnection *self = SOUP_WEBSOCKET_CONNECTION (object); + SoupWebsocketConnectionPrivate *pv = self->pv; switch (prop_id) { case PROP_IO_STREAM: @@ -989,6 +993,10 @@ soup_websocket_connection_get_property (GObject *object, g_value_set_enum (value, soup_websocket_connection_get_state (self)); break; + case PROP_MAX_PAYLOAD_SIZE: + g_value_set_uint64 (value, pv->max_payload_size); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1029,6 +1037,10 @@ soup_websocket_connection_set_property (GObject *object, pv->protocol = g_value_dup_string (value); break; + case PROP_MAX_PAYLOAD_SIZE: + pv->max_payload_size = g_value_get_uint64 (value); + break; + default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -1197,6 +1209,24 @@ soup_websocket_connection_class_init (SoupWebsocketConnectionClass *klass) G_PARAM_STATIC_STRINGS)); /** + * SoupWebsocketConnection:max-payload-size: + * + * The maximum payload size the protocol expects or 0 to not limit it. + * + * Since: 2.56 + */ + g_object_class_install_property (gobject_class, PROP_MAX_PAYLOAD_SIZE, + g_param_spec_uint64 ("max-payload-size", + "Max payload size", + "Max payload size ", + 0, + G_MAXUINT64, + MAX_PAYLOAD_SIZE_DEFAULT, + G_PARAM_READWRITE | + G_PARAM_CONSTRUCT | + G_PARAM_STATIC_STRINGS)); + + /** * SoupWebsocketConnection::message: * @self: the WebSocket * @type: the type of message contents @@ -1569,3 +1599,49 @@ soup_websocket_connection_close (SoupWebsocketConnection *self, send_close (self, flags, code, data); close_io_after_timeout (self); } + +/** + * soup_websocket_connection_get_max_payload_size: + * @self: the WebSocket + * + * Gets the maximum payload size allowed for incoming packets. + * + * Returns: the maximum payload size. + * + * Since: 2.56 + */ +guint64 +soup_websocket_connection_get_max_payload_size (SoupWebsocketConnection *self) +{ + SoupWebsocketConnectionPrivate *pv; + + g_return_val_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self), MAX_PAYLOAD_SIZE_DEFAULT); + pv = self->pv; + + return pv->max_payload_size; +} + +/** + * soup_websocket_connection_set_max_payload_size: + * @self: the WebSocket + * @max_payload_size: the maximum payload size + * + * Sets the maximum payload size allowed for incoming packets. It + * does not limit the outgoing packet size. + * + * Since: 2.56 + */ +void +soup_websocket_connection_set_max_payload_size (SoupWebsocketConnection *self, + guint64 max_payload_size) +{ + SoupWebsocketConnectionPrivate *pv; + + g_return_if_fail (SOUP_IS_WEBSOCKET_CONNECTION (self)); + pv = self->pv; + + if (pv->max_payload_size != max_payload_size) { + pv->max_payload_size = max_payload_size; + g_object_notify (G_OBJECT (self), "max-payload-size"); + } +} diff --git a/libsoup/soup-websocket-connection.h b/libsoup/soup-websocket-connection.h index 515961b6..9bc56cd7 100644 --- a/libsoup/soup-websocket-connection.h +++ b/libsoup/soup-websocket-connection.h @@ -105,6 +105,13 @@ void soup_websocket_connection_close (SoupWebsocketConne gushort code, const char *data); +SOUP_AVAILABLE_IN_2_56 +guint64 soup_websocket_connection_get_max_payload_size (SoupWebsocketConnection *self); + +SOUP_AVAILABLE_IN_2_56 +void soup_websocket_connection_set_max_payload_size (SoupWebsocketConnection *self, + guint64 max_payload_size); + G_END_DECLS #endif /* __SOUP_WEBSOCKET_CONNECTION_H__ */ diff --git a/tests/websocket-test.c b/tests/websocket-test.c index eb74ea12..56cd1e13 100644 --- a/tests/websocket-test.c +++ b/tests/websocket-test.c @@ -380,6 +380,19 @@ test_send_big_packets (Test *test, g_assert (g_bytes_equal (sent, received)); g_bytes_unref (sent); g_bytes_unref (received); + received = NULL; + + soup_websocket_connection_set_max_payload_size (test->client, 1000 * 1000 + 1); + g_assert (soup_websocket_connection_get_max_payload_size (test->client) == (1000 * 1000 + 1)); + soup_websocket_connection_set_max_payload_size (test->server, 1000 * 1000 + 1); + g_assert (soup_websocket_connection_get_max_payload_size (test->server) == (1000 * 1000 + 1)); + + sent = g_bytes_new_take (g_strnfill (1000 * 1000, '?'), 1000 * 1000); + soup_websocket_connection_send_text (test->server, g_bytes_get_data (sent, NULL)); + WAIT_UNTIL (received != NULL); + g_assert (g_bytes_equal (sent, received)); + g_bytes_unref (sent); + g_bytes_unref (received); } static void |