Coverage Report

Created: 2025-07-18 06:25

/src/libsoup/libsoup/websocket/soup-websocket-extension.c
Line
Count
Source (jump to first uncovered line)
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; 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
 * SoupWebsocketExtension:
31
 *
32
 * A WebSocket extension
33
 *
34
 * [class@WebsocketExtension] is the base class for WebSocket extension objects.
35
 */
36
37
/**
38
 * SoupWebsocketExtensionClass:
39
 * @name: the name of the extension
40
 * @parent_class: the parent class
41
 * @configure: called to configure the extension with the given parameters
42
 * @get_request_params: called by the client to build the request header.
43
 *    It should include the parameters string starting with ';'
44
 * @get_response_params: called by the server to build the response header.
45
 *    It should include the parameters string starting with ';'
46
 * @process_outgoing_message: called to process the payload data of a message
47
 *    before it's sent. Reserved bits of the header should be changed.
48
 * @process_incoming_message: called to process the payload data of a message
49
 *    after it's received. Reserved bits of the header should be cleared.
50
 *
51
 * The class structure for the [class@WebsocketExtension].
52
 */
53
54
G_DEFINE_ABSTRACT_TYPE (SoupWebsocketExtension, soup_websocket_extension, G_TYPE_OBJECT)
55
56
static void
57
soup_websocket_extension_init (SoupWebsocketExtension *extension)
58
0
{
59
0
}
60
61
static void
62
soup_websocket_extension_class_init (SoupWebsocketExtensionClass *auth_class)
63
0
{
64
0
}
65
66
/**
67
 * soup_websocket_extension_configure:
68
 * @extension: a #SoupWebsocketExtension
69
 * @connection_type: either %SOUP_WEBSOCKET_CONNECTION_CLIENT or %SOUP_WEBSOCKET_CONNECTION_SERVER
70
 * @params: (nullable): the parameters
71
 * @error: return location for a #GError
72
 *
73
 * Configures @extension with the given @params.
74
 *
75
 * Returns: %TRUE if extension could be configured with the given parameters, or %FALSE otherwise
76
 */
77
gboolean
78
soup_websocket_extension_configure (SoupWebsocketExtension     *extension,
79
            SoupWebsocketConnectionType connection_type,
80
            GHashTable                 *params,
81
            GError                    **error)
82
0
{
83
0
  SoupWebsocketExtensionClass *klass;
84
85
0
  g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), FALSE);
86
0
  g_return_val_if_fail (connection_type != SOUP_WEBSOCKET_CONNECTION_UNKNOWN, FALSE);
87
0
  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
88
89
0
  klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
90
0
  if (!klass->configure)
91
0
    return TRUE;
92
93
0
  return klass->configure (extension, connection_type, params, error);
94
0
}
95
96
/**
97
 * soup_websocket_extension_get_request_params:
98
 * @extension: a #SoupWebsocketExtension
99
 *
100
 * Get the parameters strings to be included in the request header.
101
 *
102
 * If the extension doesn't include any parameter in the request, this function
103
 * returns %NULL.
104
 *
105
 * Returns: (nullable) (transfer full): a new allocated string with the parameters
106
 */
107
char *
108
soup_websocket_extension_get_request_params (SoupWebsocketExtension *extension)
109
0
{
110
0
  SoupWebsocketExtensionClass *klass;
111
112
0
        g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
113
114
0
  klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
115
0
        if (!klass->get_request_params)
116
0
                return NULL;
117
118
0
        return klass->get_request_params (extension);
119
0
}
120
121
/**
122
 * soup_websocket_extension_get_response_params:
123
 * @extension: a #SoupWebsocketExtension
124
 *
125
 * Get the parameters strings to be included in the response header.
126
 *
127
 * If the extension doesn't include any parameter in the response, this function
128
 * returns %NULL.
129
 *
130
 * Returns: (nullable) (transfer full): a new allocated string with the parameters
131
 */
132
char *
133
soup_websocket_extension_get_response_params (SoupWebsocketExtension *extension)
134
0
{
135
0
  SoupWebsocketExtensionClass *klass;
136
137
0
  g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
138
139
0
  klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
140
0
  if (!klass->get_response_params)
141
0
    return NULL;
142
143
0
  return klass->get_response_params (extension);
144
0
}
145
146
/**
147
 * soup_websocket_extension_process_outgoing_message:
148
 * @extension: a #SoupWebsocketExtension
149
 * @header: (inout): the message header
150
 * @payload: (transfer full): the payload data
151
 * @error: return location for a #GError
152
 *
153
 * Process a message before it's sent.
154
 *
155
 * If the payload isn't changed the given @payload is just returned, otherwise
156
 * [method@Glib.Bytes.unref] is called on the given @payload and a new
157
 * [struct@GLib.Bytes] is returned with the new data.
158
 *
159
 * Extensions using reserved bits of the header will change them in @header.
160
 *
161
 * Returns: (transfer full): the message payload data, or %NULL in case of error
162
 */
163
GBytes *
164
soup_websocket_extension_process_outgoing_message (SoupWebsocketExtension *extension,
165
               guint8                 *header,
166
               GBytes                 *payload,
167
               GError                **error)
168
0
{
169
0
  SoupWebsocketExtensionClass *klass;
170
171
0
        g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
172
0
  g_return_val_if_fail (header != NULL, NULL);
173
0
  g_return_val_if_fail (payload != NULL, NULL);
174
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
175
176
0
        klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
177
0
  if (!klass->process_outgoing_message)
178
0
    return payload;
179
180
0
  return klass->process_outgoing_message (extension, header, payload, error);
181
0
}
182
183
/**
184
 * soup_websocket_extension_process_incoming_message:
185
 * @extension: a #SoupWebsocketExtension
186
 * @header: (inout): the message header
187
 * @payload: (transfer full): the payload data
188
 * @error: return location for a #GError
189
 *
190
 * Process a message after it's received.
191
 *
192
 * If the payload isn't changed the given @payload is just returned, otherwise
193
 * [method@GLib.Bytes.unref] is called on the given @payload and a new
194
 * [struct@GLib.Bytes] is returned with the new data.
195
 *
196
 * Extensions using reserved bits of the header will reset them in @header.
197
 *
198
 * Returns: (transfer full): the message payload data, or %NULL in case of error
199
 */
200
GBytes *
201
soup_websocket_extension_process_incoming_message (SoupWebsocketExtension *extension,
202
               guint8                 *header,
203
               GBytes                 *payload,
204
               GError                **error)
205
0
{
206
0
  SoupWebsocketExtensionClass *klass;
207
208
0
        g_return_val_if_fail (SOUP_IS_WEBSOCKET_EXTENSION (extension), NULL);
209
0
  g_return_val_if_fail (header != NULL, NULL);
210
0
  g_return_val_if_fail (payload != NULL, NULL);
211
0
  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
212
213
0
        klass = SOUP_WEBSOCKET_EXTENSION_GET_CLASS (extension);
214
0
  if (!klass->process_incoming_message)
215
0
    return payload;
216
217
0
  return klass->process_incoming_message (extension, header, payload, error);
218
0
}