• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-websocket-extension.c
4  *
5  * Copyright (C) 2019 Igalia S.L.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Library General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Library General Public License for more details.
16  *
17  * You should have received a copy of the GNU Library General Public License
18  * along with this library; see the file COPYING.LIB.  If not, write to
19  * the Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
20  * Boston, MA 02110-1301, USA.
21  */
22 
23 #ifdef HAVE_CONFIG_H
24 #include <config.h>
25 #endif
26 
27 #include "soup-websocket-extension.h"
28 
29 /**
30  * SECTION:soup-websocket-extension
31  * @short_description: a WebSocket extension
32  * @see_also: #SoupSession, #SoupWebsocketExtensionManager
33  *
34  * SoupWebsocketExtension is the base class for WebSocket extension objects.
35  *
36  * Since: 2.68
37  */
38 
39 /**
40  * SoupWebsocketExtensionClass:
41  * @parent_class: the parent class
42  * @configure: called to configure the extension with the given parameters
43  * @get_request_params: called by the client to build the request header.
44  *    It should include the parameters string starting with ';'
45  * @get_response_params: called by the server to build the response header.
46  *    It should include the parameters string starting with ';'
47  * @process_outgoing_message: called to process the payload data of a message
48  *    before it's sent. Reserved bits of the header should be changed.
49  * @process_incoming_message: called to process the payload data of a message
50  *    after it's received. Reserved bits of the header should be cleared.
51  *
52  * The class structure for the SoupWebsocketExtension.
53  *
54  * Since: 2.68
55  */
56 
G_DEFINE_ABSTRACT_TYPE(SoupWebsocketExtension,soup_websocket_extension,G_TYPE_OBJECT)57 G_DEFINE_ABSTRACT_TYPE (SoupWebsocketExtension, soup_websocket_extension, G_TYPE_OBJECT)
58 
59 static void
60 soup_websocket_extension_init (SoupWebsocketExtension *extension)
61 {
62 }
63 
64 static void
soup_websocket_extension_class_init(SoupWebsocketExtensionClass * auth_class)65 soup_websocket_extension_class_init (SoupWebsocketExtensionClass *auth_class)
66 {
67 }
68 
69 /**
70  * soup_websocket_extension_configure:
71  * @extension: a #SoupWebsocketExtension
72  * @connection_type: either %SOUP_WEBSOCKET_CONNECTION_CLIENT or %SOUP_WEBSOCKET_CONNECTION_SERVER
73  * @params: (nullable): the parameters, or %NULL
74  * @error: return location for a #GError
75  *
76  * Configures @extension with the given @params
77  *
78  * Return value: %TRUE if extension could be configured with the given parameters, or %FALSE otherwise
79  */
80 gboolean
soup_websocket_extension_configure(SoupWebsocketExtension * extension,SoupWebsocketConnectionType connection_type,GHashTable * params,GError ** error)81 soup_websocket_extension_configure (SoupWebsocketExtension     *extension,
82 				    SoupWebsocketConnectionType connection_type,
83 				    GHashTable                 *params,
84 				    GError                    **error)
85 {
86 	SoupWebsocketExtensionClass *klass;
87 
88 	g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), FALSE);
89 	g_return_val_if_fail (connection_type != SOUP_WEBSOCKET_CONNECTION_UNKNOWN, FALSE);
90 	g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
91 
92 	klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
93 	if (!klass->configure)
94 		return TRUE;
95 
96 	return klass->configure (extension, connection_type, params, error);
97 }
98 
99 /**
100  * soup_websocket_extension_get_request_params:
101  * @extension: a #SoupWebsocketExtension
102  *
103  * Get the parameters strings to be included in the request header. If the extension
104  * doesn't include any parameter in the request, this function returns %NULL.
105  *
106  * Returns: (nullable) (transfer full): a new allocated string with the parameters
107  *
108  * Since: 2.68
109  */
110 char *
soup_websocket_extension_get_request_params(SoupWebsocketExtension * extension)111 soup_websocket_extension_get_request_params (SoupWebsocketExtension *extension)
112 {
113 	SoupWebsocketExtensionClass *klass;
114 
115         g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
116 
117 	klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
118         if (!klass->get_request_params)
119                 return NULL;
120 
121         return klass->get_request_params (extension);
122 }
123 
124 /**
125  * soup_websocket_extension_get_response_params:
126  * @extension: a #SoupWebsocketExtension
127  *
128  * Get the parameters strings to be included in the response header. If the extension
129  * doesn't include any parameter in the response, this function returns %NULL.
130  *
131  * Returns: (nullable) (transfer full): a new allocated string with the parameters
132  *
133  * Since: 2.68
134  */
135 char *
soup_websocket_extension_get_response_params(SoupWebsocketExtension * extension)136 soup_websocket_extension_get_response_params (SoupWebsocketExtension *extension)
137 {
138 	SoupWebsocketExtensionClass *klass;
139 
140 	g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
141 
142 	klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
143 	if (!klass->get_response_params)
144 		return NULL;
145 
146 	return klass->get_response_params (extension);
147 }
148 
149 /**
150  * soup_websocket_extension_process_outgoing_message:
151  * @extension: a #SoupWebsocketExtension
152  * @header: (inout): the message header
153  * @payload: (transfer full): the payload data
154  * @error: return location for a #GError
155  *
156  * Process a message before it's sent. If the payload isn't changed the given
157  * @payload is just returned, otherwise g_bytes_unref() is called on the given
158  * @payload and a new #GBytes is returned with the new data.
159  *
160  * Extensions using reserved bits of the header will change them in @header.
161  *
162  * Returns: (transfer full): the message payload data, or %NULL in case of error
163  *
164  * Since: 2.68
165  */
166 GBytes *
soup_websocket_extension_process_outgoing_message(SoupWebsocketExtension * extension,guint8 * header,GBytes * payload,GError ** error)167 soup_websocket_extension_process_outgoing_message (SoupWebsocketExtension *extension,
168 						   guint8                 *header,
169 						   GBytes                 *payload,
170 						   GError                **error)
171 {
172 	SoupWebsocketExtensionClass *klass;
173 
174         g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
175 	g_return_val_if_fail (header != NULL, NULL);
176 	g_return_val_if_fail (payload != NULL, NULL);
177 	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
178 
179         klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
180 	if (!klass->process_outgoing_message)
181 		return payload;
182 
183 	return klass->process_outgoing_message (extension, header, payload, error);
184 }
185 
186 /**
187  * soup_websocket_extension_process_incoming_message:
188  * @extension: a #SoupWebsocketExtension
189  * @header: (inout): the message header
190  * @payload: (transfer full): the payload data
191  * @error: return location for a #GError
192  *
193  * Process a message after it's received. If the payload isn't changed the given
194  * @payload is just returned, otherwise g_bytes_unref() is called on the given
195  * @payload and a new #GBytes is returned with the new data.
196  *
197  * Extensions using reserved bits of the header will reset them in @header.
198  *
199  * Returns: (transfer full): the message payload data, or %NULL in case of error
200  *
201  * Since: 2.68
202  */
203 GBytes *
soup_websocket_extension_process_incoming_message(SoupWebsocketExtension * extension,guint8 * header,GBytes * payload,GError ** error)204 soup_websocket_extension_process_incoming_message (SoupWebsocketExtension *extension,
205 						   guint8                 *header,
206 						   GBytes                 *payload,
207 						   GError                **error)
208 {
209 	SoupWebsocketExtensionClass *klass;
210 
211         g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
212 	g_return_val_if_fail (header != NULL, NULL);
213 	g_return_val_if_fail (payload != NULL, NULL);
214 	g_return_val_if_fail (error == NULL || *error == NULL, NULL);
215 
216         klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
217 	if (!klass->process_incoming_message)
218 		return payload;
219 
220 	return klass->process_incoming_message (extension, header, payload, error);
221 }
222