Coverage Report

Created: 2025-11-02 06:42

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/libsoup/libsoup/soup-message-metrics.c
Line
Count
Source
1
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 8 -*- */
2
/*
3
 * soup-message-metrics.c
4
 *
5
 * Copyright (C) 2021 Igalia S.L.
6
 */
7
8
#ifdef HAVE_CONFIG_H
9
#include <config.h>
10
#endif
11
12
#include "soup-message-metrics-private.h"
13
14
/**
15
 * SoupMessageMetrics:
16
 *
17
 * Contains metrics collected while loading a [class@Message] either from the
18
 * network or the disk cache.
19
 *
20
 * Metrics are not collected by default for a [class@Message], you need to add the
21
 * flag %SOUP_MESSAGE_COLLECT_METRICS to enable the feature.
22
 *
23
 * Temporal metrics are expressed as a monotonic time and always start with a
24
 * fetch start event and finish with response end. All other events are optional.
25
 * An event can be 0 because it hasn't happened yet, because it's optional or
26
 * because the load failed before the event reached.
27
 *
28
 * Size metrics are expressed in bytes and are updated while the [class@Message] is
29
 * being loaded. You can connect to different [class@Message] signals to get the
30
 * final result of every value.
31
 */
32
33
0
G_DEFINE_BOXED_TYPE (SoupMessageMetrics, soup_message_metrics, soup_message_metrics_copy, soup_message_metrics_free)
34
0
35
0
SoupMessageMetrics *
36
0
soup_message_metrics_new (void)
37
0
{
38
0
        return g_slice_new0 (SoupMessageMetrics);
39
0
}
40
41
/**
42
 * soup_message_metrics_copy:
43
 * @metrics: a #SoupMessageMetrics
44
 *
45
 * Copies @metrics.
46
 *
47
 * Returns: a copy of @metrics
48
 **/
49
SoupMessageMetrics *
50
soup_message_metrics_copy (SoupMessageMetrics *metrics)
51
0
{
52
0
        SoupMessageMetrics *copy;
53
54
0
        g_return_val_if_fail (metrics != NULL, NULL);
55
56
0
        copy = soup_message_metrics_new ();
57
0
        *copy = *metrics;
58
59
0
        return copy;
60
0
}
61
62
/**
63
 * soup_message_metrics_free:
64
 * @metrics: a #SoupMessageMetrics
65
 *
66
 * Frees @metrics.
67
 */
68
void
69
soup_message_metrics_free (SoupMessageMetrics *metrics)
70
0
{
71
0
        g_return_if_fail (metrics != NULL);
72
73
0
        g_slice_free (SoupMessageMetrics, metrics);
74
0
}
75
76
/**
77
 * soup_message_metrics_get_fetch_start:
78
 * @metrics: a #SoupMessageMetrics
79
 *
80
 * Get the time immediately before the [class@Message] started to
81
 * fetch a resource either from a remote server or local disk cache.
82
 *
83
 * Returns: the fetch start time
84
 */
85
guint64
86
soup_message_metrics_get_fetch_start (SoupMessageMetrics *metrics)
87
0
{
88
0
        g_return_val_if_fail (metrics != NULL, 0);
89
90
0
        return metrics->fetch_start;
91
0
}
92
93
/**
94
 * soup_message_metrics_get_dns_start:
95
 * @metrics: a #SoupMessageMetrics
96
 *
97
 * Get the time immediately before the [class@Message] started the
98
 * domain lookup name for the resource.
99
 *
100
 * It will be 0 if no domain lookup was required to fetch the resource (a
101
 * persistent connection was used or resource was loaded from the local disk
102
 * cache).
103
 *
104
 * Returns: the domain lookup start time
105
 */
106
guint64
107
soup_message_metrics_get_dns_start (SoupMessageMetrics *metrics)
108
0
{
109
0
        g_return_val_if_fail (metrics != NULL, 0);
110
111
0
        return metrics->dns_start;
112
0
}
113
114
/**
115
 * soup_message_metrics_get_dns_end:
116
 * @metrics: a #SoupMessageMetrics
117
 *
118
 * Get the time immediately after the [class@Message] completed the
119
 * domain lookup name for the resource.
120
 *
121
 * It will be 0 if no domain lookup was required to fetch the resource (a
122
 * persistent connection was used or resource was loaded from the local disk
123
 * cache).
124
 *
125
 * Returns: the domain lookup end time
126
 */
127
guint64
128
soup_message_metrics_get_dns_end (SoupMessageMetrics *metrics)
129
0
{
130
0
        g_return_val_if_fail (metrics != NULL, 0);
131
132
0
        return metrics->dns_end;
133
0
}
134
135
/**
136
 * soup_message_metrics_get_connect_start:
137
 * @metrics: a #SoupMessageMetrics
138
 *
139
 * Get the time immediately before the [class@Message] started to
140
 * establish the connection to the server.
141
 *
142
 * It will be 0 if no network connection was required to fetch the resource (a
143
 * persistent connection was used or resource was loaded from the local disk
144
 * cache).
145
 *
146
 * Returns: the connection start time
147
 */
148
guint64
149
soup_message_metrics_get_connect_start (SoupMessageMetrics *metrics)
150
0
{
151
0
        g_return_val_if_fail (metrics != NULL, 0);
152
153
0
        return metrics->connect_start;
154
0
}
155
156
/**
157
 * soup_message_metrics_get_connect_end:
158
 * @metrics: a #SoupMessageMetrics
159
 *
160
 * Get the time immediately after the [class@Message] completed the
161
 * connection to the server. This includes the time for the proxy
162
 * negotiation and TLS handshake.
163
 *
164
 * It will be 0 if no network connection was required to fetch the resource (a
165
 * persistent connection was used or resource was loaded from the local disk
166
 * cache).
167
 *
168
 * Returns: the connection end time
169
 */
170
guint64
171
soup_message_metrics_get_connect_end (SoupMessageMetrics *metrics)
172
0
{
173
0
        g_return_val_if_fail (metrics != NULL, 0);
174
175
0
        return metrics->connect_end;
176
0
}
177
178
/**
179
 * soup_message_metrics_get_tls_start:
180
 * @metrics: a #SoupMessageMetrics
181
 *
182
 * Get the time immediately before the [class@Message] started the
183
 * TLS handshake.
184
 *
185
 * It will be 0 if no TLS handshake was required to fetch the resource
186
 * (connection was not secure, a persistent connection was used or resource was
187
 * loaded from the local disk cache).
188
 *
189
 * Returns: the tls start time
190
 */
191
guint64
192
soup_message_metrics_get_tls_start (SoupMessageMetrics *metrics)
193
0
{
194
0
        g_return_val_if_fail (metrics != NULL, 0);
195
196
0
        return metrics->tls_start;
197
0
}
198
199
/**
200
 * soup_message_metrics_get_request_start:
201
 * @metrics: a #SoupMessageMetrics
202
 *
203
 * Get the time immediately before the [class@Message] started the
204
 * request of the resource from the server or the local disk cache.
205
 *
206
 * Returns: the request start time
207
 */
208
guint64
209
soup_message_metrics_get_request_start (SoupMessageMetrics *metrics)
210
0
{
211
0
        g_return_val_if_fail (metrics != NULL, 0);
212
213
0
        return metrics->request_start;
214
0
}
215
216
/**
217
 * soup_message_metrics_get_response_start:
218
 * @metrics: a #SoupMessageMetrics
219
 *
220
 * Get the time immediately after the [class@Message] received the first
221
 * bytes of the response from the server or the local disk cache.
222
 *
223
 * Returns: the response start time
224
 */
225
guint64
226
soup_message_metrics_get_response_start (SoupMessageMetrics *metrics)
227
0
{
228
0
        g_return_val_if_fail (metrics != NULL, 0);
229
230
0
        return metrics->response_start;
231
0
}
232
233
/**
234
 * soup_message_metrics_get_response_end:
235
 * @metrics: a #SoupMessageMetrics
236
 *
237
 * Get the time immediately after the [class@Message] received the last
238
 * bytes of the response from the server or the local disk cache.
239
 *
240
 * In case of load failure, this returns the time immediately before the
241
 * fetch is aborted.
242
 *
243
 * Returns: the response end time
244
 */
245
guint64
246
soup_message_metrics_get_response_end (SoupMessageMetrics *metrics)
247
0
{
248
0
        g_return_val_if_fail (metrics != NULL, 0);
249
250
0
        return metrics->response_end;
251
0
}
252
253
/**
254
 * soup_message_metrics_get_request_header_bytes_sent:
255
 * @metrics: a #SoupMessageMetrics
256
 *
257
 * Get the number of bytes sent to the network for the request headers.
258
 *
259
 * This value is available right before [signal@Message::wrote-headers] signal
260
 * is emitted, but you might get an intermediate value if called before.
261
 *
262
 * Returns: the request headers bytes sent
263
 */
264
guint64
265
soup_message_metrics_get_request_header_bytes_sent (SoupMessageMetrics *metrics)
266
0
{
267
0
        g_return_val_if_fail (metrics != NULL, 0);
268
269
0
        return metrics->request_header_bytes_sent;
270
0
}
271
272
/**
273
 * soup_message_metrics_get_request_body_size:
274
 * @metrics: a #SoupMessageMetrics
275
 *
276
 * Get the request body size in bytes. This is the size of the original body
277
 * given to the request before any encoding is applied.
278
 *
279
 * This value is available right before [signal@Message::wrote-body] signal is
280
 * emitted, but you might get an intermediate value if called before.
281
 *
282
 * Returns: the request body size
283
 */
284
guint64
285
soup_message_metrics_get_request_body_size (SoupMessageMetrics *metrics)
286
0
{
287
0
        g_return_val_if_fail (metrics != NULL, 0);
288
289
0
        return metrics->request_body_size;
290
0
}
291
292
/**
293
 * soup_message_metrics_get_request_body_bytes_sent:
294
 * @metrics: a #SoupMessageMetrics
295
 *
296
 * Get the number of bytes sent to the network for the request body.
297
 *
298
 * This is the size of the body sent, after encodings are applied, so it might
299
 * be greater than the value returned by
300
 * [method@MessageMetrics.get_request_body_size]. This value is available right
301
 * before [signal@Message::wrote-body] signal is emitted, but you might get an
302
 * intermediate value if called before.
303
 *
304
 * Returns: the request body bytes sent
305
 */
306
guint64
307
soup_message_metrics_get_request_body_bytes_sent (SoupMessageMetrics *metrics)
308
0
{
309
0
        g_return_val_if_fail (metrics != NULL, 0);
310
311
0
        return metrics->request_body_bytes_sent;
312
0
}
313
314
/**
315
 * soup_message_metrics_get_response_header_bytes_received:
316
 * @metrics: a #SoupMessageMetrics
317
 *
318
 * Get the number of bytes received from the network for the response headers.
319
 *
320
 * This value is available right before [signal@Message::got-headers] signal
321
 * is emitted, but you might get an intermediate value if called before.
322
 * For resources loaded from the disk cache this value is always 0.
323
 *
324
 * Returns: the response headers bytes received
325
 */
326
guint64
327
soup_message_metrics_get_response_header_bytes_received (SoupMessageMetrics *metrics)
328
0
{
329
0
        g_return_val_if_fail (metrics != NULL, 0);
330
331
0
        return metrics->response_header_bytes_received;
332
0
}
333
334
/**
335
 * soup_message_metrics_get_response_body_size:
336
 * @metrics: a #SoupMessageMetrics
337
 *
338
 * Get the response body size in bytes.
339
 *
340
 * This is the size of the body as given to the user after all encodings are
341
 * applied, so it might be greater than the value returned by
342
 * [method@MessageMetrics.get_response_body_bytes_received]. This value is
343
 * available right before [signal@Message::got-body] signal is emitted, but you
344
 * might get an intermediate value if called before.
345
 *
346
 * Returns: the response body size
347
 */
348
guint64
349
soup_message_metrics_get_response_body_size (SoupMessageMetrics *metrics)
350
0
{
351
0
        g_return_val_if_fail (metrics != NULL, 0);
352
353
0
        return metrics->response_body_size;
354
0
}
355
356
/**
357
 * soup_message_metrics_get_response_body_bytes_received:
358
 * @metrics: a #SoupMessageMetrics
359
 *
360
 * Get the number of bytes received from the network for the response body.
361
 *
362
 * This value is available right before [signal@Message::got-body] signal is
363
 * emitted, but you might get an intermediate value if called before. For
364
 * resources loaded from the disk cache this value is always 0.
365
 *
366
 * Returns: the response body bytes received
367
 */
368
guint64
369
soup_message_metrics_get_response_body_bytes_received (SoupMessageMetrics *metrics)
370
0
{
371
0
        g_return_val_if_fail (metrics != NULL, 0);
372
373
0
        return metrics->response_body_bytes_received;
374
0
}