1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
|
/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
/*
* Copyright (C) 2000-2003, Ximian, Inc.
*/
#ifndef SOUP_MESSAGE_H
#define SOUP_MESSAGE_H 1
#include <libsoup/soup-types.h>
#include <libsoup/soup-method.h>
G_BEGIN_DECLS
#define SOUP_TYPE_MESSAGE (soup_message_get_type ())
#define SOUP_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SOUP_TYPE_MESSAGE, SoupMessage))
#define SOUP_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SOUP_TYPE_MESSAGE, SoupMessageClass))
#define SOUP_IS_MESSAGE(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SOUP_TYPE_MESSAGE))
#define SOUP_IS_MESSAGE_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((obj), SOUP_TYPE_MESSAGE))
#define SOUP_MESSAGE_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SOUP_TYPE_MESSAGE, SoupMessageClass))
/**
* SoupMessageStatus:
* @SOUP_MESSAGE_STATUS_IDLE: The message has not yet been queued.
* @SOUP_MESSAGE_STATUS_QUEUED: The message has been queued, but is
* waiting for a connection to be available.
* @SOUP_MESSAGE_STATUS_CONNECTING: The message is waiting for a
* specific connection to finish connecting.
* @SOUP_MESSAGE_STATUS_RUNNING: The message is being processed.
* @SOUP_MESSAGE_STATUS_FINISHED: The message is complete (request and
* response both processed).
*
* Enum indicating the lifecycle of a #SoupMessage.
**/
typedef enum {
SOUP_MESSAGE_STATUS_IDLE,
SOUP_MESSAGE_STATUS_QUEUED,
SOUP_MESSAGE_STATUS_CONNECTING,
SOUP_MESSAGE_STATUS_RUNNING,
SOUP_MESSAGE_STATUS_FINISHED
} SoupMessageStatus;
/**
* SOUP_MESSAGE_IS_STARTING:
* @msg: a #SoupMessage
*
* Tests if @msg is in a "starting" state, waiting to be sent. (More
* commonly used to test if a message has been requeued after its
* first attempt.)
*
* Return value: %TRUE if @msg is waiting to be sent.
**/
#define SOUP_MESSAGE_IS_STARTING(msg) (msg->status == SOUP_MESSAGE_STATUS_QUEUED || msg->status == SOUP_MESSAGE_STATUS_CONNECTING)
/**
* SoupTransferEncoding:
* @SOUP_TRANSFER_UNKNOWN: unknown / error
* @SOUP_TRANSFER_CHUNKED: chunked encoding (currently only supported
* for response)
* @SOUP_TRANSFER_CONTENT_LENGTH: Content-Length encoding
* @SOUP_TRANSFER_BYTERANGES: multipart/byteranges (Reserved for future
* use: NOT CURRENTLY IMPLEMENTED)
* @SOUP_TRANSFER_NONE: no body is present (which is not the same as a
* 0-length body, and only occurs in certain places)
* @SOUP_TRANSFER_EOF: Response body ends when the connection is closed
*
* How the length of a request or response is to be encoded.
**/
typedef enum {
SOUP_TRANSFER_UNKNOWN = 0,
SOUP_TRANSFER_CHUNKED,
SOUP_TRANSFER_CONTENT_LENGTH,
SOUP_TRANSFER_BYTERANGES,
SOUP_TRANSFER_NONE,
SOUP_TRANSFER_EOF
} SoupTransferEncoding;
/**
* SoupOwnership:
* @SOUP_BUFFER_SYSTEM_OWNED: The data is owned by soup and it can
* free it when it is done with it.
* @SOUP_BUFFER_USER_OWNED: The data is owned by the user, who is
* responsible for freeing it at the right point
* @SOUP_BUFFER_STATIC: The data should not be freed.
*
* Used by #SoupDataBuffer (and several functions) to indicate the
* ownership of a buffer.
**/
typedef enum {
SOUP_BUFFER_SYSTEM_OWNED = 0,
SOUP_BUFFER_USER_OWNED,
SOUP_BUFFER_STATIC
} SoupOwnership;
/**
* SoupDataBuffer:
* @owner: the ownership of the data
* @body: the data itself
* @length: length of @body
*
* A data buffer used in several places.
**/
typedef struct {
SoupOwnership owner;
char *body;
guint length;
} SoupDataBuffer;
/**
* SoupMessage:
* @method: the HTTP method
* @status_code: the HTTP status code
* @reason_phrase: the status phrase associated with @status_code
* @request: the request buffer
* @request_headers: the request headers
* @response: the response buffer
* @response_headers: the response headers
* @status: the processing status of the message
*
* Represents an HTTP message being sent or received.
**/
struct SoupMessage {
GObject parent;
/*< public >*/
const char *method;
guint status_code;
const char *reason_phrase;
SoupDataBuffer request;
GHashTable *request_headers;
SoupDataBuffer response;
GHashTable *response_headers;
SoupMessageStatus status;
};
typedef struct {
GObjectClass parent_class;
/* signals */
void (*wrote_informational) (SoupMessage *msg);
void (*wrote_headers) (SoupMessage *msg);
void (*wrote_chunk) (SoupMessage *msg);
void (*wrote_body) (SoupMessage *msg);
void (*got_informational) (SoupMessage *msg);
void (*got_headers) (SoupMessage *msg);
void (*got_chunk) (SoupMessage *msg);
void (*got_body) (SoupMessage *msg);
void (*restarted) (SoupMessage *msg);
void (*finished) (SoupMessage *msg);
} SoupMessageClass;
GType soup_message_get_type (void);
/**
* SoupMessageCallbackFn:
* @req: the #SoupMessage in question
* @user_data: user data
*
* A callback function used by many #SoupMessage methods.
**/
typedef void (*SoupMessageCallbackFn) (SoupMessage *req, gpointer user_data);
SoupMessage *soup_message_new (const char *method,
const char *uri_string);
SoupMessage *soup_message_new_from_uri (const char *method,
const SoupUri *uri);
void soup_message_set_request (SoupMessage *msg,
const char *content_type,
SoupOwnership req_owner,
char *req_body,
gulong req_length);
void soup_message_set_response (SoupMessage *msg,
const char *content_type,
SoupOwnership resp_owner,
char *resp_body,
gulong resp_length);
void soup_message_add_header (GHashTable *hash,
const char *name,
const char *value);
const char *soup_message_get_header (GHashTable *hash,
const char *name);
const GSList *soup_message_get_header_list (GHashTable *hash,
const char *name);
void soup_message_foreach_header (GHashTable *hash,
GHFunc func,
gpointer user_data);
void soup_message_remove_header (GHashTable *hash,
const char *name);
void soup_message_clear_headers (GHashTable *hash);
/**
* SoupHttpVersion:
* @SOUP_HTTP_1_0: HTTP 1.0 (RFC 1945)
* @SOUP_HTTP_1_1: HTTP 1.1 (RFC 2616)
*
* Indicates the HTTP protocol version being used.
**/
typedef enum {
SOUP_HTTP_1_0 = 0,
SOUP_HTTP_1_1 = 1
} SoupHttpVersion;
void soup_message_set_http_version (SoupMessage *msg,
SoupHttpVersion version);
SoupHttpVersion soup_message_get_http_version (SoupMessage *msg);
gboolean soup_message_is_keepalive (SoupMessage *msg);
const SoupUri *soup_message_get_uri (SoupMessage *msg);
void soup_message_set_uri (SoupMessage *msg,
const SoupUri *uri);
SoupTransferEncoding soup_message_get_request_encoding (SoupMessage *msg,
guint *content_length);
SoupTransferEncoding soup_message_get_response_encoding (SoupMessage *msg,
guint *content_length);
/**
* SoupMessageFlags:
* @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
* (3xx) responses received by this message.
* @SOUP_MESSAGE_OVERWRITE_CHUNKS: Rather than building up the
* response body in %response, each new chunk should overwrite the
* previous one. (This can be used if you are connecting to the
* %got_chunk signal or have installed a %SOUP_MESSAGE_BODY_CHUNK
* handler.
* @SOUP_MESSAGE_EXPECT_CONTINUE: This will cause an "Expect:
* 100-continue" header to be added to the outgoing request, giving
* the server the opportunity to reject the message (eg, with a 401
* Unauthorized) before the full request body is sent.
*
* Various flags that can be set on a #SoupMessage to alter its
* behavior.
**/
typedef enum {
SOUP_MESSAGE_NO_REDIRECT = (1 << 1),
SOUP_MESSAGE_OVERWRITE_CHUNKS = (1 << 3),
SOUP_MESSAGE_EXPECT_CONTINUE = (1 << 4)
} SoupMessageFlags;
void soup_message_set_flags (SoupMessage *msg,
guint flags);
guint soup_message_get_flags (SoupMessage *msg);
/*
* Handler Registration
*/
/**
* SoupHandlerPhase:
* @SOUP_HANDLER_POST_REQUEST: The handler should run immediately
* after sending the request body
* @SOUP_HANDLER_PRE_BODY: The handler should run before reading the
* response body (after reading the headers).
* @SOUP_HANDLER_BODY_CHUNK: The handler should run after every body
* chunk is read. (See also %SOUP_MESSAGE_OVERWRITE_CHUNKS.)
* @SOUP_HANDLER_POST_BODY: The handler should run after the entire
* message body has been read.
*
* Indicates when a handler added with soup_message_add_handler() or
* the like will be run.
**/
typedef enum {
SOUP_HANDLER_POST_REQUEST = 1,
SOUP_HANDLER_PRE_BODY,
SOUP_HANDLER_BODY_CHUNK,
SOUP_HANDLER_POST_BODY
} SoupHandlerPhase;
void soup_message_add_handler (SoupMessage *msg,
SoupHandlerPhase phase,
SoupMessageCallbackFn handler_cb,
gpointer user_data);
void soup_message_add_header_handler (SoupMessage *msg,
const char *header,
SoupHandlerPhase phase,
SoupMessageCallbackFn handler_cb,
gpointer user_data);
void soup_message_add_status_code_handler (
SoupMessage *msg,
guint status_code,
SoupHandlerPhase phase,
SoupMessageCallbackFn handler_cb,
gpointer user_data);
void soup_message_add_status_class_handler (
SoupMessage *msg,
SoupStatusClass status_class,
SoupHandlerPhase phase,
SoupMessageCallbackFn handler_cb,
gpointer user_data);
void soup_message_remove_handler (SoupMessage *msg,
SoupHandlerPhase phase,
SoupMessageCallbackFn handler_cb,
gpointer user_data);
/*
* Status Setting
*/
void soup_message_set_status (SoupMessage *msg,
guint status_code);
void soup_message_set_status_full (SoupMessage *msg,
guint status_code,
const char *reason_phrase);
/* Chunked encoding */
void soup_message_add_chunk (SoupMessage *msg,
SoupOwnership owner,
const char *body,
guint length);
void soup_message_add_final_chunk (SoupMessage *msg);
SoupDataBuffer*soup_message_pop_chunk (SoupMessage *msg);
/* I/O */
void soup_message_send_request (SoupMessage *req,
SoupSocket *sock,
gboolean is_via_proxy);
void soup_message_read_request (SoupMessage *req,
SoupSocket *sock);
void soup_message_io_stop (SoupMessage *msg);
void soup_message_io_pause (SoupMessage *msg);
void soup_message_io_unpause (SoupMessage *msg);
gboolean soup_message_io_in_progress (SoupMessage *msg);
void soup_message_wrote_informational (SoupMessage *msg);
void soup_message_wrote_headers (SoupMessage *msg);
void soup_message_wrote_chunk (SoupMessage *msg);
void soup_message_wrote_body (SoupMessage *msg);
void soup_message_got_informational (SoupMessage *msg);
void soup_message_got_headers (SoupMessage *msg);
void soup_message_got_chunk (SoupMessage *msg);
void soup_message_got_body (SoupMessage *msg);
void soup_message_restarted (SoupMessage *msg);
void soup_message_finished (SoupMessage *msg);
G_END_DECLS
#endif /*SOUP_MESSAGE_H*/
|