summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorCarlos Garcia Campos <cgarcia@igalia.com>2020-10-09 11:29:11 +0200
committerCarlos Garcia Campos <cgarcia@igalia.com>2020-10-19 14:02:25 +0200
commit99c19cc27ae837e665ace3c1f0e99cd1088e6c24 (patch)
treebbb7f7a7a9c9544801c66cf3e543ee3ea93291be
parentd5cd7249b20beee01dc26c09ec80f270ef8962fd (diff)
downloadlibsoup-carlosgc/split-io.tar.gz
Split SoupMessage into client and server partscarlosgc/split-io
Add SoupServerMessage and move there all the server only functionality.
-rw-r--r--docs/reference/libsoup-3.0-docs.xml6
-rw-r--r--docs/reference/libsoup-3.0-sections.txt45
-rw-r--r--libsoup/meson.build3
-rw-r--r--libsoup/server/soup-auth-domain-basic.c27
-rw-r--r--libsoup/server/soup-auth-domain-basic.h10
-rw-r--r--libsoup/server/soup-auth-domain-digest.c31
-rw-r--r--libsoup/server/soup-auth-domain-digest.h8
-rw-r--r--libsoup/server/soup-auth-domain.c48
-rw-r--r--libsoup/server/soup-auth-domain.h46
-rw-r--r--libsoup/server/soup-server-io.c473
-rw-r--r--libsoup/server/soup-server-message-private.h50
-rw-r--r--libsoup/server/soup-server-message.c881
-rw-r--r--libsoup/server/soup-server-message.h79
-rw-r--r--libsoup/server/soup-server-private.h23
-rw-r--r--libsoup/server/soup-server.c625
-rw-r--r--libsoup/server/soup-server.h54
-rw-r--r--libsoup/soup-client-input-stream.c5
-rw-r--r--libsoup/soup-connection.c8
-rw-r--r--libsoup/soup-connection.h8
-rw-r--r--libsoup/soup-form.c26
-rw-r--r--libsoup/soup-form.h10
-rw-r--r--libsoup/soup-headers.c2
-rw-r--r--libsoup/soup-logger.c39
-rw-r--r--libsoup/soup-message-io-data.c266
-rw-r--r--libsoup/soup-message-io-data.h99
-rw-r--r--libsoup/soup-message-io.c468
-rw-r--r--libsoup/soup-message-private.h97
-rw-r--r--libsoup/soup-message.c427
-rw-r--r--libsoup/soup-message.h41
-rw-r--r--libsoup/soup-session.c9
-rw-r--r--libsoup/soup-status.c8
-rw-r--r--libsoup/soup-status.h5
-rw-r--r--libsoup/soup-types.h1
-rw-r--r--libsoup/soup.h1
-rw-r--r--libsoup/websocket/soup-websocket.c128
-rw-r--r--libsoup/websocket/soup-websocket.h34
-rw-r--r--tests/auth-test.c56
-rw-r--r--tests/cache-test.c51
-rw-r--r--tests/coding-test.c39
-rw-r--r--tests/connection-test.c60
-rw-r--r--tests/context-test.c33
-rw-r--r--tests/continue-test.c167
-rw-r--r--tests/cookies-test.c25
-rw-r--r--tests/forms-test.c88
-rw-r--r--tests/hsts-db-test.c25
-rw-r--r--tests/hsts-test.c49
-rw-r--r--tests/misc-test.c42
-rw-r--r--tests/multipart-test.c25
-rw-r--r--tests/no-ssl-test.c11
-rw-r--r--tests/ntlm-test.c42
-rw-r--r--tests/proxy-test.c12
-rw-r--r--tests/pull-api-test.c42
-rw-r--r--tests/range-test.c9
-rw-r--r--tests/redirect-test.c78
-rw-r--r--tests/request-body-test.c20
-rw-r--r--tests/server-auth-test.c55
-rw-r--r--tests/server-test.c188
-rw-r--r--tests/session-test.c11
-rw-r--r--tests/sniffing-test.c46
-rw-r--r--tests/ssl-test.c11
-rw-r--r--tests/streaming-test.c39
-rw-r--r--tests/timeout-test.c11
-rw-r--r--tests/websocket-test.c167
63 files changed, 3121 insertions, 2372 deletions
diff --git a/docs/reference/libsoup-3.0-docs.xml b/docs/reference/libsoup-3.0-docs.xml
index 479edf8c..adb0d12c 100644
--- a/docs/reference/libsoup-3.0-docs.xml
+++ b/docs/reference/libsoup-3.0-docs.xml
@@ -43,6 +43,12 @@
</chapter>
<chapter>
+ <title>HTTP Server</title>
+ <xi:include href="xml/soup-server.xml"/>
+ <xi:include href="xml/soup-server-message.xml"/>
+ </chapter>
+
+ <chapter>
<title>Additional Features</title>
<xi:include href="xml/soup-session-feature.xml"/>
<xi:include href="xml/soup-content-decoder.xml"/>
diff --git a/docs/reference/libsoup-3.0-sections.txt b/docs/reference/libsoup-3.0-sections.txt
index 4b1d56ac..64989b04 100644
--- a/docs/reference/libsoup-3.0-sections.txt
+++ b/docs/reference/libsoup-3.0-sections.txt
@@ -8,7 +8,6 @@ soup_message_new
soup_message_new_from_uri
soup_message_set_request_body
soup_message_set_request_body_from_bytes
-soup_message_set_response
<SUBSECTION>
SoupHTTPVersion
soup_message_set_http_version
@@ -18,7 +17,6 @@ soup_message_set_uri
<SUBSECTION>
soup_message_set_status
soup_message_set_status_full
-soup_message_set_redirect
soup_message_is_keepalive
soup_message_get_https_status
<SUBSECTION>
@@ -74,15 +72,12 @@ SOUP_IS_MESSAGE_CLASS
SOUP_MESSAGE_GET_CLASS
SoupMessageClass
<SUBSECTION Private>
-soup_message_wrote_informational
soup_message_wrote_headers
-soup_message_wrote_chunk
soup_message_wrote_body_data
soup_message_wrote_body
soup_message_got_informational
soup_message_got_headers
soup_message_content_sniffed
-soup_message_got_chunk
soup_message_got_body
soup_message_finished
soup_message_restarted
@@ -260,17 +255,6 @@ soup_server_add_websocket_handler
soup_server_add_websocket_extension
soup_server_remove_websocket_extension
<SUBSECTION>
-SoupClientContext
-soup_client_context_get_local_address
-soup_client_context_get_remote_address
-soup_client_context_get_host
-soup_client_context_get_auth_domain
-soup_client_context_get_auth_user
-soup_client_context_get_socket
-soup_client_context_steal_connection
-<SUBSECTION Private>
-soup_client_context_get_soup_socket
-<SUBSECTION>
soup_server_add_auth_domain
soup_server_remove_auth_domain
<SUBSECTION>
@@ -296,6 +280,35 @@ soup_client_context_get_type
</SECTION>
<SECTION>
+<FILE>soup-server-message</FILE>
+<TITLE>SoupServerMessage</TITLE>
+SoupServerMessage
+soup_server_message_get_request_headers
+soup_server_message_get_response_headers
+soup_server_message_get_request_body
+soup_server_message_get_response_body
+soup_server_message_get_method
+soup_server_message_get_http_version
+soup_server_message_set_http_version
+soup_server_message_get_status
+soup_server_message_set_status
+soup_server_message_get_uri
+soup_server_message_set_response
+soup_server_message_set_redirect
+soup_server_message_get_socket
+soup_server_message_get_local_address
+soup_server_message_get_remote_address
+soup_server_message_get_remote_host
+soup_server_message_steal_connection
+<SUBSECTION Standard>
+SOUP_SERVER_MESSAGE
+SOUP_IS_SERVER_MESSAGE
+SOUP_TYPE_SERVER_MESSAGE
+<SUBSECTION Private>
+soup_server_message_get_type
+</SECTION>
+
+<SECTION>
<FILE>soup-auth-domain</FILE>
<TITLE>SoupAuthDomain</TITLE>
SoupAuthDomain
diff --git a/libsoup/meson.build b/libsoup/meson.build
index c3a691d4..3a700870 100644
--- a/libsoup/meson.build
+++ b/libsoup/meson.build
@@ -44,6 +44,7 @@ soup_sources = [
'server/soup-path-map.c',
'server/soup-server.c',
'server/soup-server-io.c',
+ 'server/soup-server-message.c',
'websocket/soup-websocket.c',
'websocket/soup-websocket-connection.c',
@@ -67,6 +68,7 @@ soup_sources = [
'soup-message-body.c',
'soup-message-headers.c',
'soup-message-io.c',
+ 'soup-message-io-data.c',
'soup-message-queue.c',
'soup-method.c',
'soup-misc.c',
@@ -117,6 +119,7 @@ soup_introspection_headers = [
'server/soup-auth-domain-basic.h',
'server/soup-auth-domain-digest.h',
'server/soup-server.h',
+ 'server/soup-server-message.h',
'websocket/soup-websocket.h',
'websocket/soup-websocket-connection.h',
diff --git a/libsoup/server/soup-auth-domain-basic.c b/libsoup/server/soup-auth-domain-basic.c
index 9a850050..0cba37d2 100644
--- a/libsoup/server/soup-auth-domain-basic.c
+++ b/libsoup/server/soup-auth-domain-basic.c
@@ -204,8 +204,9 @@ pw_free (char *pw)
}
static gboolean
-parse_basic (SoupMessage *msg, const char *header,
- char **username, char **password)
+parse_basic (const char *header,
+ char **username,
+ char **password)
{
char *decoded, *colon;
gsize len, plen;
@@ -232,15 +233,16 @@ parse_basic (SoupMessage *msg, const char *header,
}
static char *
-soup_auth_domain_basic_accepts (SoupAuthDomain *domain, SoupMessage *msg,
- const char *header)
+soup_auth_domain_basic_accepts (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *header)
{
SoupAuthDomainBasicPrivate *priv =
soup_auth_domain_basic_get_instance_private (SOUP_AUTH_DOMAIN_BASIC (domain));
char *username, *password;
gboolean ok = FALSE;
- if (!parse_basic (msg, header, &username, &password))
+ if (!parse_basic (header, &username, &password))
return NULL;
if (priv->auth_callback) {
@@ -262,7 +264,8 @@ soup_auth_domain_basic_accepts (SoupAuthDomain *domain, SoupMessage *msg,
}
static char *
-soup_auth_domain_basic_challenge (SoupAuthDomain *domain, SoupMessage *msg)
+soup_auth_domain_basic_challenge (SoupAuthDomain *domain,
+ SoupServerMessage *msg)
{
GString *challenge;
@@ -272,18 +275,18 @@ soup_auth_domain_basic_challenge (SoupAuthDomain *domain, SoupMessage *msg)
}
static gboolean
-soup_auth_domain_basic_check_password (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username,
- const char *password)
+soup_auth_domain_basic_check_password (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username,
+ const char *password)
{
const char *header;
char *msg_username, *msg_password;
gboolean ok;
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (soup_server_message_get_request_headers (msg),
"Authorization");
- if (!parse_basic (msg, header, &msg_username, &msg_password))
+ if (!parse_basic (header, &msg_username, &msg_password))
return FALSE;
ok = (!strcmp (username, msg_username) &&
diff --git a/libsoup/server/soup-auth-domain-basic.h b/libsoup/server/soup-auth-domain-basic.h
index a260e891..d0397051 100644
--- a/libsoup/server/soup-auth-domain-basic.h
+++ b/libsoup/server/soup-auth-domain-basic.h
@@ -20,11 +20,11 @@ SOUP_AVAILABLE_IN_2_4
SoupAuthDomain *soup_auth_domain_basic_new (const char *optname1,
...) G_GNUC_NULL_TERMINATED;
-typedef gboolean (*SoupAuthDomainBasicAuthCallback) (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username,
- const char *password,
- gpointer user_data);
+typedef gboolean (*SoupAuthDomainBasicAuthCallback) (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username,
+ const char *password,
+ gpointer user_data);
SOUP_AVAILABLE_IN_2_4
void soup_auth_domain_basic_set_auth_callback (SoupAuthDomain *domain,
diff --git a/libsoup/server/soup-auth-domain-digest.c b/libsoup/server/soup-auth-domain-digest.c
index ae9fa266..1ad34a91 100644
--- a/libsoup/server/soup-auth-domain-digest.c
+++ b/libsoup/server/soup-auth-domain-digest.c
@@ -191,9 +191,11 @@ soup_auth_domain_digest_set_auth_callback (SoupAuthDomain *domain,
}
static gboolean
-check_hex_urp (SoupAuthDomain *domain, SoupMessage *msg,
- GHashTable *params, const char *username,
- const char *hex_urp)
+check_hex_urp (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ GHashTable *params,
+ const char *username,
+ const char *hex_urp)
{
const char *uri, *qop, *realm, *msg_username;
const char *nonce, *nc, *cnonce, *response;
@@ -210,7 +212,7 @@ check_hex_urp (SoupAuthDomain *domain, SoupMessage *msg,
if (!uri)
return FALSE;
- req_uri = soup_message_get_uri (msg);
+ req_uri = soup_server_message_get_uri (msg);
dig_uri = soup_uri_new (uri);
if (dig_uri) {
if (!soup_uri_equal (dig_uri, req_uri)) {
@@ -263,7 +265,8 @@ check_hex_urp (SoupAuthDomain *domain, SoupMessage *msg,
soup_auth_digest_compute_hex_a1 (hex_urp,
SOUP_AUTH_DIGEST_ALGORITHM_MD5,
nonce, cnonce, hex_a1);
- soup_auth_digest_compute_response (msg->method, uri,
+ soup_auth_digest_compute_response (soup_server_message_get_method (msg),
+ uri,
hex_a1,
SOUP_AUTH_DIGEST_QOP_AUTH,
nonce, cnonce, nonce_count,
@@ -272,8 +275,9 @@ check_hex_urp (SoupAuthDomain *domain, SoupMessage *msg,
}
static char *
-soup_auth_domain_digest_accepts (SoupAuthDomain *domain, SoupMessage *msg,
- const char *header)
+soup_auth_domain_digest_accepts (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *header)
{
SoupAuthDomainDigestPrivate *priv =
soup_auth_domain_digest_get_instance_private (SOUP_AUTH_DOMAIN_DIGEST (domain));
@@ -317,7 +321,8 @@ soup_auth_domain_digest_accepts (SoupAuthDomain *domain, SoupMessage *msg,
}
static char *
-soup_auth_domain_digest_challenge (SoupAuthDomain *domain, SoupMessage *msg)
+soup_auth_domain_digest_challenge (SoupAuthDomain *domain,
+ SoupServerMessage *msg)
{
GString *str;
@@ -366,10 +371,10 @@ soup_auth_domain_digest_encode_password (const char *username,
}
static gboolean
-soup_auth_domain_digest_check_password (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username,
- const char *password)
+soup_auth_domain_digest_check_password (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username,
+ const char *password)
{
const char *header;
GHashTable *params;
@@ -377,7 +382,7 @@ soup_auth_domain_digest_check_password (SoupAuthDomain *domain,
char hex_urp[33];
gboolean accept;
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (soup_server_message_get_request_headers (msg),
"Authorization");
if (!header || (strncmp (header, "Digest ", 7) != 0))
return FALSE;
diff --git a/libsoup/server/soup-auth-domain-digest.h b/libsoup/server/soup-auth-domain-digest.h
index 523497ce..c5630470 100644
--- a/libsoup/server/soup-auth-domain-digest.h
+++ b/libsoup/server/soup-auth-domain-digest.h
@@ -20,10 +20,10 @@ SOUP_AVAILABLE_IN_2_4
SoupAuthDomain *soup_auth_domain_digest_new (const char *optname1,
...) G_GNUC_NULL_TERMINATED;
-typedef char * (*SoupAuthDomainDigestAuthCallback) (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username,
- gpointer user_data);
+typedef char * (*SoupAuthDomainDigestAuthCallback) (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username,
+ gpointer user_data);
SOUP_AVAILABLE_IN_2_4
void soup_auth_domain_digest_set_auth_callback (SoupAuthDomain *domain,
diff --git a/libsoup/server/soup-auth-domain.c b/libsoup/server/soup-auth-domain.c
index 8785c474..f22cd9ea 100644
--- a/libsoup/server/soup-auth-domain.c
+++ b/libsoup/server/soup-auth-domain.c
@@ -364,7 +364,7 @@ soup_auth_domain_remove_path (SoupAuthDomain *domain, const char *path)
/**
* SoupAuthDomainFilter:
* @domain: a #SoupAuthDomain
- * @msg: a #SoupMessage
+ * @msg: a #SoupServerMessage
* @user_data: the data passed to soup_auth_domain_set_filter()
*
* The prototype for a #SoupAuthDomain filter; see
@@ -444,7 +444,7 @@ soup_auth_domain_get_realm (SoupAuthDomain *domain)
/**
* SoupAuthDomainGenericAuthCallback:
* @domain: a #SoupAuthDomain
- * @msg: the #SoupMessage being authenticated
+ * @msg: the #SoupServerMessage being authenticated
* @username: the username from @msg
* @user_data: the data passed to
* soup_auth_domain_set_generic_auth_callback()
@@ -504,9 +504,9 @@ soup_auth_domain_set_generic_auth_callback (SoupAuthDomain *domain,
}
gboolean
-soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username)
+soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username)
{
SoupAuthDomainPrivate *priv = soup_auth_domain_get_instance_private (domain);
@@ -519,7 +519,7 @@ soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
/**
* soup_auth_domain_check_password:
* @domain: a #SoupAuthDomain
- * @msg: a #SoupMessage
+ * @msg: a #SoupServerMessage
* @username: a username
* @password: a password
*
@@ -530,10 +530,10 @@ soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
* Return value: whether or not the message is authenticated
**/
gboolean
-soup_auth_domain_check_password (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username,
- const char *password)
+soup_auth_domain_check_password (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username,
+ const char *password)
{
return SOUP_AUTH_DOMAIN_GET_CLASS (domain)->check_password (domain, msg,
username,
@@ -543,7 +543,7 @@ soup_auth_domain_check_password (SoupAuthDomain *domain,
/**
* soup_auth_domain_covers:
* @domain: a #SoupAuthDomain
- * @msg: a #SoupMessage
+ * @msg: a #SoupServerMessage
*
* Checks if @domain requires @msg to be authenticated (according to
* its paths and filter function). This does not actually look at
@@ -556,13 +556,14 @@ soup_auth_domain_check_password (SoupAuthDomain *domain,
* Return value: %TRUE if @domain requires @msg to be authenticated
**/
gboolean
-soup_auth_domain_covers (SoupAuthDomain *domain, SoupMessage *msg)
+soup_auth_domain_covers (SoupAuthDomain *domain,
+ SoupServerMessage *msg)
{
SoupAuthDomainPrivate *priv = soup_auth_domain_get_instance_private (domain);
const char *path;
if (!priv->proxy) {
- path = soup_message_get_uri (msg)->path;
+ path = soup_server_message_get_uri (msg)->path;
if (!soup_path_map_lookup (priv->paths, path))
return FALSE;
}
@@ -576,7 +577,7 @@ soup_auth_domain_covers (SoupAuthDomain *domain, SoupMessage *msg)
/**
* soup_auth_domain_accepts:
* @domain: a #SoupAuthDomain
- * @msg: a #SoupMessage
+ * @msg: a #SoupServerMessage
*
* Checks if @msg contains appropriate authorization for @domain to
* accept it. Mirroring soup_auth_domain_covers(), this does not check
@@ -590,12 +591,13 @@ soup_auth_domain_covers (SoupAuthDomain *domain, SoupMessage *msg)
* as, if in fact it has authenticated. %NULL otherwise.
**/
char *
-soup_auth_domain_accepts (SoupAuthDomain *domain, SoupMessage *msg)
+soup_auth_domain_accepts (SoupAuthDomain *domain,
+ SoupServerMessage *msg)
{
SoupAuthDomainPrivate *priv = soup_auth_domain_get_instance_private (domain);
const char *header;
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (soup_server_message_get_request_headers (msg),
priv->proxy ?
"Proxy-Authorization" :
"Authorization");
@@ -607,7 +609,7 @@ soup_auth_domain_accepts (SoupAuthDomain *domain, SoupMessage *msg)
/**
* soup_auth_domain_challenge: (virtual challenge)
* @domain: a #SoupAuthDomain
- * @msg: a #SoupMessage
+ * @msg: a #SoupServerMessage
*
* Adds a "WWW-Authenticate" or "Proxy-Authenticate" header to @msg,
* requesting that the client authenticate, and sets @msg's status
@@ -617,16 +619,18 @@ soup_auth_domain_accepts (SoupAuthDomain *domain, SoupMessage *msg)
* anyone else.
**/
void
-soup_auth_domain_challenge (SoupAuthDomain *domain, SoupMessage *msg)
+soup_auth_domain_challenge (SoupAuthDomain *domain,
+ SoupServerMessage *msg)
{
SoupAuthDomainPrivate *priv = soup_auth_domain_get_instance_private (domain);
char *challenge;
challenge = SOUP_AUTH_DOMAIN_GET_CLASS (domain)->challenge (domain, msg);
- soup_message_set_status (msg, priv->proxy ?
- SOUP_STATUS_PROXY_UNAUTHORIZED :
- SOUP_STATUS_UNAUTHORIZED);
- soup_message_headers_append (msg->response_headers,
+ soup_server_message_set_status (msg, priv->proxy ?
+ SOUP_STATUS_PROXY_UNAUTHORIZED :
+ SOUP_STATUS_UNAUTHORIZED,
+ NULL);
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
priv->proxy ?
"Proxy-Authenticate" :
"WWW-Authenticate",
diff --git a/libsoup/server/soup-auth-domain.h b/libsoup/server/soup-auth-domain.h
index 397dc53b..c904d01b 100644
--- a/libsoup/server/soup-auth-domain.h
+++ b/libsoup/server/soup-auth-domain.h
@@ -16,15 +16,15 @@ G_DECLARE_DERIVABLE_TYPE (SoupAuthDomain, soup_auth_domain, SOUP, AUTH_DOMAIN, G
struct _SoupAuthDomainClass {
GObjectClass parent_class;
- char * (*accepts) (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *header);
- char * (*challenge) (SoupAuthDomain *domain,
- SoupMessage *msg);
- gboolean (*check_password) (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username,
- const char *password);
+ char * (*accepts) (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *header);
+ char * (*challenge) (SoupAuthDomain *domain,
+ SoupServerMessage *msg);
+ gboolean (*check_password) (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username,
+ const char *password);
gpointer padding[6];
};
@@ -37,14 +37,14 @@ struct _SoupAuthDomainClass {
#define SOUP_AUTH_DOMAIN_GENERIC_AUTH_CALLBACK "generic-auth-callback"
#define SOUP_AUTH_DOMAIN_GENERIC_AUTH_DATA "generic-auth-data"
-typedef gboolean (*SoupAuthDomainFilter) (SoupAuthDomain *domain,
- SoupMessage *msg,
- gpointer user_data);
+typedef gboolean (*SoupAuthDomainFilter) (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ gpointer user_data);
-typedef gboolean (*SoupAuthDomainGenericAuthCallback) (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username,
- gpointer user_data);
+typedef gboolean (*SoupAuthDomainGenericAuthCallback) (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username,
+ gpointer user_data);
SOUP_AVAILABLE_IN_2_4
void soup_auth_domain_add_path (SoupAuthDomain *domain,
@@ -69,24 +69,24 @@ void soup_auth_domain_set_generic_auth_callback (SoupAuthDomain *domain,
GDestroyNotify dnotify);
SOUP_AVAILABLE_IN_2_4
gboolean soup_auth_domain_check_password (SoupAuthDomain *domain,
- SoupMessage *msg,
+ SoupServerMessage *msg,
const char *username,
const char *password);
SOUP_AVAILABLE_IN_2_4
gboolean soup_auth_domain_covers (SoupAuthDomain *domain,
- SoupMessage *msg);
+ SoupServerMessage *msg);
SOUP_AVAILABLE_IN_2_4
char *soup_auth_domain_accepts (SoupAuthDomain *domain,
- SoupMessage *msg);
+ SoupServerMessage *msg);
SOUP_AVAILABLE_IN_2_4
void soup_auth_domain_challenge (SoupAuthDomain *domain,
- SoupMessage *msg);
+ SoupServerMessage *msg);
/* protected */
SOUP_AVAILABLE_IN_2_4
-gboolean soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
- SoupMessage *msg,
- const char *username);
+gboolean soup_auth_domain_try_generic_auth_callback (SoupAuthDomain *domain,
+ SoupServerMessage *msg,
+ const char *username);
G_END_DECLS
diff --git a/libsoup/server/soup-server-io.c b/libsoup/server/soup-server-io.c
index 4556635f..e94a366e 100644
--- a/libsoup/server/soup-server-io.c
+++ b/libsoup/server/soup-server-io.c
@@ -15,34 +15,115 @@
#include "soup-body-input-stream.h"
#include "soup-body-output-stream.h"
#include "soup-filter-input-stream.h"
-#include "soup-message-private.h"
+#include "soup-server-message-private.h"
#include "soup-misc.h"
#include "soup-socket-private.h"
+struct _SoupServerMessageIOData {
+ SoupMessageIOData base;
+
+ GBytes *write_chunk;
+ goffset write_body_offset;
+
+ GSource *unpause_source;
+};
+
#define RESPONSE_BLOCK_SIZE 8192
#define HEADER_SIZE_LIMIT (64 * 1024)
+void
+soup_server_message_io_data_free (SoupServerMessageIOData *io)
+{
+ if (!io)
+ return;
+
+ soup_message_io_data_cleanup (&io->base);
+
+ if (io->unpause_source) {
+ g_source_destroy (io->unpause_source);
+ g_source_unref (io->unpause_source);
+ io->unpause_source = NULL;
+ }
+
+ g_clear_pointer (&io->write_chunk, g_bytes_unref);
+
+ g_slice_free (SoupServerMessageIOData, io);
+}
+
+void
+soup_server_message_io_finished (SoupServerMessage *msg)
+{
+ SoupServerMessageIOData *io;
+ SoupMessageIOCompletionFn completion_cb;
+ gpointer completion_data;
+ SoupMessageIOCompletion completion;
+
+ io = soup_server_message_get_io_data (msg);
+ if (!io)
+ return;
+
+ completion_cb = io->base.completion_cb;
+ completion_data = io->base.completion_data;
+
+ if ((io->base.read_state >= SOUP_MESSAGE_IO_STATE_FINISHING &&
+ io->base.write_state >= SOUP_MESSAGE_IO_STATE_FINISHING))
+ completion = SOUP_MESSAGE_IO_COMPLETE;
+ else
+ completion = SOUP_MESSAGE_IO_INTERRUPTED;
+
+ g_object_ref (msg);
+ soup_server_message_set_io_data (msg, NULL);
+ if (completion_cb)
+ completion_cb (G_OBJECT (msg), completion, completion_data);
+ g_object_unref (msg);
+}
+
+GIOStream *
+soup_server_message_io_steal (SoupServerMessage *msg)
+{
+ SoupServerMessageIOData *io;
+ SoupMessageIOCompletionFn completion_cb;
+ gpointer completion_data;
+ GIOStream *iostream;
+
+ io = soup_server_message_get_io_data (msg);
+ if (!io || !io->base.iostream)
+ return NULL;
+
+ iostream = g_object_ref (io->base.iostream);
+ completion_cb = io->base.completion_cb;
+ completion_data = io->base.completion_data;
+
+ g_object_ref (msg);
+ soup_server_message_set_io_data (msg, NULL);
+ if (completion_cb)
+ completion_cb (G_OBJECT (msg), SOUP_MESSAGE_IO_STOLEN, completion_data);
+ g_object_unref (msg);
+
+ return iostream;
+}
+
static void
closed_async (GObject *source,
GAsyncResult *result,
gpointer user_data)
{
GOutputStream *body_ostream = G_OUTPUT_STREAM (source);
- SoupMessage *msg = user_data;
- SoupMessageIOData *io;
+ SoupServerMessage *msg = user_data;
+ SoupServerMessageIOData *io;
GCancellable *async_wait;
- io = soup_message_get_io_data (msg);
- if (!io || !io->async_wait || io->body_ostream != body_ostream) {
+ io = soup_server_message_get_io_data (msg);
+ if (!io || !io->base.async_wait || io->base.body_ostream != body_ostream) {
g_object_unref (msg);
return;
}
- g_output_stream_close_finish (body_ostream, result, &io->async_error);
- g_clear_object (&io->body_ostream);
+ g_output_stream_close_finish (body_ostream, result, &io->base.async_error);
+ g_clear_object (&io->base.body_ostream);
- async_wait = io->async_wait;
- io->async_wait = NULL;
+ async_wait = io->base.async_wait;
+ io->base.async_wait = NULL;
g_cancellable_cancel (async_wait);
g_object_unref (async_wait);
@@ -76,12 +157,19 @@ closed_async (GObject *source,
*/
static void
-handle_partial_get (SoupMessage *msg)
+handle_partial_get (SoupServerMessage *msg)
{
SoupRange *ranges;
int nranges;
GBytes *full_response;
guint status;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageBody *response_body;
+
+ request_headers = soup_server_message_get_request_headers (msg);
+ response_headers = soup_server_message_get_response_headers (msg);
+ response_body = soup_server_message_get_response_body (msg);
/* Make sure the message is set up right for us to return a
* partial response; it has to be a GET, the status must be
@@ -89,50 +177,50 @@ handle_partial_get (SoupMessage *msg)
* Content), and the SoupServer must have already filled in
* the response body
*/
- if (msg->method != SOUP_METHOD_GET ||
- msg->status_code != SOUP_STATUS_OK ||
- soup_message_headers_get_encoding (msg->response_headers) !=
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_GET ||
+ soup_server_message_get_status (msg, NULL) != SOUP_STATUS_OK ||
+ soup_message_headers_get_encoding (response_headers) !=
SOUP_ENCODING_CONTENT_LENGTH ||
- msg->response_body->length == 0 ||
- !soup_message_body_get_accumulate (msg->response_body))
+ response_body->length == 0 ||
+ !soup_message_body_get_accumulate (response_body))
return;
/* Oh, and there has to have been a valid Range header on the
* request, of course.
*/
- status = soup_message_headers_get_ranges_internal (msg->request_headers,
- msg->response_body->length,
+ status = soup_message_headers_get_ranges_internal (request_headers,
+ response_body->length,
TRUE,
&ranges, &nranges);
if (status == SOUP_STATUS_REQUESTED_RANGE_NOT_SATISFIABLE) {
- soup_message_set_status (msg, status);
- soup_message_body_truncate (msg->response_body);
+ soup_server_message_set_status (msg, status, NULL);
+ soup_message_body_truncate (response_body);
return;
} else if (status != SOUP_STATUS_PARTIAL_CONTENT)
return;
- full_response = soup_message_body_flatten (msg->response_body);
+ full_response = soup_message_body_flatten (response_body);
if (!full_response) {
- soup_message_headers_free_ranges (msg->request_headers, ranges);
+ soup_message_headers_free_ranges (request_headers, ranges);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_PARTIAL_CONTENT);
- soup_message_body_truncate (msg->response_body);
+ soup_server_message_set_status (msg, SOUP_STATUS_PARTIAL_CONTENT, NULL);
+ soup_message_body_truncate (response_body);
if (nranges == 1) {
GBytes *range_buf;
/* Single range, so just set Content-Range and fix the body. */
- soup_message_headers_set_content_range (msg->response_headers,
+ soup_message_headers_set_content_range (response_headers,
ranges[0].start,
ranges[0].end,
g_bytes_get_size (full_response));
range_buf = g_bytes_new_from_bytes (full_response,
ranges[0].start,
ranges[0].end - ranges[0].start + 1);
- soup_message_body_append_bytes (msg->response_body, range_buf);
+ soup_message_body_append_bytes (response_body, range_buf);
g_bytes_unref (range_buf);
} else {
SoupMultipart *multipart;
@@ -147,7 +235,7 @@ handle_partial_get (SoupMessage *msg)
*/
multipart = soup_multipart_new ("multipart/byteranges");
- content_type = soup_message_headers_get_one (msg->response_headers,
+ content_type = soup_message_headers_get_one (response_headers,
"Content-Type");
for (i = 0; i < nranges; i++) {
part_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART);
@@ -169,52 +257,62 @@ handle_partial_get (SoupMessage *msg)
g_bytes_unref (part_body);
}
- soup_multipart_to_message (multipart, msg->response_headers, &body);
- soup_message_body_append_bytes (msg->response_body, body);
+ soup_multipart_to_message (multipart, response_headers, &body);
+ soup_message_body_append_bytes (response_body, body);
g_bytes_unref (body);
soup_multipart_free (multipart);
}
g_bytes_unref (full_response);
- soup_message_headers_free_ranges (msg->request_headers, ranges);
+ soup_message_headers_free_ranges (request_headers, ranges);
}
static void
-write_headers (SoupMessage *msg,
- GString *headers,
- SoupEncoding *encoding)
+write_headers (SoupServerMessage *msg,
+ GString *headers,
+ SoupEncoding *encoding)
{
SoupEncoding claimed_encoding;
SoupMessageHeadersIter iter;
const char *name, *value;
+ guint status_code;
+ const char *reason_phrase;
+ const char *method;
+ SoupMessageHeaders *response_headers;
+ SoupMessageBody *response_body;
- if (msg->status_code == 0)
- soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ if (soup_server_message_get_status (msg, NULL) == 0)
+ soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, NULL);
handle_partial_get (msg);
+ status_code = soup_server_message_get_status (msg, &reason_phrase);
+
g_string_append_printf (headers, "HTTP/1.%c %d %s\r\n",
- soup_message_get_http_version (msg) == SOUP_HTTP_1_0 ? '0' : '1',
- msg->status_code, msg->reason_phrase);
-
- claimed_encoding = soup_message_headers_get_encoding (msg->response_headers);
- if ((msg->method == SOUP_METHOD_HEAD ||
- msg->status_code == SOUP_STATUS_NO_CONTENT ||
- msg->status_code == SOUP_STATUS_NOT_MODIFIED ||
- SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) ||
- (msg->method == SOUP_METHOD_CONNECT &&
- SOUP_STATUS_IS_SUCCESSFUL (msg->status_code)))
+ soup_server_message_get_http_version (msg) == SOUP_HTTP_1_0 ? '0' : '1',
+ status_code, reason_phrase);
+
+ method = soup_server_message_get_method (msg);
+ response_headers = soup_server_message_get_response_headers (msg);
+ claimed_encoding = soup_message_headers_get_encoding (response_headers);
+ if ((method == SOUP_METHOD_HEAD ||
+ status_code == SOUP_STATUS_NO_CONTENT ||
+ status_code == SOUP_STATUS_NOT_MODIFIED ||
+ SOUP_STATUS_IS_INFORMATIONAL (status_code)) ||
+ (method == SOUP_METHOD_CONNECT &&
+ SOUP_STATUS_IS_SUCCESSFUL (status_code)))
*encoding = SOUP_ENCODING_NONE;
else
*encoding = claimed_encoding;
+ response_body = soup_server_message_get_response_body (msg);
if (claimed_encoding == SOUP_ENCODING_CONTENT_LENGTH &&
- !soup_message_headers_get_content_length (msg->response_headers)) {
- soup_message_headers_set_content_length (msg->response_headers,
- msg->response_body->length);
+ !soup_message_headers_get_content_length (response_headers)) {
+ soup_message_headers_set_content_length (response_headers,
+ response_body->length);
}
- soup_message_headers_iter_init (&iter, msg->response_headers);
+ soup_message_headers_iter_init (&iter, response_headers);
while (soup_message_headers_iter_next (&iter, &name, &value))
g_string_append_printf (headers, "%s: %s\r\n", name, value);
g_string_append (headers, "\r\n");
@@ -227,13 +325,15 @@ write_headers (SoupMessage *msg,
* socket not writable, write is complete, etc).
*/
static gboolean
-io_write (SoupMessage *msg,
- GCancellable *cancellable,
- GError **error)
+io_write (SoupServerMessage *msg,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+ SoupMessageIOData *io = &server_io->base;
GBytes *chunk;
gssize nwrote;
+ guint status_code;
if (io->async_error) {
g_propagate_error (error, io->async_error);
@@ -248,11 +348,12 @@ io_write (SoupMessage *msg,
switch (io->write_state) {
case SOUP_MESSAGE_IO_STATE_HEADERS:
- if (io->read_state == SOUP_MESSAGE_IO_STATE_BLOCKING && msg->status_code == 0) {
+ status_code = soup_server_message_get_status (msg, NULL);
+ if (io->read_state == SOUP_MESSAGE_IO_STATE_BLOCKING && status_code == 0) {
/* Client requested "Expect: 100-continue", and
* server did not set an error.
*/
- soup_message_set_status (msg, SOUP_STATUS_CONTINUE);
+ soup_server_message_set_status (msg, SOUP_STATUS_CONTINUE, NULL);
}
if (!io->write_buf->len)
@@ -272,8 +373,9 @@ io_write (SoupMessage *msg,
io->written = 0;
g_string_truncate (io->write_buf, 0);
- if (SOUP_STATUS_IS_INFORMATIONAL (msg->status_code)) {
- if (msg->status_code == SOUP_STATUS_CONTINUE) {
+ status_code = soup_server_message_get_status (msg, NULL);
+ if (SOUP_STATUS_IS_INFORMATIONAL (status_code)) {
+ if (status_code == SOUP_STATUS_CONTINUE) {
/* Stop and wait for the body now */
io->write_state =
SOUP_MESSAGE_IO_STATE_BLOCKING;
@@ -288,20 +390,20 @@ io_write (SoupMessage *msg,
*/
}
- soup_message_wrote_informational (msg);
+ soup_server_message_wrote_informational (msg);
/* If this was "101 Switching Protocols", then
* the server probably stole the connection...
*/
- if (io != soup_message_get_io_data (msg))
+ if (server_io != soup_server_message_get_io_data (msg))
return FALSE;
- soup_message_cleanup_response (msg);
+ soup_server_message_cleanup_response (msg);
break;
}
if (io->write_encoding == SOUP_ENCODING_CONTENT_LENGTH)
- io->write_length = soup_message_headers_get_content_length (msg->response_headers);
+ io->write_length = soup_message_headers_get_content_length (soup_server_message_get_response_headers (msg));
io->write_state = SOUP_MESSAGE_IO_STATE_BODY_START;
/* If the client was waiting for a Continue
@@ -311,7 +413,7 @@ io_write (SoupMessage *msg,
if (io->read_state == SOUP_MESSAGE_IO_STATE_BLOCKING)
io->read_state = SOUP_MESSAGE_IO_STATE_DONE;
- soup_message_wrote_headers (msg);
+ soup_server_message_wrote_headers (msg);
break;
case SOUP_MESSAGE_IO_STATE_BODY_START:
@@ -329,51 +431,53 @@ io_write (SoupMessage *msg,
break;
}
- if (!io->write_chunk) {
- io->write_chunk = soup_message_body_get_chunk (msg->response_body, io->write_body_offset);
- if (!io->write_chunk) {
- soup_message_io_pause (msg);
+ if (!server_io->write_chunk) {
+ server_io->write_chunk = soup_message_body_get_chunk (soup_server_message_get_response_body (msg),
+ server_io->write_body_offset);
+ if (!server_io->write_chunk) {
+ soup_server_message_io_pause (msg);
return FALSE;
}
- if (!g_bytes_get_size (io->write_chunk)) {
+ if (!g_bytes_get_size (server_io->write_chunk)) {
io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH;
break;
}
}
nwrote = g_pollable_stream_write (io->body_ostream,
- (guchar*)g_bytes_get_data (io->write_chunk, NULL) + io->written,
- g_bytes_get_size (io->write_chunk) - io->written,
+ (guchar*)g_bytes_get_data (server_io->write_chunk, NULL) + io->written,
+ g_bytes_get_size (server_io->write_chunk) - io->written,
FALSE,
cancellable, error);
if (nwrote == -1)
return FALSE;
- chunk = g_bytes_new_from_bytes (io->write_chunk, io->written, nwrote);
+ chunk = g_bytes_new_from_bytes (server_io->write_chunk, io->written, nwrote);
io->written += nwrote;
if (io->write_length)
io->write_length -= nwrote;
- if (io->written == g_bytes_get_size (io->write_chunk))
+ if (io->written == g_bytes_get_size (server_io->write_chunk))
io->write_state = SOUP_MESSAGE_IO_STATE_BODY_DATA;
- soup_message_wrote_body_data (msg, chunk);
+ soup_server_message_wrote_body_data (msg, g_bytes_get_size (chunk));
g_bytes_unref (chunk);
break;
case SOUP_MESSAGE_IO_STATE_BODY_DATA:
io->written = 0;
- if (g_bytes_get_size (io->write_chunk) == 0) {
+ if (g_bytes_get_size (server_io->write_chunk) == 0) {
io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH;
break;
}
- soup_message_body_wrote_chunk (msg->response_body, io->write_chunk);
- io->write_body_offset += g_bytes_get_size (io->write_chunk);
- g_clear_pointer (&io->write_chunk, g_bytes_unref);
+ soup_message_body_wrote_chunk (soup_server_message_get_response_body (msg),
+ server_io->write_chunk);
+ server_io->write_body_offset += g_bytes_get_size (server_io->write_chunk);
+ g_clear_pointer (&server_io->write_chunk, g_bytes_unref);
io->write_state = SOUP_MESSAGE_IO_STATE_BODY;
- soup_message_wrote_chunk (msg);
+ soup_server_message_wrote_chunk (msg);
break;
case SOUP_MESSAGE_IO_STATE_BODY_FLUSH:
@@ -397,7 +501,7 @@ io_write (SoupMessage *msg,
case SOUP_MESSAGE_IO_STATE_BODY_DONE:
io->write_state = SOUP_MESSAGE_IO_STATE_FINISHING;
- soup_message_wrote_body (msg);
+ soup_server_message_wrote_body (msg);
break;
case SOUP_MESSAGE_IO_STATE_FINISHING:
@@ -435,55 +539,52 @@ parse_connect_authority (const char *req_path)
}
static guint
-parse_headers (SoupMessage *msg,
- char *headers,
- guint headers_len,
- SoupEncoding *encoding,
- SoupSocket *sock,
- GError **error)
+parse_headers (SoupServerMessage *msg,
+ char *headers,
+ guint headers_len,
+ SoupEncoding *encoding,
+ GError **error)
{
char *req_method, *req_path, *url;
SoupHTTPVersion version;
+ SoupSocket *sock;
const char *req_host;
guint status;
SoupURI *uri;
+ SoupMessageHeaders *request_headers;
+
+ request_headers = soup_server_message_get_request_headers (msg);
status = soup_headers_parse_request (headers, headers_len,
- msg->request_headers,
+ request_headers,
&req_method,
&req_path,
&version);
- if (!SOUP_STATUS_IS_SUCCESSFUL (status)) {
- if (status == SOUP_STATUS_MALFORMED) {
- g_set_error_literal (error, SOUP_REQUEST_ERROR,
- SOUP_REQUEST_ERROR_PARSING,
- _("Could not parse HTTP request"));
- }
+ if (!SOUP_STATUS_IS_SUCCESSFUL (status))
return status;
- }
- g_object_set (G_OBJECT (msg),
- SOUP_MESSAGE_METHOD, req_method,
- SOUP_MESSAGE_HTTP_VERSION, version,
- NULL);
+ soup_server_message_set_method (msg, req_method);
+ soup_server_message_set_http_version (msg, version);
g_free (req_method);
/* Handle request body encoding */
- *encoding = soup_message_headers_get_encoding (msg->request_headers);
+ *encoding = soup_message_headers_get_encoding (request_headers);
if (*encoding == SOUP_ENCODING_UNRECOGNIZED) {
- if (soup_message_headers_get_list (msg->request_headers, "Transfer-Encoding"))
+ if (soup_message_headers_get_list (request_headers, "Transfer-Encoding"))
return SOUP_STATUS_NOT_IMPLEMENTED;
else
return SOUP_STATUS_BAD_REQUEST;
}
/* Generate correct context for request */
- req_host = soup_message_headers_get_one (msg->request_headers, "Host");
+ req_host = soup_message_headers_get_one (request_headers, "Host");
if (req_host && strchr (req_host, '/')) {
g_free (req_path);
return SOUP_STATUS_BAD_REQUEST;
}
+ sock = soup_server_message_get_soup_socket (msg);
+
if (!strcmp (req_path, "*") && req_host) {
/* Eg, "OPTIONS * HTTP/1.1" */
url = g_strdup_printf ("%s://%s",
@@ -493,7 +594,7 @@ parse_headers (SoupMessage *msg,
if (uri)
soup_uri_set_path (uri, "*");
g_free (url);
- } else if (msg->method == SOUP_METHOD_CONNECT) {
+ } else if (soup_server_message_get_method (msg) == SOUP_METHOD_CONNECT) {
/* Authority */
uri = parse_connect_authority (req_path);
} else if (*req_path != '/') {
@@ -505,7 +606,7 @@ parse_headers (SoupMessage *msg,
req_host, req_path);
uri = soup_uri_new (url);
g_free (url);
- } else if (soup_message_get_http_version (msg) == SOUP_HTTP_1_0) {
+ } else if (soup_server_message_get_http_version (msg) == SOUP_HTTP_1_0) {
/* No Host header, no AbsoluteUri */
GInetSocketAddress *addr = soup_socket_get_local_address (sock);
GInetAddress *inet_addr = g_inet_socket_address_get_address (addr);
@@ -530,7 +631,7 @@ parse_headers (SoupMessage *msg,
return SOUP_STATUS_BAD_REQUEST;
}
- soup_message_set_uri (msg, uri);
+ soup_server_message_set_uri (msg, uri);
soup_uri_free (uri);
return SOUP_STATUS_OK;
@@ -543,27 +644,33 @@ parse_headers (SoupMessage *msg,
* socket not readable, read is complete, etc).
*/
static gboolean
-io_read (SoupMessage *msg,
- GCancellable *cancellable,
- GError **error)
+io_read (SoupServerMessage *msg,
+ GCancellable *cancellable,
+ GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+ SoupMessageIOData *io = &server_io->base;
gssize nread;
guint status;
+ SoupMessageHeaders *request_headers;
switch (io->read_state) {
case SOUP_MESSAGE_IO_STATE_HEADERS:
- if (!soup_message_io_read_headers (msg, io->istream, io->read_header_buf, FALSE, cancellable, error))
+ if (!soup_message_io_data_read_headers (io, FALSE, cancellable, error)) {
+ if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT))
+ soup_server_message_set_status (msg, SOUP_STATUS_MALFORMED, NULL);
return FALSE;
+ }
status = parse_headers (msg,
(char *)io->read_header_buf->data,
io->read_header_buf->len,
&io->read_encoding,
- io->sock,
error);
g_byte_array_set_size (io->read_header_buf, 0);
+ request_headers = soup_server_message_get_request_headers (msg);
+
if (status != SOUP_STATUS_OK) {
/* Either we couldn't parse the headers, or they
* indicated something that would mean we wouldn't
@@ -572,14 +679,13 @@ io_read (SoupMessage *msg,
* reading, and make sure the connection gets
* closed when we're done.
*/
- soup_message_set_status (msg, status);
- soup_message_headers_append (msg->request_headers,
- "Connection", "close");
+ soup_server_message_set_status (msg, status, NULL);
+ soup_message_headers_append (request_headers, "Connection", "close");
io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
break;
}
- if (soup_message_headers_get_expectations (msg->request_headers) & SOUP_EXPECTATION_CONTINUE) {
+ if (soup_message_headers_get_expectations (request_headers) & SOUP_EXPECTATION_CONTINUE) {
/* We must return a status code and response
* headers to the client; either an error to
* be set by a got-headers handler below, or
@@ -591,11 +697,11 @@ io_read (SoupMessage *msg,
io->read_state = SOUP_MESSAGE_IO_STATE_BODY_START;
if (io->read_encoding == SOUP_ENCODING_CONTENT_LENGTH)
- io->read_length = soup_message_headers_get_content_length (msg->request_headers);
+ io->read_length = soup_message_headers_get_content_length (request_headers);
else
io->read_length = -1;
- soup_message_got_headers (msg);
+ soup_server_message_got_headers (msg);
break;
case SOUP_MESSAGE_IO_STATE_BODY_START:
@@ -618,10 +724,13 @@ io_read (SoupMessage *msg,
FALSE,
cancellable, error);
if (nread > 0) {
- if (msg->request_body) {
+ SoupMessageBody *request_body;
+
+ request_body = soup_server_message_get_request_body (msg);
+ if (request_body) {
GBytes *bytes = g_bytes_new (buf, nread);
- soup_message_body_got_chunk (msg->request_body, bytes);
- soup_message_got_chunk (msg, bytes);
+ soup_message_body_got_chunk (request_body, bytes);
+ soup_server_message_got_chunk (msg, bytes);
g_bytes_unref (bytes);
}
break;
@@ -637,7 +746,7 @@ io_read (SoupMessage *msg,
case SOUP_MESSAGE_IO_STATE_BODY_DONE:
io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
- soup_message_got_body (msg);
+ soup_server_message_got_body (msg);
break;
case SOUP_MESSAGE_IO_STATE_FINISHING:
@@ -653,13 +762,14 @@ io_read (SoupMessage *msg,
}
static gboolean
-io_run_until (SoupMessage *msg,
+io_run_until (SoupServerMessage *msg,
SoupMessageIOState read_state,
SoupMessageIOState write_state,
GCancellable *cancellable,
GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+ SoupMessageIOData *io = &server_io->base;
gboolean progress = TRUE, done;
GError *my_error = NULL;
@@ -674,7 +784,7 @@ io_run_until (SoupMessage *msg,
g_object_ref (msg);
- while (progress && soup_message_get_io_data (msg) == io && !io->paused && !io->async_wait &&
+ while (progress && soup_server_message_get_io_data (msg) == server_io && !io->paused && !io->async_wait &&
(io->read_state < read_state || io->write_state < write_state)) {
if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
@@ -689,7 +799,7 @@ io_run_until (SoupMessage *msg,
g_propagate_error (error, my_error);
g_object_unref (msg);
return FALSE;
- } else if (soup_message_get_io_data (msg) != io) {
+ } else if (soup_server_message_get_io_data (msg) != server_io) {
g_set_error_literal (error, G_IO_ERROR,
G_IO_ERROR_CANCELLED,
_("Operation was cancelled"));
@@ -716,22 +826,22 @@ io_run_until (SoupMessage *msg,
return done;
}
-static void io_run (SoupMessage *msg);
+static void io_run (SoupServerMessage *msg);
static gboolean
-io_run_ready (SoupMessage *msg,
- gpointer user_data)
+io_run_ready (SoupServerMessage *msg,
+ gpointer user_data)
{
io_run (msg);
return FALSE;
}
static void
-io_run (SoupMessage *msg)
+io_run (SoupServerMessage *msg)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupServerMessageIOData *server_io = soup_server_message_get_io_data (msg);
+ SoupMessageIOData *io = &server_io->base;
GError *error = NULL;
- GCancellable *cancellable;
if (io->io_source) {
g_source_destroy (io->io_source);
@@ -740,58 +850,109 @@ io_run (SoupMessage *msg)
}
g_object_ref (msg);
- cancellable = io->cancellable ? g_object_ref (io->cancellable) : NULL;
-
if (io_run_until (msg,
SOUP_MESSAGE_IO_STATE_DONE,
SOUP_MESSAGE_IO_STATE_DONE,
- cancellable, &error)) {
- soup_message_io_finished (msg);
+ NULL, &error)) {
+ soup_server_message_io_finished (msg);
} else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
g_clear_error (&error);
- io->io_source = soup_message_io_get_source (msg, NULL, io_run_ready, msg);
+ io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg), NULL,
+ (SoupMessageIOSourceFunc)io_run_ready,
+ NULL);
g_source_attach (io->io_source, io->async_context);
} else {
- if (soup_message_get_io_data (msg) == io) {
- if (!SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code) &&
+ if (soup_server_message_get_io_data (msg) == server_io) {
+ if (!SOUP_STATUS_IS_TRANSPORT_ERROR (soup_server_message_get_status (msg, NULL)) &&
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) {
- soup_message_set_status (msg, SOUP_STATUS_IO_ERROR);
+ soup_server_message_set_status (msg, SOUP_STATUS_IO_ERROR, NULL);
}
- soup_message_io_finished (msg);
+ soup_server_message_io_finished (msg);
}
g_error_free (error);
}
-
g_object_unref (msg);
- g_clear_object (&cancellable);
}
void
-soup_message_read_request (SoupMessage *msg,
- SoupSocket *sock,
- SoupMessageCompletionFn completion_cb,
- gpointer user_data)
+soup_server_message_read_request (SoupServerMessage *msg,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data)
{
- SoupMessageIOData *io;
+ SoupServerMessageIOData *io;
+ SoupSocket *sock;
- io = g_slice_new0 (SoupMessageIOData);
- io->completion_cb = completion_cb;
- io->completion_data = user_data;
+ io = g_slice_new0 (SoupServerMessageIOData);
+ io->base.completion_cb = completion_cb;
+ io->base.completion_data = user_data;
- io->sock = sock;
- io->iostream = g_object_ref (soup_socket_get_iostream (io->sock));
- io->istream = SOUP_FILTER_INPUT_STREAM (g_io_stream_get_input_stream (io->iostream));
- io->ostream = g_io_stream_get_output_stream (io->iostream);
- io->async_context = g_main_context_ref_thread_default ();
+ sock = soup_server_message_get_soup_socket (msg);
+ io->base.iostream = g_object_ref (soup_socket_get_iostream (sock));
+ io->base.istream = SOUP_FILTER_INPUT_STREAM (g_io_stream_get_input_stream (io->base.iostream));
+ io->base.ostream = g_io_stream_get_output_stream (io->base.iostream);
+ io->base.async_context = g_main_context_ref_thread_default ();
- io->read_header_buf = g_byte_array_new ();
- io->write_buf = g_string_new (NULL);
+ io->base.read_header_buf = g_byte_array_new ();
+ io->base.write_buf = g_string_new (NULL);
- io->read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
- io->write_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
+ io->base.read_state = SOUP_MESSAGE_IO_STATE_HEADERS;
+ io->base.write_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
- soup_message_set_io_data (msg, io);
+ soup_server_message_set_io_data (msg, io);
io_run (msg);
}
+
+void
+soup_server_message_io_pause (SoupServerMessage *msg)
+{
+ SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
+
+ g_return_if_fail (io != NULL);
+
+ if (io->unpause_source) {
+ g_source_destroy (io->unpause_source);
+ g_source_unref (io->unpause_source);
+ io->unpause_source = NULL;
+ }
+
+ soup_message_io_data_pause (&io->base);
+}
+
+static gboolean
+io_unpause_internal (gpointer msg)
+{
+ SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
+
+ g_return_val_if_fail (io != NULL, FALSE);
+
+ g_clear_pointer (&io->unpause_source, g_source_unref);
+ soup_message_io_data_unpause (&io->base);
+ if (io->base.io_source)
+ return FALSE;
+
+ io_run (msg);
+ return FALSE;
+}
+
+void
+soup_server_message_io_unpause (SoupServerMessage *msg)
+{
+ SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
+
+ g_return_if_fail (io != NULL);
+
+ if (!io->unpause_source) {
+ io->unpause_source = soup_add_completion_reffed (io->base.async_context,
+ io_unpause_internal, msg, NULL);
+ }
+}
+
+gboolean
+soup_server_message_is_io_paused (SoupServerMessage *msg)
+{
+ SoupServerMessageIOData *io = soup_server_message_get_io_data (msg);
+
+ return io && io->base.paused;
+}
diff --git a/libsoup/server/soup-server-message-private.h b/libsoup/server/soup-server-message-private.h
new file mode 100644
index 00000000..057b058d
--- /dev/null
+++ b/libsoup/server/soup-server-message-private.h
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ */
+
+#ifndef __SOUP_SERVER_MESSAGE_PRIVATE_H__
+#define __SOUP_SERVER_MESSAGE_PRIVATE_H__ 1
+
+#include "soup-server-message.h"
+#include "soup-auth-domain.h"
+#include "soup-message-io-data.h"
+#include "soup-socket.h"
+
+SoupServerMessage *soup_server_message_new (SoupSocket *sock);
+void soup_server_message_set_uri (SoupServerMessage *msg,
+ SoupURI *uri);
+void soup_server_message_set_method (SoupServerMessage *msg,
+ const char *method);
+SoupSocket *soup_server_message_get_soup_socket (SoupServerMessage *msg);
+void soup_server_message_set_auth (SoupServerMessage *msg,
+ SoupAuthDomain *domain,
+ char *user);
+gboolean soup_server_message_is_keepalive (SoupServerMessage *msg);
+GIOStream *soup_server_message_io_steal (SoupServerMessage *msg);
+void soup_server_message_io_pause (SoupServerMessage *msg);
+void soup_server_message_io_unpause (SoupServerMessage *msg);
+gboolean soup_server_message_is_io_paused (SoupServerMessage *msg);
+void soup_server_message_io_finished (SoupServerMessage *msg);
+void soup_server_message_cleanup_response (SoupServerMessage *msg);
+void soup_server_message_wrote_informational (SoupServerMessage *msg);
+void soup_server_message_wrote_headers (SoupServerMessage *msg);
+void soup_server_message_wrote_chunk (SoupServerMessage *msg);
+void soup_server_message_wrote_body_data (SoupServerMessage *msg,
+ gsize chunk_size);
+void soup_server_message_wrote_body (SoupServerMessage *msg);
+void soup_server_message_got_headers (SoupServerMessage *msg);
+void soup_server_message_got_chunk (SoupServerMessage *msg,
+ GBytes *chunk);
+void soup_server_message_got_body (SoupServerMessage *msg);
+void soup_server_message_finished (SoupServerMessage *msg);
+void soup_server_message_read_request (SoupServerMessage *msg,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data);
+
+typedef struct _SoupServerMessageIOData SoupServerMessageIOData;
+void soup_server_message_io_data_free (SoupServerMessageIOData *io);
+void soup_server_message_set_io_data (SoupServerMessage *msg,
+ SoupServerMessageIOData *io);
+SoupServerMessageIOData *soup_server_message_get_io_data (SoupServerMessage *msg);
+
+#endif /* __SOUP_SERVER_MESSAGE_PRIVATE_H__ */
diff --git a/libsoup/server/soup-server-message.c b/libsoup/server/soup-server-message.c
new file mode 100644
index 00000000..1f2e8515
--- /dev/null
+++ b/libsoup/server/soup-server-message.c
@@ -0,0 +1,881 @@
+/*
+ * soup-server-message.c: HTTP server request/response
+ *
+ * Copyright (C) 2020 Igalia S.L.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <string.h>
+
+#include "soup-server-message.h"
+#include "soup.h"
+#include "soup-connection.h"
+#include "soup-server-message-private.h"
+#include "soup-socket-private.h"
+
+/**
+ * SECTION:soup-server-message
+ * @short_description: An HTTP server request and response.
+ * @see_also: #SoupMessageHeaders, #SoupMessageBody
+ *
+ * A SoupServerMessage represents an HTTP message that is being sent or
+ * received on a #SoupServer
+ *
+ * #SoupServer will create #SoupServerMessage<!-- -->s automatically for
+ * incoming requests, which your application will receive via handlers.
+ *
+ * Note that libsoup's terminology here does not quite match the HTTP
+ * specification: in RFC 2616, an "HTTP-message" is
+ * <emphasis>either</emphasis> a Request, <emphasis>or</emphasis> a
+ * Response. In libsoup, a #SoupServerMessage combines both the request and
+ * the response.
+ **/
+
+struct _SoupServerMessage {
+ GObject parent;
+
+ SoupSocket *sock;
+ GSocket *gsock;
+ SoupAuthDomain *auth_domain;
+ char *auth_user;
+
+ GSocketAddress *remote_addr;
+ char *remote_ip;
+ GSocketAddress *local_addr;
+
+ const char *method;
+ SoupHTTPVersion http_version;
+ SoupHTTPVersion orig_http_version;
+
+ guint status_code;
+ char *reason_phrase;
+
+ SoupURI *uri;
+
+ SoupMessageBody *request_body;
+ SoupMessageHeaders *request_headers;
+
+ SoupMessageBody *response_body;
+ SoupMessageHeaders *response_headers;
+
+ SoupServerMessageIOData *io_data;
+};
+
+struct _SoupServerMessageClass {
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (SoupServerMessage, soup_server_message, G_TYPE_OBJECT)
+
+enum {
+ WROTE_INFORMATIONAL,
+ WROTE_HEADERS,
+ WROTE_CHUNK,
+ WROTE_BODY_DATA,
+ WROTE_BODY,
+
+ GOT_HEADERS,
+ GOT_CHUNK,
+ GOT_BODY,
+
+ DISCONNECTED,
+ FINISHED,
+
+ LAST_SIGNAL
+};
+
+static guint signals[LAST_SIGNAL] = { 0 };
+
+static void
+soup_server_message_init (SoupServerMessage *msg)
+{
+ msg->request_body = soup_message_body_new ();
+ msg->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
+ msg->response_body = soup_message_body_new ();
+ msg->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
+ soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_CONTENT_LENGTH);
+}
+
+static void
+soup_server_message_finalize (GObject *object)
+{
+ SoupServerMessage *msg = SOUP_SERVER_MESSAGE (object);
+
+ soup_server_message_io_data_free (msg->io_data);
+
+ g_clear_object (&msg->auth_domain);
+ g_clear_pointer (&msg->auth_user, g_free);
+ g_clear_object (&msg->remote_addr);
+ g_clear_object (&msg->local_addr);
+
+ if (msg->sock) {
+ g_signal_handlers_disconnect_by_data (msg->sock, msg);
+ g_object_unref (msg->sock);
+ }
+ g_clear_object (&msg->gsock);
+ g_clear_pointer (&msg->remote_ip, g_free);
+
+ g_clear_pointer (&msg->uri, soup_uri_free);
+ g_free (msg->reason_phrase);
+
+ soup_message_body_free (msg->request_body);
+ soup_message_headers_free (msg->request_headers);
+ soup_message_body_free (msg->response_body);
+ soup_message_headers_free (msg->response_headers);
+
+ G_OBJECT_CLASS (soup_server_message_parent_class)->finalize (object);
+}
+
+static void
+soup_server_message_class_init (SoupServerMessageClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = soup_server_message_finalize;
+
+ /**
+ * SoupServerMessage::wrote-informational:
+ * @msg: the message
+ *
+ * Emitted immediately after writing a 1xx (Informational) response.
+ */
+ signals[WROTE_INFORMATIONAL] =
+ g_signal_new ("wrote-informational",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * SoupServerMessage::wrote-headers:
+ * @msg: the message
+ *
+ * Emitted immediately after writing the response headers for a
+ * message.
+ */
+ signals[WROTE_HEADERS] =
+ g_signal_new ("wrote-headers",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * SoupServerMessage::wrote-chunk:
+ * @msg: the message
+ *
+ * Emitted immediately after writing a body chunk for a message.
+ *
+ * Note that this signal is not parallel to
+ * #SoupServerMessage::got-chunk; it is emitted only when a complete
+ * chunk (added with soup_message_body_append() or
+ * soup_message_body_append_bytes()) has been written. To get
+ * more useful continuous progress information, use
+ * #SoupServerMessage::wrote-body-data.
+ */
+ signals[WROTE_CHUNK] =
+ g_signal_new ("wrote-chunk",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * SoupServerMessage::wrote-body-data:
+ * @msg: the message
+ * @chunk_size: the number of bytes written
+ *
+ * Emitted immediately after writing a portion of the message
+ * body to the network.
+ */
+ signals[WROTE_BODY_DATA] =
+ g_signal_new ("wrote-body-data",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 1,
+ G_TYPE_UINT);
+
+ /**
+ * SoupServerMessage::wrote-body:
+ * @msg: the message
+ *
+ * Emitted immediately after writing the complete response body for a
+ * message.
+ */
+ signals[WROTE_BODY] =
+ g_signal_new ("wrote-body",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * SoupServerMessage::got-headers:
+ * @msg: the message
+ *
+ * Emitted after receiving the Request-Line and request headers.
+ */
+ signals[GOT_HEADERS] =
+ g_signal_new ("got-headers",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * SoupServerMessage::got-chunk:
+ * @msg: the message
+ * @chunk: the just-read chunk
+ *
+ * Emitted after receiving a chunk of a message body. Note
+ * that "chunk" in this context means any subpiece of the
+ * body, not necessarily the specific HTTP 1.1 chunks sent by
+ * the other side.
+ */
+ signals[GOT_CHUNK] =
+ g_signal_new ("got-chunk",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_FIRST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 1,
+ G_TYPE_BYTES);
+
+ /**
+ * SoupServerMessage::got-body:
+ * @msg: the message
+ *
+ * Emitted after receiving the complete request body.
+ */
+ signals[GOT_BODY] =
+ g_signal_new ("got-body",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * SoupServerMessage::finished:
+ * @msg: the message
+ *
+ * Emitted when all HTTP processing is finished for a message.
+ * (After #SoupServerMessage::wrote-body).
+ */
+ signals[FINISHED] =
+ g_signal_new ("finished",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+
+ /**
+ * SoupServerMessage::disconnected:
+ * @msg: the message
+ *
+ * Emitted when the @msg's socket is disconnected.
+ */
+ signals[DISCONNECTED] =
+ g_signal_new ("disconnected",
+ G_OBJECT_CLASS_TYPE (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ NULL,
+ G_TYPE_NONE, 0);
+}
+
+static void
+socket_disconnected (SoupServerMessage *msg)
+{
+ g_signal_emit (msg, signals[DISCONNECTED], 0);
+}
+
+SoupServerMessage *
+soup_server_message_new (SoupSocket *sock)
+{
+ SoupServerMessage *msg;
+
+ msg = g_object_new (SOUP_TYPE_SERVER_MESSAGE, NULL);
+ msg->sock = g_object_ref (sock);
+ msg->gsock = soup_socket_get_gsocket (sock);
+ if (msg->gsock)
+ g_object_ref (msg->gsock);
+
+ g_signal_connect_object (sock, "disconnected",
+ G_CALLBACK (socket_disconnected),
+ msg, G_CONNECT_SWAPPED);
+
+ return msg;
+}
+
+void
+soup_server_message_set_uri (SoupServerMessage *msg,
+ SoupURI *uri)
+{
+ if (msg->uri)
+ soup_uri_free (msg->uri);
+ msg->uri = soup_uri_copy (uri);
+}
+
+SoupSocket *
+soup_server_message_get_soup_socket (SoupServerMessage *msg)
+{
+ return msg->sock;
+}
+
+void
+soup_server_message_set_auth (SoupServerMessage *msg,
+ SoupAuthDomain *domain,
+ char *user)
+{
+ if (msg->auth_domain)
+ g_object_unref (msg->auth_domain);
+ msg->auth_domain = domain;
+
+ if (msg->auth_user)
+ g_free (msg->auth_user);
+ msg->auth_user = user;
+}
+
+gboolean
+soup_server_message_is_keepalive (SoupServerMessage *msg)
+{
+ if (msg->status_code == SOUP_STATUS_OK && msg->method == SOUP_METHOD_CONNECT)
+ return TRUE;
+
+ /* Not persistent if the server sent a terminate-by-EOF response */
+ if (soup_message_headers_get_encoding (msg->response_headers) == SOUP_ENCODING_EOF)
+ return FALSE;
+
+ if (msg->http_version == SOUP_HTTP_1_0) {
+ /* In theory, HTTP/1.0 connections are only persistent
+ * if the client requests it, and the server agrees.
+ * But some servers do keep-alive even if the client
+ * doesn't request it. So ignore c_conn.
+ */
+
+ if (!soup_message_headers_header_contains (msg->response_headers,
+ "Connection", "Keep-Alive"))
+ return FALSE;
+ } else {
+ /* Normally persistent unless either side requested otherwise */
+ if (soup_message_headers_header_contains (msg->request_headers,
+ "Connection", "close") ||
+ soup_message_headers_header_contains (msg->response_headers,
+ "Connection", "close"))
+ return FALSE;
+
+ return TRUE;
+ }
+
+ return TRUE;
+}
+
+void
+soup_server_message_set_io_data (SoupServerMessage *msg,
+ SoupServerMessageIOData *io)
+{
+ soup_server_message_io_data_free (msg->io_data);
+ msg->io_data = io;
+}
+
+SoupServerMessageIOData *
+soup_server_message_get_io_data (SoupServerMessage *msg)
+{
+ return msg->io_data;
+}
+
+void
+soup_server_message_cleanup_response (SoupServerMessage *msg)
+{
+ soup_message_body_truncate (msg->response_body);
+ soup_message_headers_clear (msg->response_headers);
+ soup_message_headers_set_encoding (msg->response_headers,
+ SOUP_ENCODING_CONTENT_LENGTH);
+ msg->status_code = SOUP_STATUS_NONE;
+ g_clear_pointer (&msg->reason_phrase, g_free);
+ msg->http_version = msg->orig_http_version;
+}
+
+void
+soup_server_message_wrote_informational (SoupServerMessage *msg)
+{
+ g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
+}
+
+void
+soup_server_message_wrote_headers (SoupServerMessage *msg)
+{
+ g_signal_emit (msg, signals[WROTE_HEADERS], 0);
+}
+
+void
+soup_server_message_wrote_chunk (SoupServerMessage *msg)
+{
+ g_signal_emit (msg, signals[WROTE_CHUNK], 0);
+}
+
+void
+soup_server_message_wrote_body_data (SoupServerMessage *msg,
+ gsize chunk_size)
+{
+ g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk_size);
+}
+
+void
+soup_server_message_wrote_body (SoupServerMessage *msg)
+{
+ g_signal_emit (msg, signals[WROTE_BODY], 0);
+}
+
+void
+soup_server_message_got_headers (SoupServerMessage *msg)
+{
+ g_signal_emit (msg, signals[GOT_HEADERS], 0);
+}
+
+void
+soup_server_message_got_chunk (SoupServerMessage *msg,
+ GBytes *chunk)
+{
+ g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
+}
+
+void
+soup_server_message_got_body (SoupServerMessage *msg)
+{
+ if (soup_message_body_get_accumulate (msg->request_body))
+ g_bytes_unref (soup_message_body_flatten (msg->request_body));
+ g_signal_emit (msg, signals[GOT_BODY], 0);
+}
+
+void
+soup_server_message_finished (SoupServerMessage *msg)
+{
+ g_signal_emit (msg, signals[FINISHED], 0);
+}
+
+/**
+ * soup_server_message_get_request_headers:
+ * @msg: a #SoupServerMessage
+ *
+ * Get the request headers of @msg.
+ *
+ * Returns: (transfer none): a #SoupMessageHeaders with the request headers.
+ */
+SoupMessageHeaders *
+soup_server_message_get_request_headers (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ return msg->request_headers;
+}
+
+/**
+ * soup_server_message_get_response_headers:
+ * @msg: a #SoupServerMessage
+ *
+ * Get the response headers of @msg.
+ *
+ * Returns: (transfer none): a #SoupMessageHeaders with the response headers.
+ */
+SoupMessageHeaders *
+soup_server_message_get_response_headers (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ return msg->response_headers;
+}
+
+/**
+ * soup_server_message_get_request_body:
+ * @msg: a #SoupServerMessage
+ *
+ * Get the request body of @msg.
+ *
+ * Returns: (transfer none): a #SoupMessageBody.
+ */
+SoupMessageBody *
+soup_server_message_get_request_body (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ return msg->request_body;
+}
+
+/**
+ * soup_server_message_get_response_body:
+ * @msg: a #SoupServerMessage
+ *
+ * Get the response body of @msg.
+ *
+ * Returns: (transfer none): a #SoupMessageBody.
+ */
+SoupMessageBody *
+soup_server_message_get_response_body (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ return msg->response_body;
+}
+
+/**
+ * soup_server_message_get_method:
+ * @msg: a #SoupServerMessage
+ *
+ * Get the HTTP method of @msg.
+ *
+ * Returns: the HTTP method.
+ */
+const char *
+soup_server_message_get_method (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ return msg->method;
+}
+
+void
+soup_server_message_set_method (SoupServerMessage *msg,
+ const char *method)
+{
+ msg->method = g_intern_string (method);
+}
+
+/**
+ * soup_server_message_get_http_version:
+ * @msg: a #SoupServerMessage
+ *
+ * Get the HTTP version of @msg.
+ *
+ * Returns: a #SoupHTTPVersion.
+ */
+SoupHTTPVersion
+soup_server_message_get_http_version (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), SOUP_HTTP_1_1);
+
+ return msg->http_version;
+}
+
+/**
+ * soup_server_message_set_http_version:
+ * @msg: a #SoupServerMessage
+ * @version: a #SoupHTTPVersion
+ *
+ * Set the HTTP version of @msg.
+ */
+void
+soup_server_message_set_http_version (SoupServerMessage *msg,
+ SoupHTTPVersion version)
+{
+ g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
+
+ msg->http_version = version;
+ if (msg->status_code == SOUP_STATUS_NONE)
+ msg->orig_http_version = version;
+}
+
+/**
+ * soup_server_message_get_status:
+ * @msg: a #SoupServerMessage
+ * @reason_phrase: (out) (nullable) (transfer none): a location to store the reason phrase or %NULL
+ *
+ * Get the HTTP status code of @msg and optionally the reason phrase if @reason_phrase is not %NULL.
+ *
+ * Returns: the HTTP status code.
+ */
+guint
+soup_server_message_get_status (SoupServerMessage *msg,
+ const char **reason_phrase)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), 0);
+
+ if (reason_phrase)
+ *reason_phrase = msg->reason_phrase;
+
+ return msg->status_code;
+}
+
+/**
+ * soup_server_message_set_status:
+ * @msg: a #SoupServerMessage
+ * @status_code: an HTTP status code
+ * @reason_phrase: (nullable): a reason phrase
+ *
+ * Sets @msg's status code to @status_code. If @status_code is a
+ * known value and @reason_phrase is %NULL, the reason_phrase will
+ * be set automatically.
+ **/
+void
+soup_server_message_set_status (SoupServerMessage *msg,
+ guint status_code,
+ const char *reason_phrase)
+{
+ g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
+ g_return_if_fail (status_code != 0);
+
+ g_free (msg->reason_phrase);
+
+ msg->status_code = status_code;
+ msg->reason_phrase = g_strdup (reason_phrase ? reason_phrase : soup_status_get_phrase (status_code));
+}
+
+/**
+ * soup_server_message_get_uri:
+ * @msg: a #SoupServerMessage
+ *
+ * Get @msg's URI.
+ *
+ * Returns: (transfer none): a #SoupURI
+ */
+SoupURI *
+soup_server_message_get_uri (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ return msg->uri;
+}
+
+/**
+ * soup_server_message_set_response:
+ * @msg: the message
+ * @content_type: (allow-none): MIME Content-Type of the body
+ * @resp_use: a #SoupMemoryUse describing how to handle @resp_body
+ * @resp_body: (allow-none) (array length=resp_length) (element-type guint8):
+ * a data buffer containing the body of the message response.
+ * @resp_length: the byte length of @resp_body.
+ *
+ * Convenience function to set the response body of a #SoupServerMessage. If
+ * @content_type is %NULL, the response body must be empty as well.
+ */
+void
+soup_server_message_set_response (SoupServerMessage *msg,
+ const char *content_type,
+ SoupMemoryUse resp_use,
+ const char *resp_body,
+ gsize resp_length)
+{
+ g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
+ g_return_if_fail (content_type != NULL || resp_length == 0);
+
+ if (content_type) {
+ g_warn_if_fail (strchr (content_type, '/') != NULL);
+
+ soup_message_headers_replace (msg->response_headers,
+ "Content-Type", content_type);
+ soup_message_body_append (msg->response_body, resp_use,
+ resp_body, resp_length);
+ } else {
+ soup_message_headers_remove (msg->response_headers,
+ "Content-Type");
+ soup_message_body_truncate (msg->response_body);
+ }
+}
+
+/**
+ * soup_server_message_set_redirect:
+ * @msg: a #SoupServerMessage
+ * @status_code: a 3xx status code
+ * @redirect_uri: the URI to redirect @msg to
+ *
+ * Sets @msg's status_code to @status_code and adds a Location header
+ * pointing to @redirect_uri. Use this from a #SoupServer when you
+ * want to redirect the client to another URI.
+ *
+ * @redirect_uri can be a relative URI, in which case it is
+ * interpreted relative to @msg's current URI. In particular, if
+ * @redirect_uri is just a path, it will replace the path
+ * <emphasis>and query</emphasis> of @msg's URI.
+ */
+void
+soup_server_message_set_redirect (SoupServerMessage *msg,
+ guint status_code,
+ const char *redirect_uri)
+{
+ SoupURI *location;
+ char *location_str;
+
+ g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
+
+ location = soup_uri_new_with_base (soup_server_message_get_uri (msg), redirect_uri);
+ g_return_if_fail (location != NULL);
+
+ soup_server_message_set_status (msg, status_code, NULL);
+ location_str = soup_uri_to_string (location, FALSE);
+ soup_message_headers_replace (msg->response_headers, "Location",
+ location_str);
+ g_free (location_str);
+ soup_uri_free (location);
+}
+
+/**
+ * soup_server_message_get_socket:
+ * @msg: a #SoupServerMessage
+ *
+ * Retrieves the #GSocket that @msg is associated with.
+ *
+ * If you are using this method to observe when multiple requests are
+ * made on the same persistent HTTP connection (eg, as the ntlm-test
+ * test program does), you will need to pay attention to socket
+ * destruction as well (eg, by using weak references), so that you do
+ * not get fooled when the allocator reuses the memory address of a
+ * previously-destroyed socket to represent a new socket.
+ *
+ * Return value: (nullable) (transfer none): the #GSocket that @msg is
+ * associated with, %NULL if you used soup_server_accept_iostream().
+ */
+GSocket *
+soup_server_message_get_socket (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ return msg->gsock;
+}
+
+/**
+ * soup_server_message_get_remote_address:
+ * @msg: a #SoupServerMessage
+ *
+ * Retrieves the #GSocketAddress associated with the remote end
+ * of a connection.
+ *
+ * Return value: (nullable) (transfer none): the #GSocketAddress
+ * associated with the remote end of a connection, it may be
+ * %NULL if you used soup_server_accept_iostream().
+ */
+GSocketAddress *
+soup_server_message_get_remote_address (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ if (msg->remote_addr)
+ return msg->remote_addr;
+
+ msg->remote_addr = msg->gsock ?
+ g_socket_get_remote_address (msg->gsock, NULL) :
+ G_SOCKET_ADDRESS (g_object_ref (soup_socket_get_remote_address (msg->sock)));
+
+ return msg->remote_addr;
+}
+
+/**
+ * soup_server_message_get_local_address:
+ * @msg: a #SoupServerMessage
+ *
+ * Retrieves the #GSocketAddress associated with the local end
+ * of a connection.
+ *
+ * Return value: (nullable) (transfer none): the #GSocketAddress
+ * associated with the local end of a connection, it may be
+ * %NULL if you used soup_server_accept_iostream().
+ */
+GSocketAddress *
+soup_server_message_get_local_address (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ if (msg->local_addr)
+ return msg->local_addr;
+
+ msg->local_addr = msg->gsock ?
+ g_socket_get_local_address (msg->gsock, NULL) :
+ G_SOCKET_ADDRESS (g_object_ref (soup_socket_get_local_address (msg->sock)));
+
+ return msg->local_addr;
+}
+
+/**
+ * soup_server_message_get_remote_host:
+ * @msg: a #SoupServerMessage
+ *
+ * Retrieves the IP address associated with the remote end of a
+ * connection.
+ *
+ * Return value: (nullable): the IP address associated with the remote
+ * end of a connection, it may be %NULL if you used
+ * soup_server_accept_iostream().
+ */
+const char *
+soup_server_message_get_remote_host (SoupServerMessage *msg)
+{
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), NULL);
+
+ if (msg->remote_ip)
+ return msg->remote_ip;
+
+ if (msg->gsock) {
+ GSocketAddress *addr = soup_server_message_get_remote_address (msg);
+ GInetAddress *iaddr;
+
+ if (!addr || !G_IS_INET_SOCKET_ADDRESS (addr))
+ return NULL;
+ iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
+ msg->remote_ip = g_inet_address_to_string (iaddr);
+ } else {
+ GInetSocketAddress *addr = G_INET_SOCKET_ADDRESS (soup_socket_get_remote_address (msg->sock));
+ GInetAddress *inet_addr = g_inet_socket_address_get_address (addr);
+ msg->remote_ip = g_inet_address_to_string (inet_addr);
+ }
+
+ return msg->remote_ip;
+}
+
+/**
+ * soup_server_message_steal_connection:
+ * @msg: a #SoupServerMessage
+ *
+ * "Steals" the HTTP connection associated with @msg from its
+ * #SoupServer. This happens immediately, regardless of the current
+ * state of the connection; if the response to @msg has not yet finished
+ * being sent, then it will be discarded; you can steal the connection from a
+ * #SoupServerMessage:wrote-informational or #SoupServerMessage:wrote-body signal
+ * handler if you need to wait for part or all of the response to be sent.
+ *
+ * Note that when calling this function from C, @msg will most
+ * likely be freed as a side effect.
+ *
+ * Return value: (transfer full): the #GIOStream formerly associated
+ * with @msg (or %NULL if @msg was no longer associated with a
+ * connection). No guarantees are made about what kind of #GIOStream
+ * is returned.
+ */
+GIOStream *
+soup_server_message_steal_connection (SoupServerMessage *msg)
+{
+ GIOStream *stream;
+
+ g_object_ref (msg);
+ stream = soup_server_message_io_steal (msg);
+ if (stream) {
+ g_object_set_data_full (G_OBJECT (stream), "GSocket",
+ soup_socket_steal_gsocket (msg->sock),
+ g_object_unref);
+ }
+
+ socket_disconnected (msg);
+ g_object_unref (msg);
+
+ return stream;
+}
diff --git a/libsoup/server/soup-server-message.h b/libsoup/server/soup-server-message.h
new file mode 100644
index 00000000..5102648e
--- /dev/null
+++ b/libsoup/server/soup-server-message.h
@@ -0,0 +1,79 @@
+/*
+ * Copyright (C) 2020 Igalia S.L.
+ */
+
+#ifndef __SOUP_SERVER_MESSAGE_H__
+#define __SOUP_SERVER_MESSAGE_H__ 1
+
+#include "soup-types.h"
+#include "soup-message-body.h"
+#include "soup-message-headers.h"
+#include "soup-method.h"
+
+G_BEGIN_DECLS
+
+#define SOUP_TYPE_SERVER_MESSAGE (soup_server_message_get_type ())
+SOUP_AVAILABLE_IN_ALL
+G_DECLARE_FINAL_TYPE (SoupServerMessage, soup_server_message, SOUP, SERVER_MESSAGE, GObject)
+
+SOUP_AVAILABLE_IN_ALL
+SoupMessageHeaders *soup_server_message_get_request_headers (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+SoupMessageHeaders *soup_server_message_get_response_headers (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+SoupMessageBody *soup_server_message_get_request_body (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+SoupMessageBody *soup_server_message_get_response_body (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+const char *soup_server_message_get_method (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+SoupHTTPVersion soup_server_message_get_http_version (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+void soup_server_message_set_http_version (SoupServerMessage *msg,
+ SoupHTTPVersion version);
+
+SOUP_AVAILABLE_IN_ALL
+guint soup_server_message_get_status (SoupServerMessage *msg,
+ const char **reason_phrase);
+SOUP_AVAILABLE_IN_ALL
+void soup_server_message_set_status (SoupServerMessage *msg,
+ guint status_code,
+ const char *reason_phrase);
+SOUP_AVAILABLE_IN_ALL
+SoupURI *soup_server_message_get_uri (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+void soup_server_message_set_response (SoupServerMessage *msg,
+ const char *content_type,
+ SoupMemoryUse resp_use,
+ const char *resp_body,
+ gsize resp_length);
+SOUP_AVAILABLE_IN_ALL
+void soup_server_message_set_redirect (SoupServerMessage *msg,
+ guint status_code,
+ const char *redirect_uri);
+
+SOUP_AVAILABLE_IN_ALL
+GSocket *soup_server_message_get_socket (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+GSocketAddress *soup_server_message_get_local_address (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+GSocketAddress *soup_server_message_get_remote_address (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+const char *soup_server_message_get_remote_host (SoupServerMessage *msg);
+
+SOUP_AVAILABLE_IN_ALL
+GIOStream *soup_server_message_steal_connection (SoupServerMessage *msg);
+
+G_END_DECLS
+
+#endif /* __SOUP_SERVER_MESSAGE_H__ */
diff --git a/libsoup/server/soup-server-private.h b/libsoup/server/soup-server-private.h
deleted file mode 100644
index 15430e73..00000000
--- a/libsoup/server/soup-server-private.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/*
- * Copyright 2020 Igalia S.L.
- *
- * This file is free software; you can redistribute it and/or modify it
- * under the terms of the GNU Lesser General Public License as
- * published by the Free Software Foundation; either version 2 of the
- * License, or (at your option) any later version.
- *
- * This file is distributed in the hope that it will be useful, but
- * WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
- * Lesser General Public License for more details.
- *
- * You should have received a copy of the GNU Lesser General Public
- * License along with this program. If not, see <http://www.gnu.org/licenses/>.
- *
- */
-
-#pragma once
-
-#include "soup-server.h"
-
-SoupSocket *soup_client_context_get_soup_socket (SoupClientContext *client);
diff --git a/libsoup/server/soup-server.c b/libsoup/server/soup-server.c
index aa5f2203..2802f66a 100644
--- a/libsoup/server/soup-server.c
+++ b/libsoup/server/soup-server.c
@@ -13,9 +13,10 @@
#include <glib/gi18n-lib.h>
-#include "soup-server-private.h"
+#include "soup-server.h"
+#include "soup-server-message-private.h"
#include "soup.h"
-#include "soup-message-private.h"
+#include "soup-server-message-private.h"
#include "soup-misc.h"
#include "soup-path-map.h"
#include "soup-socket-private.h"
@@ -129,21 +130,6 @@ enum {
static guint signals[LAST_SIGNAL] = { 0 };
-struct _SoupClientContext {
- SoupServer *server;
- SoupSocket *sock;
- GSocket *gsock;
- SoupMessage *msg;
- SoupAuthDomain *auth_domain;
- char *auth_user;
-
- GSocketAddress *remote_addr;
- char *remote_ip;
- GSocketAddress *local_addr;
-
- int ref_count;
-};
-
typedef struct {
char *path;
@@ -207,9 +193,8 @@ enum {
G_DEFINE_TYPE_WITH_PRIVATE (SoupServer, soup_server, G_TYPE_OBJECT)
-static SoupClientContext *soup_client_context_ref (SoupClientContext *client);
-static void soup_client_context_unref (SoupClientContext *client);
-
+static void start_request (SoupServer *server,
+ SoupServerMessage *msg);
static void
free_handler (SoupServerHandler *handler)
{
@@ -398,7 +383,6 @@ soup_server_class_init (SoupServerClass *server_class)
* SoupServer::request-started:
* @server: the server
* @message: the new message
- * @client: the client context
*
* Emitted when the server has started reading a new request.
* @message will be completely blank; not even the
@@ -419,15 +403,13 @@ soup_server_class_init (SoupServerClass *server_class)
G_STRUCT_OFFSET (SoupServerClass, request_started),
NULL, NULL,
NULL,
- G_TYPE_NONE, 2,
- SOUP_TYPE_MESSAGE,
- SOUP_TYPE_CLIENT_CONTEXT);
+ G_TYPE_NONE, 1,
+ SOUP_TYPE_SERVER_MESSAGE);
/**
* SoupServer::request-read:
* @server: the server
* @message: the message
- * @client: the client context
*
* Emitted when the server has successfully read a request.
* @message will have all of its request-side information
@@ -444,15 +426,13 @@ soup_server_class_init (SoupServerClass *server_class)
G_STRUCT_OFFSET (SoupServerClass, request_read),
NULL, NULL,
NULL,
- G_TYPE_NONE, 2,
- SOUP_TYPE_MESSAGE,
- SOUP_TYPE_CLIENT_CONTEXT);
+ G_TYPE_NONE, 1,
+ SOUP_TYPE_SERVER_MESSAGE);
/**
* SoupServer::request-finished:
* @server: the server
* @message: the message
- * @client: the client context
*
* Emitted when the server has finished writing a response to
* a request.
@@ -464,15 +444,13 @@ soup_server_class_init (SoupServerClass *server_class)
G_STRUCT_OFFSET (SoupServerClass, request_finished),
NULL, NULL,
NULL,
- G_TYPE_NONE, 2,
- SOUP_TYPE_MESSAGE,
- SOUP_TYPE_CLIENT_CONTEXT);
+ G_TYPE_NONE, 1,
+ SOUP_TYPE_SERVER_MESSAGE);
/**
* SoupServer::request-aborted:
* @server: the server
* @message: the message
- * @client: the client context
*
* Emitted when processing has failed for a message; this
* could mean either that it could not be read (if
@@ -493,9 +471,8 @@ soup_server_class_init (SoupServerClass *server_class)
G_STRUCT_OFFSET (SoupServerClass, request_aborted),
NULL, NULL,
NULL,
- G_TYPE_NONE, 2,
- SOUP_TYPE_MESSAGE,
- SOUP_TYPE_CLIENT_CONTEXT);
+ G_TYPE_NONE, 1,
+ SOUP_TYPE_SERVER_MESSAGE);
/* properties */
/**
@@ -818,97 +795,6 @@ soup_server_get_listeners (SoupServer *server)
return listeners;
}
-static void start_request (SoupServer *, SoupClientContext *);
-static void socket_disconnected (SoupSocket *sock, SoupClientContext *client);
-
-static SoupClientContext *
-soup_client_context_new (SoupServer *server, SoupSocket *sock)
-{
- SoupClientContext *client = g_slice_new0 (SoupClientContext);
-
- client->server = server;
- client->sock = g_object_ref (sock);
- client->gsock = soup_socket_get_gsocket (sock);
- if (client->gsock)
- g_object_ref (client->gsock);
- g_signal_connect (sock, "disconnected",
- G_CALLBACK (socket_disconnected), client);
- client->ref_count = 1;
-
- return client;
-}
-
-static void
-soup_client_context_cleanup (SoupClientContext *client)
-{
- g_clear_object (&client->auth_domain);
- g_clear_pointer (&client->auth_user, g_free);
- g_clear_object (&client->remote_addr);
- g_clear_object (&client->local_addr);
-
- client->msg = NULL;
-}
-
-static SoupClientContext *
-soup_client_context_ref (SoupClientContext *client)
-{
- g_atomic_int_inc (&client->ref_count);
- return client;
-}
-
-static void
-soup_client_context_unref (SoupClientContext *client)
-{
- if (!g_atomic_int_dec_and_test (&client->ref_count))
- return;
-
- soup_client_context_cleanup (client);
-
- g_signal_handlers_disconnect_by_func (client->sock, socket_disconnected, client);
- g_object_unref (client->sock);
- g_clear_object (&client->gsock);
- g_clear_pointer (&client->remote_ip, g_free);
- g_slice_free (SoupClientContext, client);
-}
-
-static void
-request_finished (SoupMessage *msg, SoupMessageIOCompletion completion, gpointer user_data)
-{
- SoupClientContext *client = user_data;
- SoupServer *server = client->server;
- SoupServerPrivate *priv = soup_server_get_instance_private (server);
- SoupSocket *sock = client->sock;
- gboolean failed;
-
- if (completion == SOUP_MESSAGE_IO_STOLEN) {
- soup_client_context_unref (client);
- g_object_unref (msg);
- return;
- }
-
- /* Complete the message, assuming it actually really started. */
- if (msg->method) {
- soup_message_finished (msg);
-
- failed = (completion == SOUP_MESSAGE_IO_INTERRUPTED ||
- msg->status_code == SOUP_STATUS_IO_ERROR);
- g_signal_emit (server,
- failed ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
- 0, msg, client);
- }
-
- if (completion == SOUP_MESSAGE_IO_COMPLETE &&
- soup_socket_is_connected (sock) &&
- soup_message_is_keepalive (msg) &&
- priv->listeners) {
- start_request (server, client);
- } else {
- soup_socket_disconnect (client->sock);
- soup_client_context_unref (client);
- }
- g_object_unref (msg);
-}
-
/* "" was never documented as meaning the same thing as "/", but it
* effectively was. We have to special case it now or otherwise it
* would match "*" too.
@@ -916,19 +802,21 @@ request_finished (SoupMessage *msg, SoupMessageIOCompletion completion, gpointer
#define NORMALIZED_PATH(path) ((path) && *(path) ? (path) : "/")
static SoupServerHandler *
-get_handler (SoupServer *server, SoupMessage *msg)
+get_handler (SoupServer *server,
+ SoupServerMessage *msg)
{
SoupServerPrivate *priv = soup_server_get_instance_private (server);
SoupURI *uri;
- uri = soup_message_get_uri (msg);
+ uri = soup_server_message_get_uri (msg);
return soup_path_map_lookup (priv->handlers, NORMALIZED_PATH (uri->path));
}
static void
-call_handler (SoupServer *server, SoupServerHandler *handler,
- SoupClientContext *client, SoupMessage *msg,
- gboolean early)
+call_handler (SoupServer *server,
+ SoupServerHandler *handler,
+ SoupServerMessage *msg,
+ gboolean early)
{
GHashTable *form_data_set;
SoupURI *uri;
@@ -938,10 +826,10 @@ call_handler (SoupServer *server, SoupServerHandler *handler,
else if (!early && !handler->callback)
return;
- if (msg->status_code != 0)
+ if (soup_server_message_get_status (msg, NULL) != 0)
return;
- uri = soup_message_get_uri (msg);
+ uri = soup_server_message_get_uri (msg);
if (uri->query)
form_data_set = soup_form_decode (uri->query);
else
@@ -950,11 +838,11 @@ call_handler (SoupServer *server, SoupServerHandler *handler,
if (early) {
(*handler->early_callback) (server, msg,
uri->path, form_data_set,
- client, handler->early_user_data);
+ handler->early_user_data);
} else {
(*handler->callback) (server, msg,
uri->path, form_data_set,
- client, handler->user_data);
+ handler->user_data);
}
if (form_data_set)
@@ -962,9 +850,9 @@ call_handler (SoupServer *server, SoupServerHandler *handler,
}
static void
-got_headers (SoupMessage *msg, SoupClientContext *client)
+got_headers (SoupServer *server,
+ SoupServerMessage *msg)
{
- SoupServer *server = client->server;
SoupServerPrivate *priv = soup_server_get_instance_private (server);
SoupServerHandler *handler;
SoupURI *uri;
@@ -974,22 +862,26 @@ got_headers (SoupMessage *msg, SoupClientContext *client)
GSList *iter;
gboolean rejected = FALSE;
char *auth_user;
+ SoupMessageHeaders *headers;
+ SoupSocket *sock;
/* Add required response headers */
+ headers = soup_server_message_get_response_headers (msg);
+
date = g_date_time_new_now_utc ();
date_string = soup_date_time_to_string (date, SOUP_DATE_HTTP);
- soup_message_headers_replace (msg->response_headers, "Date",
- date_string);
+ soup_message_headers_replace (headers, "Date", date_string);
g_free (date_string);
g_date_time_unref (date);
- if (msg->status_code != 0)
+ if (soup_server_message_get_status (msg, NULL) != 0)
return;
- uri = soup_message_get_uri (msg);
- if ((soup_socket_is_ssl (client->sock) && !soup_uri_is_https (uri, priv->https_aliases)) ||
- (!soup_socket_is_ssl (client->sock) && !soup_uri_is_http (uri, priv->http_aliases))) {
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ sock = soup_server_message_get_soup_socket (msg);
+ uri = soup_server_message_get_uri (msg);
+ if ((soup_socket_is_ssl (sock) && !soup_uri_is_https (uri, priv->https_aliases)) ||
+ (!soup_socket_is_ssl (sock) && !soup_uri_is_http (uri, priv->http_aliases))) {
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
return;
}
@@ -1010,7 +902,7 @@ got_headers (SoupMessage *msg, SoupClientContext *client)
) {
/* Introducing new ".." segments is not allowed */
g_free (decoded_path);
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
return;
}
@@ -1029,8 +921,7 @@ got_headers (SoupMessage *msg, SoupClientContext *client)
if (soup_auth_domain_covers (domain, msg)) {
auth_user = soup_auth_domain_accepts (domain, msg);
if (auth_user) {
- client->auth_domain = g_object_ref (domain);
- client->auth_user = auth_user;
+ soup_server_message_set_auth (msg, g_object_ref (domain), auth_user);
return;
}
@@ -1052,15 +943,14 @@ got_headers (SoupMessage *msg, SoupClientContext *client)
/* Otherwise, call the early handlers. */
handler = get_handler (server, msg);
if (handler)
- call_handler (server, handler, client, msg, TRUE);
+ call_handler (server, handler, msg, TRUE);
}
static void
-complete_websocket_upgrade (SoupMessage *msg, gpointer user_data)
+complete_websocket_upgrade (SoupServer *server,
+ SoupServerMessage *msg)
{
- SoupClientContext *client = user_data;
- SoupServer *server = client->server;
- SoupURI *uri = soup_message_get_uri (msg);
+ SoupURI *uri = soup_server_message_get_uri (msg);
SoupServerHandler *handler;
GIOStream *stream;
SoupWebsocketConnection *conn;
@@ -1069,42 +959,41 @@ complete_websocket_upgrade (SoupMessage *msg, gpointer user_data)
if (!handler || !handler->websocket_callback)
return;
- soup_client_context_ref (client);
- stream = soup_client_context_steal_connection (client);
+ g_object_ref (msg);
+ stream = soup_server_message_steal_connection (msg);
conn = soup_websocket_connection_new_with_extensions (stream, uri,
SOUP_WEBSOCKET_CONNECTION_SERVER,
- soup_message_headers_get_one (msg->request_headers, "Origin"),
- soup_message_headers_get_one (msg->response_headers, "Sec-WebSocket-Protocol"),
+ soup_message_headers_get_one (soup_server_message_get_request_headers (msg), "Origin"),
+ soup_message_headers_get_one (soup_server_message_get_response_headers (msg), "Sec-WebSocket-Protocol"),
handler->websocket_extensions);
handler->websocket_extensions = NULL;
g_object_unref (stream);
- soup_client_context_unref (client);
- (*handler->websocket_callback) (server, conn, uri->path, client,
+ (*handler->websocket_callback) (server, msg, uri->path, conn,
handler->websocket_user_data);
g_object_unref (conn);
- soup_client_context_unref (client);
+ g_object_unref (msg);
}
static void
-got_body (SoupMessage *msg, SoupClientContext *client)
+got_body (SoupServer *server,
+ SoupServerMessage *msg)
{
- SoupServer *server = client->server;
SoupServerHandler *handler;
- g_signal_emit (server, signals[REQUEST_READ], 0, msg, client);
+ g_signal_emit (server, signals[REQUEST_READ], 0, msg);
- if (msg->status_code != 0)
+ if (soup_server_message_get_status (msg, NULL) != 0)
return;
handler = get_handler (server, msg);
if (!handler) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND, NULL);
return;
}
- call_handler (server, handler, client, msg, FALSE);
- if (msg->status_code != 0)
+ call_handler (server, handler, msg, FALSE);
+ if (soup_server_message_get_status (msg, NULL) != 0)
return;
if (handler->websocket_callback) {
@@ -1116,65 +1005,110 @@ got_body (SoupMessage *msg, SoupClientContext *client)
handler->websocket_protocols,
priv->websocket_extension_types,
&handler->websocket_extensions)) {
- g_signal_connect (msg, "wrote-informational",
- G_CALLBACK (complete_websocket_upgrade),
- soup_client_context_ref (client));
+ g_signal_connect_object (msg, "wrote-informational",
+ G_CALLBACK (complete_websocket_upgrade),
+ server, G_CONNECT_SWAPPED);
}
}
}
static void
-start_request (SoupServer *server, SoupClientContext *client)
+client_disconnected (SoupServer *server,
+ SoupServerMessage *msg)
{
SoupServerPrivate *priv = soup_server_get_instance_private (server);
- SoupMessage *msg;
-
- soup_client_context_cleanup (client);
- /* Listen for another request on this connection */
- msg = g_object_new (SOUP_TYPE_MESSAGE,
- SOUP_MESSAGE_SERVER_SIDE, TRUE,
- NULL);
- client->msg = msg;
+ priv->clients = g_slist_remove (priv->clients, msg);
- if (priv->server_header) {
- soup_message_headers_append (msg->response_headers, "Server",
- priv->server_header);
+ if (soup_server_message_get_status (msg, NULL) != 0) {
+ soup_server_message_set_status (msg, SOUP_STATUS_IO_ERROR, NULL);
+ soup_server_message_io_finished (msg);
}
+}
- g_signal_connect (msg, "got_headers", G_CALLBACK (got_headers), client);
- g_signal_connect (msg, "got_body", G_CALLBACK (got_body), client);
-
- g_signal_emit (server, signals[REQUEST_STARTED], 0,
- msg, client);
-
- soup_message_read_request (msg, client->sock,
- request_finished, client);
+static void
+soup_server_accept_socket (SoupServer *server,
+ SoupSocket *sock)
+{
+ SoupServerPrivate *priv = soup_server_get_instance_private (server);
+ SoupServerMessage *msg;
+
+ msg = soup_server_message_new (sock);
+ g_signal_connect_object (msg, "disconnected",
+ G_CALLBACK (client_disconnected),
+ server, G_CONNECT_SWAPPED);
+ priv->clients = g_slist_prepend (priv->clients, msg);
+ start_request (server, msg);
}
static void
-socket_disconnected (SoupSocket *sock, SoupClientContext *client)
+request_finished (SoupServerMessage *msg,
+ SoupMessageIOCompletion completion,
+ SoupServer *server)
{
- SoupServerPrivate *priv = soup_server_get_instance_private (client->server);
+ SoupServerPrivate *priv = soup_server_get_instance_private (server);
+ SoupSocket *sock = soup_server_message_get_soup_socket (msg);
+ gboolean failed;
+
+ if (completion == SOUP_MESSAGE_IO_STOLEN) {
+ g_object_unref (msg);
+ return;
+ }
- priv->clients = g_slist_remove (priv->clients, client);
+ /* Complete the message, assuming it actually really started. */
+ if (soup_server_message_get_method (msg)) {
+ soup_server_message_finished (msg);
+
+ failed = (completion == SOUP_MESSAGE_IO_INTERRUPTED ||
+ soup_server_message_get_status (msg, NULL) == SOUP_STATUS_IO_ERROR);
+ g_signal_emit (server,
+ failed ? signals[REQUEST_ABORTED] : signals[REQUEST_FINISHED],
+ 0, msg);
+ }
- if (client->msg) {
- soup_message_set_status (client->msg, SOUP_STATUS_IO_ERROR);
- soup_message_io_finished (client->msg);
+ if (completion == SOUP_MESSAGE_IO_COMPLETE &&
+ soup_socket_is_connected (sock) &&
+ soup_server_message_is_keepalive (msg) &&
+ priv->listeners) {
+ g_object_ref (sock);
+ priv->clients = g_slist_remove (priv->clients, msg);
+ g_object_unref (msg);
+
+ soup_server_accept_socket (server, sock);
+ g_object_unref (sock);
+ return;
}
+
+ soup_socket_disconnect (sock);
+ g_object_unref (msg);
}
static void
-soup_server_accept_socket (SoupServer *server,
- SoupSocket *sock)
+start_request (SoupServer *server,
+ SoupServerMessage *msg)
{
SoupServerPrivate *priv = soup_server_get_instance_private (server);
- SoupClientContext *client;
- client = soup_client_context_new (server, sock);
- priv->clients = g_slist_prepend (priv->clients, client);
- start_request (server, client);
+ if (priv->server_header) {
+ SoupMessageHeaders *headers;
+
+ headers = soup_server_message_get_response_headers (msg);
+ soup_message_headers_append (headers, "Server",
+ priv->server_header);
+ }
+
+ g_signal_connect_object (msg, "got-headers",
+ G_CALLBACK (got_headers),
+ server, G_CONNECT_SWAPPED);
+ g_signal_connect_object (msg, "got-body",
+ G_CALLBACK (got_body),
+ server, G_CONNECT_SWAPPED);
+
+ g_signal_emit (server, signals[REQUEST_STARTED], 0, msg);
+
+ soup_server_message_read_request (msg,
+ (SoupMessageIOCompletionFn)request_finished,
+ server);
}
/**
@@ -1194,11 +1128,11 @@ soup_server_accept_socket (SoupServer *server,
* Since: 2.50
**/
gboolean
-soup_server_accept_iostream (SoupServer *server,
- GIOStream *stream,
- GSocketAddress *local_addr,
- GSocketAddress *remote_addr,
- GError **error)
+soup_server_accept_iostream (SoupServer *server,
+ GIOStream *stream,
+ GSocketAddress *local_addr,
+ GSocketAddress *remote_addr,
+ GError **error)
{
SoupSocket *sock;
@@ -1244,7 +1178,6 @@ soup_server_disconnect (SoupServer *server)
SoupServerPrivate *priv;
GSList *listeners, *clients, *iter;
SoupSocket *listener;
- SoupClientContext *client;
g_return_if_fail (SOUP_IS_SERVER (server));
priv = soup_server_get_instance_private (server);
@@ -1255,8 +1188,9 @@ soup_server_disconnect (SoupServer *server)
priv->listeners = NULL;
for (iter = clients; iter; iter = iter->next) {
- client = iter->data;
- soup_socket_disconnect (client->sock);
+ SoupServerMessage *msg = iter->data;
+
+ soup_socket_disconnect (soup_server_message_get_soup_socket (msg));
}
g_slist_free (clients);
@@ -1679,257 +1613,12 @@ soup_server_get_uris (SoupServer *server)
}
/**
- * SoupClientContext:
- *
- * A #SoupClientContext provides additional information about the
- * client making a particular request. In particular, you can use
- * soup_client_context_get_auth_domain() and
- * soup_client_context_get_auth_user() to determine if HTTP
- * authentication was used successfully.
- *
- * soup_client_context_get_remote_address() and/or
- * soup_client_context_get_host() can be used to get information for
- * logging or debugging purposes. soup_client_context_get_socket() may
- * also be of use in some situations (eg, tracking when multiple
- * requests are made on the same connection).
- **/
-G_DEFINE_BOXED_TYPE (SoupClientContext, soup_client_context, soup_client_context_ref, soup_client_context_unref)
-
-/**
- * soup_client_context_get_soup_socket:
- * @client: a #SoupClientContext
- *
- * Retrieves the #SoupSocket that @client is associated with.
- *
- * If you are using this method to observe when multiple requests are
- * made on the same persistent HTTP connection (eg, as the ntlm-test
- * test program does), you will need to pay attention to socket
- * destruction as well (either by using weak references, or by
- * connecting to the #SoupSocket::disconnected signal), so that you do
- * not get fooled when the allocator reuses the memory address of a
- * previously-destroyed socket to represent a new socket.
- *
- * Return value: (transfer none): the #SoupSocket that @client is
- * associated with.
- **/
-SoupSocket *
-soup_client_context_get_soup_socket (SoupClientContext *client)
-{
- g_return_val_if_fail (client != NULL, NULL);
-
- return client->sock;
-}
-
-/**
- * soup_client_context_get_socket:
- * @client: a #SoupClientContext
- *
- * Retrieves the #GSocket that @client is associated with.
- *
- * If you are using this method to observe when multiple requests are
- * made on the same persistent HTTP connection (eg, as the ntlm-test
- * test program does), you will need to pay attention to socket
- * destruction as well (eg, by using weak references), so that you do
- * not get fooled when the allocator reuses the memory address of a
- * previously-destroyed socket to represent a new socket.
- *
- * Return value: (nullable) (transfer none): the #GSocket that @client is
- * associated with, %NULL if you used soup_server_accept_iostream().
- *
- * Since: 2.48
- **/
-GSocket *
-soup_client_context_get_socket (SoupClientContext *client)
-{
- g_return_val_if_fail (client != NULL, NULL);
-
- return client->gsock;
-}
-
-/**
- * soup_client_context_get_remote_address:
- * @client: a #SoupClientContext
- *
- * Retrieves the #GSocketAddress associated with the remote end
- * of a connection.
- *
- * Return value: (nullable) (transfer none): the #GSocketAddress
- * associated with the remote end of a connection, it may be
- * %NULL if you used soup_server_accept_iostream().
- *
- * Since: 2.48
- **/
-GSocketAddress *
-soup_client_context_get_remote_address (SoupClientContext *client)
-{
- g_return_val_if_fail (client != NULL, NULL);
-
- if (client->remote_addr)
- return client->remote_addr;
-
- client->remote_addr = client->gsock ?
- g_socket_get_remote_address (client->gsock, NULL) :
- G_SOCKET_ADDRESS (g_object_ref (soup_socket_get_remote_address (client->sock)));
-
- return client->remote_addr;
-}
-
-/**
- * soup_client_context_get_local_address:
- * @client: a #SoupClientContext
- *
- * Retrieves the #GSocketAddress associated with the local end
- * of a connection.
- *
- * Return value: (nullable) (transfer none): the #GSocketAddress
- * associated with the local end of a connection, it may be
- * %NULL if you used soup_server_accept_iostream().
- *
- * Since: 2.48
- **/
-GSocketAddress *
-soup_client_context_get_local_address (SoupClientContext *client)
-{
- g_return_val_if_fail (client != NULL, NULL);
-
- if (client->local_addr)
- return client->local_addr;
-
- client->local_addr = client->gsock ?
- g_socket_get_local_address (client->gsock, NULL) :
- G_SOCKET_ADDRESS (g_object_ref (soup_socket_get_local_address (client->sock)));
-
- return client->local_addr;
-}
-
-/**
- * soup_client_context_get_host:
- * @client: a #SoupClientContext
- *
- * Retrieves the IP address associated with the remote end of a
- * connection.
- *
- * Return value: (nullable): the IP address associated with the remote
- * end of a connection, it may be %NULL if you used
- * soup_server_accept_iostream().
- **/
-const char *
-soup_client_context_get_host (SoupClientContext *client)
-{
- g_return_val_if_fail (client != NULL, NULL);
-
- if (client->remote_ip)
- return client->remote_ip;
-
- if (client->gsock) {
- GSocketAddress *addr = soup_client_context_get_remote_address (client);
- GInetAddress *iaddr;
-
- if (!addr || !G_IS_INET_SOCKET_ADDRESS (addr))
- return NULL;
- iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
- client->remote_ip = g_inet_address_to_string (iaddr);
- } else {
- GInetSocketAddress *addr = G_INET_SOCKET_ADDRESS (soup_socket_get_remote_address (client->sock));
- GInetAddress *inet_addr = g_inet_socket_address_get_address (addr);
- client->remote_ip = g_inet_address_to_string (inet_addr);
- }
-
- return client->remote_ip;
-}
-
-/**
- * soup_client_context_get_auth_domain:
- * @client: a #SoupClientContext
- *
- * Checks whether the request associated with @client has been
- * authenticated, and if so returns the #SoupAuthDomain that
- * authenticated it.
- *
- * Return value: (transfer none) (nullable): a #SoupAuthDomain, or
- * %NULL if the request was not authenticated.
- **/
-SoupAuthDomain *
-soup_client_context_get_auth_domain (SoupClientContext *client)
-{
- g_return_val_if_fail (client != NULL, NULL);
-
- return client->auth_domain;
-}
-
-/**
- * soup_client_context_get_auth_user:
- * @client: a #SoupClientContext
- *
- * Checks whether the request associated with @client has been
- * authenticated, and if so returns the username that the client
- * authenticated as.
- *
- * Return value: (nullable): the authenticated-as user, or %NULL if
- * the request was not authenticated.
- **/
-const char *
-soup_client_context_get_auth_user (SoupClientContext *client)
-{
- g_return_val_if_fail (client != NULL, NULL);
-
- return client->auth_user;
-}
-
-/**
- * soup_client_context_steal_connection:
- * @client: a #SoupClientContext
- *
- * "Steals" the HTTP connection associated with @client from its
- * #SoupServer. This happens immediately, regardless of the current
- * state of the connection; if the response to the current
- * #SoupMessage has not yet finished being sent, then it will be
- * discarded; you can steal the connection from a
- * #SoupMessage::wrote-informational or #SoupMessage::wrote-body signal
- * handler if you need to wait for part or all of the response to be
- * sent.
- *
- * Note that when calling this function from C, @client will most
- * likely be freed as a side effect.
- *
- * Return value: (transfer full): the #GIOStream formerly associated
- * with @client (or %NULL if @client was no longer associated with a
- * connection). No guarantees are made about what kind of #GIOStream
- * is returned.
- *
- * Since: 2.50
- **/
-GIOStream *
-soup_client_context_steal_connection (SoupClientContext *client)
-{
- GIOStream *stream;
-
- g_return_val_if_fail (client != NULL, NULL);
-
- soup_client_context_ref (client);
-
- stream = soup_message_io_steal (client->msg);
- if (stream) {
- g_object_set_data_full (G_OBJECT (stream), "GSocket",
- soup_socket_steal_gsocket (client->sock),
- g_object_unref);
- }
-
- socket_disconnected (client->sock, client);
- soup_client_context_unref (client);
-
- return stream;
-}
-
-
-/**
* SoupServerCallback:
* @server: the #SoupServer
* @msg: the message being processed
* @path: the path component of @msg's Request-URI
* @query: (element-type utf8 utf8) (allow-none): the parsed query
* component of @msg's Request-URI
- * @client: additional contextual information about the client
* @user_data: the data passed to soup_server_add_handler() or
* soup_server_add_early_handler().
*
@@ -2108,7 +1797,7 @@ soup_server_add_early_handler (SoupServer *server,
* @server: the #SoupServer
* @path: the path component of @msg's Request-URI
* @connection: the newly created WebSocket connection
- * @client: additional contextual information about the client
+ * @msg: the #SoupServerMessage
* @user_data: the data passed to @soup_server_add_handler
*
* A callback used to handle WebSocket requests to a #SoupServer. The
@@ -2249,30 +1938,30 @@ soup_server_remove_auth_domain (SoupServer *server, SoupAuthDomain *auth_domain)
/**
* soup_server_pause_message:
* @server: a #SoupServer
- * @msg: a #SoupMessage associated with @server.
+ * @msg: a #SoupServerMessage associated with @server.
*
* Pauses I/O on @msg. This can be used when you need to return from
* the server handler without having the full response ready yet. Use
* soup_server_unpause_message() to resume I/O.
*
- * This must only be called on a #SoupMessage which was created by the
+ * This must only be called on a #SoupServerMessage which was created by the
* #SoupServer and are currently doing I/O, such as those passed into a
* #SoupServerCallback or emitted in a #SoupServer::request-read signal.
**/
void
-soup_server_pause_message (SoupServer *server,
- SoupMessage *msg)
+soup_server_pause_message (SoupServer *server,
+ SoupServerMessage *msg)
{
g_return_if_fail (SOUP_IS_SERVER (server));
- g_return_if_fail (SOUP_IS_MESSAGE (msg));
+ g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
- soup_message_io_pause (msg);
+ soup_server_message_io_pause (msg);
}
/**
* soup_server_unpause_message:
* @server: a #SoupServer
- * @msg: a #SoupMessage associated with @server.
+ * @msg: a #SoupServerMessage associated with @server.
*
* Resumes I/O on @msg. Use this to resume after calling
* soup_server_pause_message(), or after adding a new chunk to a
@@ -2280,18 +1969,18 @@ soup_server_pause_message (SoupServer *server,
*
* I/O won't actually resume until you return to the main loop.
*
- * This must only be called on a #SoupMessage which was created by the
+ * This must only be called on a #SoupServerMessage which was created by the
* #SoupServer and are currently doing I/O, such as those passed into a
* #SoupServerCallback or emitted in a #SoupServer::request-read signal.
**/
void
-soup_server_unpause_message (SoupServer *server,
- SoupMessage *msg)
+soup_server_unpause_message (SoupServer *server,
+ SoupServerMessage *msg)
{
g_return_if_fail (SOUP_IS_SERVER (server));
- g_return_if_fail (SOUP_IS_MESSAGE (msg));
+ g_return_if_fail (SOUP_IS_SERVER_MESSAGE (msg));
- soup_message_io_unpause (msg);
+ soup_server_message_io_unpause (msg);
}
/**
diff --git a/libsoup/server/soup-server.h b/libsoup/server/soup-server.h
index eb9a13b7..b5225207 100644
--- a/libsoup/server/soup-server.h
+++ b/libsoup/server/soup-server.h
@@ -15,11 +15,6 @@ G_BEGIN_DECLS
SOUP_AVAILABLE_IN_2_4
G_DECLARE_DERIVABLE_TYPE (SoupServer, soup_server, SOUP, SERVER, GObject)
-typedef struct _SoupClientContext SoupClientContext;
-SOUP_AVAILABLE_IN_2_4
-GType soup_client_context_get_type (void);
-#define SOUP_TYPE_CLIENT_CONTEXT (soup_client_context_get_type ())
-
typedef enum {
SOUP_SERVER_LISTEN_HTTPS = (1 << 0),
SOUP_SERVER_LISTEN_IPV4_ONLY = (1 << 1),
@@ -30,14 +25,14 @@ struct _SoupServerClass {
GObjectClass parent_class;
/* signals */
- void (*request_started) (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client);
- void (*request_read) (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client);
- void (*request_finished) (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client);
- void (*request_aborted) (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client);
+ void (*request_started) (SoupServer *server,
+ SoupServerMessage *msg);
+ void (*request_read) (SoupServer *server,
+ SoupServerMessage *msg);
+ void (*request_finished) (SoupServer *server,
+ SoupServerMessage *msg);
+ void (*request_aborted) (SoupServer *server,
+ SoupServerMessage *msg);
gpointer padding[6];
};
@@ -98,10 +93,9 @@ gboolean soup_server_accept_iostream (SoupServer *server
/* Handlers and auth */
typedef void (*SoupServerCallback) (SoupServer *server,
- SoupMessage *msg,
+ SoupServerMessage *msg,
const char *path,
GHashTable *query,
- SoupClientContext *client,
gpointer user_data);
SOUP_AVAILABLE_IN_2_4
@@ -121,9 +115,9 @@ void soup_server_add_early_handler (SoupServer *server,
#define SOUP_SERVER_REMOVE_WEBSOCKET_EXTENSION "remove-websocket-extension"
typedef void (*SoupServerWebsocketCallback) (SoupServer *server,
- SoupWebsocketConnection *connection,
+ SoupServerMessage *msg,
const char *path,
- SoupClientContext *client,
+ SoupWebsocketConnection *connection,
gpointer user_data);
SOUP_AVAILABLE_IN_2_50
void soup_server_add_websocket_handler (SoupServer *server,
@@ -153,28 +147,10 @@ void soup_server_remove_auth_domain (SoupServer *server,
/* I/O */
SOUP_AVAILABLE_IN_2_4
-void soup_server_pause_message (SoupServer *server,
- SoupMessage *msg);
-SOUP_AVAILABLE_IN_2_4
-void soup_server_unpause_message (SoupServer *server,
- SoupMessage *msg);
-
-/* Client context */
-
-SOUP_AVAILABLE_IN_2_48
-GSocket *soup_client_context_get_socket (SoupClientContext *client);
-SOUP_AVAILABLE_IN_2_48
-GSocketAddress *soup_client_context_get_local_address (SoupClientContext *client);
-SOUP_AVAILABLE_IN_2_48
-GSocketAddress *soup_client_context_get_remote_address (SoupClientContext *client);
-SOUP_AVAILABLE_IN_2_4
-const char *soup_client_context_get_host (SoupClientContext *client);
+void soup_server_pause_message (SoupServer *server,
+ SoupServerMessage *msg);
SOUP_AVAILABLE_IN_2_4
-SoupAuthDomain *soup_client_context_get_auth_domain (SoupClientContext *client);
-SOUP_AVAILABLE_IN_2_4
-const char *soup_client_context_get_auth_user (SoupClientContext *client);
-
-SOUP_AVAILABLE_IN_2_50
-GIOStream *soup_client_context_steal_connection (SoupClientContext *client);
+void soup_server_unpause_message (SoupServer *server,
+ SoupServerMessage *msg);
G_END_DECLS
diff --git a/libsoup/soup-client-input-stream.c b/libsoup/soup-client-input-stream.c
index 16abb411..8fa28c0b 100644
--- a/libsoup/soup-client-input-stream.c
+++ b/libsoup/soup-client-input-stream.c
@@ -193,8 +193,9 @@ soup_client_input_stream_close_async (GInputStream *stream,
g_task_set_priority (task, priority);
if (close_async_ready (cistream->priv->msg, task) == G_SOURCE_CONTINUE) {
- source = soup_message_io_get_source (cistream->priv->msg,
- cancellable, NULL, NULL);
+ source = soup_message_io_data_get_source ((SoupMessageIOData *)soup_message_get_io_data (cistream->priv->msg),
+ G_OBJECT (cistream->priv->msg),
+ cancellable, NULL, NULL);
g_task_attach_source (task, source, (GSourceFunc) close_async_ready);
g_source_unref (source);
diff --git a/libsoup/soup-connection.c b/libsoup/soup-connection.c
index df2cdb59..6e39bc7c 100644
--- a/libsoup/soup-connection.c
+++ b/libsoup/soup-connection.c
@@ -730,10 +730,10 @@ soup_connection_get_ever_used (SoupConnection *conn)
}
void
-soup_connection_send_request (SoupConnection *conn,
- SoupMessageQueueItem *item,
- SoupMessageCompletionFn completion_cb,
- gpointer user_data)
+soup_connection_send_request (SoupConnection *conn,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data)
{
SoupConnectionPrivate *priv;
diff --git a/libsoup/soup-connection.h b/libsoup/soup-connection.h
index 19888f1f..00c030cf 100644
--- a/libsoup/soup-connection.h
+++ b/libsoup/soup-connection.h
@@ -71,10 +71,10 @@ void soup_connection_set_state (SoupConnection *conn,
gboolean soup_connection_get_ever_used (SoupConnection *conn);
-void soup_connection_send_request (SoupConnection *conn,
- SoupMessageQueueItem *item,
- SoupMessageCompletionFn completion_cb,
- gpointer user_data);
+void soup_connection_send_request (SoupConnection *conn,
+ SoupMessageQueueItem *item,
+ SoupMessageIOCompletionFn completion_cb,
+ gpointer user_data);
G_END_DECLS
diff --git a/libsoup/soup-form.c b/libsoup/soup-form.c
index 32e7de3c..e73cca93 100644
--- a/libsoup/soup-form.c
+++ b/libsoup/soup-form.c
@@ -112,13 +112,13 @@ soup_form_decode (const char *encoded_form)
/**
* soup_form_decode_multipart:
- * @msg: a #SoupMessage containing a "multipart/form-data" request body
+ * @multipart: a #SoupMultipart
* @file_control_name: (allow-none): the name of the HTML file upload control, or %NULL
* @filename: (out) (allow-none): return location for the name of the uploaded file, or %NULL
* @content_type: (out) (allow-none): return location for the MIME type of the uploaded file, or %NULL
* @file: (out) (allow-none): return location for the uploaded file data, or %NULL
*
- * Decodes the "multipart/form-data" request in @msg; this is a
+ * Decodes the "multipart/form-data" request in @multipart; this is a
* convenience method for the case when you have a single file upload
* control in a form. (Or when you don't have any file upload
* controls, but are still using "multipart/form-data" anyway.) Pass
@@ -142,29 +142,21 @@ soup_form_decode (const char *encoded_form)
* a hash table containing the name/value pairs (other than
* @file_control_name) from @msg, which you can free with
* g_hash_table_destroy(). On error, it will return %NULL.
- *
- * Since: 2.26
- **/
+ */
GHashTable *
-soup_form_decode_multipart (SoupMessage *msg, const char *file_control_name,
- char **filename, char **content_type,
- GBytes **file)
+soup_form_decode_multipart (SoupMultipart *multipart,
+ const char *file_control_name,
+ char **filename,
+ char **content_type,
+ GBytes **file)
{
- SoupMultipart *multipart;
GHashTable *form_data_set, *params;
SoupMessageHeaders *part_headers;
- GBytes *body;
GBytes *part_body;
char *disposition, *name;
int i;
- g_return_val_if_fail (SOUP_IS_MESSAGE (msg), NULL);
-
- body = soup_message_body_flatten (msg->request_body);
- multipart = soup_multipart_new_from_message (msg->request_headers, body);
- g_bytes_unref (body);
- if (!multipart)
- return NULL;
+ g_return_val_if_fail (multipart != NULL, NULL);
if (filename)
*filename = NULL;
diff --git a/libsoup/soup-form.h b/libsoup/soup-form.h
index 4880e7be..27ca8aa1 100644
--- a/libsoup/soup-form.h
+++ b/libsoup/soup-form.h
@@ -17,11 +17,11 @@ G_BEGIN_DECLS
SOUP_AVAILABLE_IN_2_4
GHashTable *soup_form_decode (const char *encoded_form);
SOUP_AVAILABLE_IN_2_26
-GHashTable *soup_form_decode_multipart (SoupMessage *msg,
- const char *file_control_name,
- char **filename,
- char **content_type,
- GBytes **file);
+GHashTable *soup_form_decode_multipart (SoupMultipart *multipart,
+ const char *file_control_name,
+ char **filename,
+ char **content_type,
+ GBytes **file);
SOUP_AVAILABLE_IN_2_4
char *soup_form_encode (const char *first_field,
diff --git a/libsoup/soup-headers.c b/libsoup/soup-headers.c
index fbe1e986..5a54b012 100644
--- a/libsoup/soup-headers.c
+++ b/libsoup/soup-headers.c
@@ -195,7 +195,7 @@ soup_headers_parse_request (const char *str,
unsigned long major_version, minor_version;
char *p;
- g_return_val_if_fail (str != NULL, SOUP_STATUS_MALFORMED);
+ g_return_val_if_fail (str != NULL, SOUP_STATUS_BAD_REQUEST);
/* RFC 2616 4.1 "servers SHOULD ignore any empty line(s)
* received where a Request-Line is expected."
diff --git a/libsoup/soup-logger.c b/libsoup/soup-logger.c
index d76701a2..402f4f57 100644
--- a/libsoup/soup-logger.c
+++ b/libsoup/soup-logger.c
@@ -597,22 +597,6 @@ print_request (SoupLogger *logger, SoupMessage *msg,
"%s: %s", name, value);
}
}
- if (log_level == SOUP_LOGGER_LOG_HEADERS)
- return;
-
- if (msg->request_body->length &&
- soup_message_body_get_accumulate (msg->request_body)) {
- GBytes *request;
-
- request = soup_message_body_flatten (msg->request_body);
- g_return_if_fail (request != NULL);
- g_bytes_unref (request);
-
- if (soup_message_headers_get_expectations (msg->request_headers) != SOUP_EXPECTATION_CONTINUE) {
- soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '>',
- "\n%s", msg->request_body->data);
- }
- }
}
static void
@@ -653,13 +637,6 @@ print_response (SoupLogger *logger, SoupMessage *msg)
soup_logger_print (logger, SOUP_LOGGER_LOG_HEADERS, '<',
"%s: %s", name, value);
}
- if (log_level == SOUP_LOGGER_LOG_HEADERS)
- return;
-
- if (msg->response_body->data) {
- soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '<',
- "\n%s", msg->response_body->data);
- }
}
static void
@@ -688,23 +665,9 @@ got_informational (SoupMessage *msg, gpointer user_data)
print_response (logger, msg);
soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', "\n");
- if (msg->status_code == SOUP_STATUS_CONTINUE && msg->request_body->data) {
- SoupLoggerLogLevel log_level;
-
+ if (msg->status_code == SOUP_STATUS_CONTINUE && msg->request_body_stream) {
soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, '>',
"[Now sending request body...]");
-
- if (priv->request_filter) {
- log_level = priv->request_filter (logger, msg,
- priv->request_filter_data);
- } else
- log_level = priv->level;
-
- if (log_level == SOUP_LOGGER_LOG_BODY) {
- soup_logger_print (logger, SOUP_LOGGER_LOG_BODY, '>',
- "%s", msg->request_body->data);
- }
-
soup_logger_print (logger, SOUP_LOGGER_LOG_MINIMAL, ' ', "\n");
}
diff --git a/libsoup/soup-message-io-data.c b/libsoup/soup-message-io-data.c
new file mode 100644
index 00000000..8af99467
--- /dev/null
+++ b/libsoup/soup-message-io-data.c
@@ -0,0 +1,266 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * soup-message-io-data.c: HTTP message I/O data
+ *
+ * Copyright (C) 2000-2003, Ximian, Inc.
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <glib/gi18n-lib.h>
+
+#include "soup-message-io-data.h"
+#include "soup-message-private.h"
+#include "soup-server-message-private.h"
+#include "soup.h"
+
+#define RESPONSE_BLOCK_SIZE 8192
+#define HEADER_SIZE_LIMIT (64 * 1024)
+
+void
+soup_message_io_data_cleanup (SoupMessageIOData *io)
+{
+ if (io->io_source) {
+ g_source_destroy (io->io_source);
+ g_source_unref (io->io_source);
+ io->io_source = NULL;
+ }
+
+ if (io->iostream)
+ g_object_unref (io->iostream);
+ if (io->body_istream)
+ g_object_unref (io->body_istream);
+ if (io->body_ostream)
+ g_object_unref (io->body_ostream);
+ if (io->async_context)
+ g_main_context_unref (io->async_context);
+
+ g_byte_array_free (io->read_header_buf, TRUE);
+
+ g_string_free (io->write_buf, TRUE);
+
+ if (io->async_wait) {
+ g_cancellable_cancel (io->async_wait);
+ g_clear_object (&io->async_wait);
+ }
+ g_clear_error (&io->async_error);
+}
+
+gboolean
+soup_message_io_data_read_headers (SoupMessageIOData *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error)
+{
+ gssize nread, old_len;
+ gboolean got_lf;
+
+ while (1) {
+ old_len = io->read_header_buf->len;
+ g_byte_array_set_size (io->read_header_buf, old_len + RESPONSE_BLOCK_SIZE);
+ nread = soup_filter_input_stream_read_line (io->istream,
+ io->read_header_buf->data + old_len,
+ RESPONSE_BLOCK_SIZE,
+ blocking,
+ &got_lf,
+ cancellable, error);
+ io->read_header_buf->len = old_len + MAX (nread, 0);
+ if (nread == 0) {
+ if (io->read_header_buf->len > 0)
+ break;
+
+ g_set_error_literal (error, G_IO_ERROR,
+ G_IO_ERROR_PARTIAL_INPUT,
+ _("Connection terminated unexpectedly"));
+ }
+ if (nread <= 0)
+ return FALSE;
+
+ if (got_lf) {
+ if (nread == 1 && old_len >= 2 &&
+ !strncmp ((char *)io->read_header_buf->data +
+ io->read_header_buf->len - 2,
+ "\n\n", 2)) {
+ io->read_header_buf->len--;
+ break;
+ } else if (nread == 2 && old_len >= 3 &&
+ !strncmp ((char *)io->read_header_buf->data +
+ io->read_header_buf->len - 3,
+ "\n\r\n", 3)) {
+ io->read_header_buf->len -= 2;
+ break;
+ }
+ }
+
+ if (io->read_header_buf->len > HEADER_SIZE_LIMIT) {
+ g_set_error_literal (error, G_IO_ERROR,
+ G_IO_ERROR_PARTIAL_INPUT,
+ _("Header too big"));
+ return FALSE;
+ }
+ }
+
+ io->read_header_buf->data[io->read_header_buf->len] = '\0';
+ return TRUE;
+}
+
+static gboolean
+message_io_is_paused (GObject *msg)
+{
+ if (SOUP_IS_MESSAGE (msg))
+ return soup_message_is_io_paused (SOUP_MESSAGE (msg));
+
+ if (SOUP_IS_SERVER_MESSAGE (msg))
+ return soup_server_message_is_io_paused (SOUP_SERVER_MESSAGE (msg));
+
+ return FALSE;
+}
+
+typedef struct {
+ GSource source;
+ GObject *msg;
+ gboolean paused;
+} SoupMessageIOSource;
+
+static gboolean
+message_io_source_check (GSource *source)
+{
+ SoupMessageIOSource *message_source = (SoupMessageIOSource *)source;
+
+ if (message_source->paused) {
+ if (message_io_is_paused (message_source->msg))
+ return FALSE;
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+static gboolean
+message_io_source_prepare (GSource *source,
+ gint *timeout)
+{
+ *timeout = -1;
+ return message_io_source_check (source);
+}
+
+static gboolean
+message_io_source_dispatch (GSource *source,
+ GSourceFunc callback,
+ gpointer user_data)
+{
+ SoupMessageIOSourceFunc func = (SoupMessageIOSourceFunc)callback;
+ SoupMessageIOSource *message_source = (SoupMessageIOSource *)source;
+
+ return (*func) (message_source->msg, user_data);
+}
+
+static void
+message_io_source_finalize (GSource *source)
+{
+ SoupMessageIOSource *message_source = (SoupMessageIOSource *)source;
+
+ g_object_unref (message_source->msg);
+}
+
+static gboolean
+message_io_source_closure_callback (GObject *msg,
+ gpointer data)
+{
+ GClosure *closure = data;
+ GValue param = G_VALUE_INIT;
+ GValue result_value = G_VALUE_INIT;
+ gboolean result;
+
+ g_value_init (&result_value, G_TYPE_BOOLEAN);
+
+ g_value_init (&param, G_TYPE_OBJECT);
+ g_value_set_object (&param, msg);
+
+ g_closure_invoke (closure, &result_value, 1, &param, NULL);
+
+ result = g_value_get_boolean (&result_value);
+ g_value_unset (&result_value);
+ g_value_unset (&param);
+
+ return result;
+}
+
+static GSourceFuncs message_io_source_funcs =
+{
+ message_io_source_prepare,
+ message_io_source_check,
+ message_io_source_dispatch,
+ message_io_source_finalize,
+ (GSourceFunc)message_io_source_closure_callback,
+ (GSourceDummyMarshal)g_cclosure_marshal_generic,
+};
+
+GSource *
+soup_message_io_data_get_source (SoupMessageIOData *io,
+ GObject *msg,
+ GCancellable *cancellable,
+ SoupMessageIOSourceFunc callback,
+ gpointer user_data)
+{
+ GSource *base_source, *source;
+ SoupMessageIOSource *message_source;
+
+ if (!io) {
+ base_source = g_timeout_source_new (0);
+ } else if (io->paused) {
+ base_source = NULL;
+ } else if (io->async_wait) {
+ base_source = g_cancellable_source_new (io->async_wait);
+ } else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->read_state)) {
+ GPollableInputStream *istream;
+
+ if (io->body_istream)
+ istream = G_POLLABLE_INPUT_STREAM (io->body_istream);
+ else
+ istream = G_POLLABLE_INPUT_STREAM (io->istream);
+ base_source = g_pollable_input_stream_create_source (istream, cancellable);
+ } else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->write_state)) {
+ GPollableOutputStream *ostream;
+
+ if (io->body_ostream)
+ ostream = G_POLLABLE_OUTPUT_STREAM (io->body_ostream);
+ else
+ ostream = G_POLLABLE_OUTPUT_STREAM (io->ostream);
+ base_source = g_pollable_output_stream_create_source (ostream, cancellable);
+ } else
+ base_source = g_timeout_source_new (0);
+
+ source = g_source_new (&message_io_source_funcs, sizeof (SoupMessageIOSource));
+ g_source_set_name (source, "SoupMessageIOSource");
+ message_source = (SoupMessageIOSource *)source;
+ message_source->msg = g_object_ref (msg);
+ message_source->paused = io && io->paused;
+
+ if (base_source) {
+ g_source_set_dummy_callback (base_source);
+ g_source_add_child_source (source, base_source);
+ g_source_unref (base_source);
+ }
+ g_source_set_callback (source, (GSourceFunc) callback, user_data, NULL);
+ return source;
+}
+
+void
+soup_message_io_data_pause (SoupMessageIOData *io)
+{
+ if (io->io_source) {
+ g_source_destroy (io->io_source);
+ g_source_unref (io->io_source);
+ io->io_source = NULL;
+ }
+
+ io->paused = TRUE;
+}
+
+void
+soup_message_io_data_unpause (SoupMessageIOData *io)
+{
+ io->paused = FALSE;
+}
diff --git a/libsoup/soup-message-io-data.h b/libsoup/soup-message-io-data.h
new file mode 100644
index 00000000..0476a425
--- /dev/null
+++ b/libsoup/soup-message-io-data.h
@@ -0,0 +1,99 @@
+/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+/*
+ * Copyright (C) 2000-2003, Ximian, Inc.
+ */
+
+#ifndef __SOUP_MESSAGE_IO_DATA_H__
+#define __SOUP_MESSAGE_IO_DATA_H__ 1
+
+#include "soup-filter-input-stream.h"
+#include "soup-message-headers.h"
+
+typedef enum {
+ SOUP_MESSAGE_IO_STATE_NOT_STARTED,
+ SOUP_MESSAGE_IO_STATE_ANY = SOUP_MESSAGE_IO_STATE_NOT_STARTED,
+ SOUP_MESSAGE_IO_STATE_HEADERS,
+ SOUP_MESSAGE_IO_STATE_BLOCKING,
+ SOUP_MESSAGE_IO_STATE_BODY_START,
+ SOUP_MESSAGE_IO_STATE_BODY,
+ SOUP_MESSAGE_IO_STATE_BODY_DATA,
+ SOUP_MESSAGE_IO_STATE_BODY_FLUSH,
+ SOUP_MESSAGE_IO_STATE_BODY_DONE,
+ SOUP_MESSAGE_IO_STATE_FINISHING,
+ SOUP_MESSAGE_IO_STATE_DONE
+} SoupMessageIOState;
+
+#define SOUP_MESSAGE_IO_STATE_ACTIVE(state) \
+ (state != SOUP_MESSAGE_IO_STATE_NOT_STARTED && \
+ state != SOUP_MESSAGE_IO_STATE_BLOCKING && \
+ state != SOUP_MESSAGE_IO_STATE_DONE)
+#define SOUP_MESSAGE_IO_STATE_POLLABLE(state) \
+ (SOUP_MESSAGE_IO_STATE_ACTIVE (state) && \
+ state != SOUP_MESSAGE_IO_STATE_BODY_DONE)
+
+typedef enum {
+ SOUP_MESSAGE_IO_COMPLETE,
+ SOUP_MESSAGE_IO_INTERRUPTED,
+ SOUP_MESSAGE_IO_STOLEN
+} SoupMessageIOCompletion;
+
+typedef void (*SoupMessageIOCompletionFn) (GObject *msg,
+ SoupMessageIOCompletion completion,
+ gpointer user_data);
+
+typedef struct {
+ GIOStream *iostream;
+ SoupFilterInputStream *istream;
+ GInputStream *body_istream;
+ GOutputStream *ostream;
+ GOutputStream *body_ostream;
+ GMainContext *async_context;
+
+ SoupMessageIOState read_state;
+ SoupEncoding read_encoding;
+ GByteArray *read_header_buf;
+ goffset read_length;
+
+ SoupMessageIOState write_state;
+ SoupEncoding write_encoding;
+ GString *write_buf;
+ GBytes *write_chunk;
+ goffset write_body_offset;
+ goffset write_length;
+ goffset written;
+
+ GSource *io_source;
+ gboolean paused;
+
+ GCancellable *async_wait;
+ GError *async_error;
+
+ SoupMessageIOCompletionFn completion_cb;
+ gpointer completion_data;
+
+#ifdef HAVE_SYSPROF
+ gint64 begin_time_nsec;
+#endif
+} SoupMessageIOData;
+
+void soup_message_io_data_cleanup (SoupMessageIOData *io);
+
+gboolean soup_message_io_data_read_headers (SoupMessageIOData *io,
+ gboolean blocking,
+ GCancellable *cancellable,
+ GError **error);
+
+typedef gboolean (*SoupMessageIOSourceFunc) (GObject *msg,
+ gpointer user_data);
+
+GSource *soup_message_io_data_get_source (SoupMessageIOData *io,
+ GObject *msg,
+ GCancellable *cancellable,
+ SoupMessageIOSourceFunc callback,
+ gpointer user_data);
+
+void soup_message_io_data_pause (SoupMessageIOData *io);
+void soup_message_io_data_unpause (SoupMessageIOData *io);
+
+
+#endif /* __SOUP_MESSAGE_IO_DATA_H__ */
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c
index bfa14417..efa84ef6 100644
--- a/libsoup/soup-message-io.c
+++ b/libsoup/soup-message-io.c
@@ -28,60 +28,37 @@
#include "soup-misc.h"
#include "soup-socket-private.h"
+struct _SoupClientMessageIOData {
+ SoupMessageIOData base;
+
+ SoupMessageQueueItem *item;
+ GCancellable *cancellable;
+
+#ifdef HAVE_SYSPROF
+ gint64 begin_time_nsec;
+#endif
+};
+
#define RESPONSE_BLOCK_SIZE 8192
#define HEADER_SIZE_LIMIT (64 * 1024)
void
-soup_message_io_cleanup (SoupMessage *msg)
+soup_client_message_io_data_free (SoupClientMessageIOData *io)
{
- SoupMessageIOData *io;
-
- io = soup_message_get_io_data (msg);
if (!io)
return;
- if (io->io_source) {
- g_source_destroy (io->io_source);
- g_source_unref (io->io_source);
- io->io_source = NULL;
- }
-
- if (io->unpause_source) {
- g_source_destroy (io->unpause_source);
- g_source_unref (io->unpause_source);
- io->unpause_source = NULL;
- }
+ soup_message_io_data_cleanup (&io->base);
+ soup_message_queue_item_unref (io->item);
- if (io->iostream)
- g_object_unref (io->iostream);
- if (io->body_istream)
- g_object_unref (io->body_istream);
- if (io->body_ostream)
- g_object_unref (io->body_ostream);
- if (io->async_context)
- g_main_context_unref (io->async_context);
- if (io->item)
- soup_message_queue_item_unref (io->item);
-
- g_byte_array_free (io->read_header_buf, TRUE);
-
- g_string_free (io->write_buf, TRUE);
- g_clear_pointer (&io->write_chunk, g_bytes_unref);
-
- if (io->async_wait) {
- g_cancellable_cancel (io->async_wait);
- g_clear_object (&io->async_wait);
- }
- g_clear_error (&io->async_error);
-
- g_slice_free (SoupMessageIOData, io);
+ g_slice_free (SoupClientMessageIOData, io);
}
void
soup_message_io_finished (SoupMessage *msg)
{
- SoupMessageIOData *io;
- SoupMessageCompletionFn completion_cb;
+ SoupClientMessageIOData *io;
+ SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
SoupMessageIOCompletion completion;
@@ -89,11 +66,11 @@ soup_message_io_finished (SoupMessage *msg)
if (!io)
return;
- completion_cb = io->completion_cb;
- completion_data = io->completion_data;
+ completion_cb = io->base.completion_cb;
+ completion_data = io->base.completion_data;
- if ((io->read_state >= SOUP_MESSAGE_IO_STATE_FINISHING &&
- io->write_state >= SOUP_MESSAGE_IO_STATE_FINISHING))
+ if ((io->base.read_state >= SOUP_MESSAGE_IO_STATE_FINISHING &&
+ io->base.write_state >= SOUP_MESSAGE_IO_STATE_FINISHING))
completion = SOUP_MESSAGE_IO_COMPLETE;
else
completion = SOUP_MESSAGE_IO_INTERRUPTED;
@@ -101,96 +78,35 @@ soup_message_io_finished (SoupMessage *msg)
g_object_ref (msg);
soup_message_set_io_data (msg, NULL);
if (completion_cb)
- completion_cb (msg, completion, completion_data);
+ completion_cb (G_OBJECT (msg), completion, completion_data);
g_object_unref (msg);
}
GIOStream *
soup_message_io_steal (SoupMessage *msg)
{
- SoupMessageIOData *io;
- SoupMessageCompletionFn completion_cb;
+ SoupClientMessageIOData *io;
+ SoupMessageIOCompletionFn completion_cb;
gpointer completion_data;
GIOStream *iostream;
io = soup_message_get_io_data (msg);
- if (!io || !io->iostream)
+ if (!io || !io->base.iostream)
return NULL;
- iostream = g_object_ref (io->iostream);
- completion_cb = io->completion_cb;
- completion_data = io->completion_data;
+ iostream = g_object_ref (io->base.iostream);
+ completion_cb = io->base.completion_cb;
+ completion_data = io->base.completion_data;
g_object_ref (msg);
soup_message_set_io_data (msg, NULL);
if (completion_cb)
- completion_cb (msg, SOUP_MESSAGE_IO_STOLEN, completion_data);
+ completion_cb (G_OBJECT (msg), SOUP_MESSAGE_IO_STOLEN, completion_data);
g_object_unref (msg);
return iostream;
}
-gboolean
-soup_message_io_read_headers (SoupMessage *msg,
- SoupFilterInputStream *stream,
- GByteArray *buffer,
- gboolean blocking,
- GCancellable *cancellable,
- GError **error)
-{
- gssize nread, old_len;
- gboolean got_lf;
-
- while (1) {
- old_len = buffer->len;
- g_byte_array_set_size (buffer, old_len + RESPONSE_BLOCK_SIZE);
- nread = soup_filter_input_stream_read_line (stream,
- buffer->data + old_len,
- RESPONSE_BLOCK_SIZE,
- blocking,
- &got_lf,
- cancellable, error);
- buffer->len = old_len + MAX (nread, 0);
- if (nread == 0) {
- if (buffer->len > 0)
- break;
- soup_message_set_status (msg, SOUP_STATUS_MALFORMED);
- g_set_error_literal (error, G_IO_ERROR,
- G_IO_ERROR_PARTIAL_INPUT,
- _("Connection terminated unexpectedly"));
- }
- if (nread <= 0)
- return FALSE;
-
- if (got_lf) {
- if (nread == 1 && old_len >= 2 &&
- !strncmp ((char *)buffer->data +
- buffer->len - 2,
- "\n\n", 2)) {
- buffer->len--;
- break;
- } else if (nread == 2 && old_len >= 3 &&
- !strncmp ((char *)buffer->data +
- buffer->len - 3,
- "\n\r\n", 3)) {
- buffer->len -= 2;
- break;
- }
- }
-
- if (buffer->len > HEADER_SIZE_LIMIT) {
- soup_message_set_status (msg, SOUP_STATUS_MALFORMED);
- g_set_error_literal (error, G_IO_ERROR,
- G_IO_ERROR_PARTIAL_INPUT,
- _("Header too big"));
- return FALSE;
- }
- }
-
- buffer->data[buffer->len] = '\0';
- return TRUE;
-}
-
static gint
processing_stage_cmp (gconstpointer a,
gconstpointer b)
@@ -257,7 +173,7 @@ request_body_stream_wrote_cb (GOutputStream *ostream,
GAsyncResult *result,
SoupMessage *msg)
{
- SoupMessageIOData *io;
+ SoupClientMessageIOData *io;
gssize nwrote;
GCancellable *async_wait;
GError *error = NULL;
@@ -265,19 +181,19 @@ request_body_stream_wrote_cb (GOutputStream *ostream,
nwrote = g_output_stream_splice_finish (ostream, result, &error);
io = soup_message_get_io_data (msg);
- if (!io || !io->async_wait || io->body_ostream != ostream) {
+ if (!io || !io->base.async_wait || io->base.body_ostream != ostream) {
g_clear_error (&error);
g_object_unref (msg);
return;
}
if (nwrote != -1)
- io->write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH;
+ io->base.write_state = SOUP_MESSAGE_IO_STATE_BODY_FLUSH;
if (error)
- g_propagate_error (&io->async_error, error);
- async_wait = io->async_wait;
- io->async_wait = NULL;
+ g_propagate_error (&io->base.async_error, error);
+ async_wait = io->base.async_wait;
+ io->base.async_wait = NULL;
g_cancellable_cancel (async_wait);
g_object_unref (async_wait);
@@ -291,20 +207,20 @@ closed_async (GObject *source,
{
GOutputStream *body_ostream = G_OUTPUT_STREAM (source);
SoupMessage *msg = user_data;
- SoupMessageIOData *io;
+ SoupClientMessageIOData *io;
GCancellable *async_wait;
io = soup_message_get_io_data (msg);
- if (!io || !io->async_wait || io->body_ostream != body_ostream) {
+ if (!io || !io->base.async_wait || io->base.body_ostream != body_ostream) {
g_object_unref (msg);
return;
}
- g_output_stream_close_finish (body_ostream, result, &io->async_error);
- g_clear_object (&io->body_ostream);
+ g_output_stream_close_finish (body_ostream, result, &io->base.async_error);
+ g_clear_object (&io->base.body_ostream);
- async_wait = io->async_wait;
- io->async_wait = NULL;
+ async_wait = io->base.async_wait;
+ io->base.async_wait = NULL;
g_cancellable_cancel (async_wait);
g_object_unref (async_wait);
@@ -393,15 +309,6 @@ write_headers (SoupMessage *msg,
g_free (uri_host);
*encoding = soup_message_headers_get_encoding (msg->request_headers);
- if ((*encoding == SOUP_ENCODING_CONTENT_LENGTH ||
- *encoding == SOUP_ENCODING_NONE) &&
- (msg->request_body->length > 0 ||
- soup_message_headers_get_one (msg->request_headers, "Content-Type")) &&
- !soup_message_headers_get_content_length (msg->request_headers)) {
- *encoding = SOUP_ENCODING_CONTENT_LENGTH;
- soup_message_headers_set_content_length (msg->request_headers,
- msg->request_body->length);
- }
soup_message_headers_iter_init (&iter, msg->request_headers);
while (soup_message_headers_iter_next (&iter, &name, &value))
@@ -419,7 +326,8 @@ static gboolean
io_write (SoupMessage *msg, gboolean blocking,
GCancellable *cancellable, GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOData *io = &client_io->base;
gssize nwrote;
if (io->async_error) {
@@ -436,7 +344,7 @@ io_write (SoupMessage *msg, gboolean blocking,
switch (io->write_state) {
case SOUP_MESSAGE_IO_STATE_HEADERS:
if (!io->write_buf->len)
- write_headers (msg, io->write_buf, io->item->conn, &io->write_encoding);
+ write_headers (msg, io->write_buf, client_io->item->conn, &io->write_encoding);
while (io->written < io->write_buf->len) {
nwrote = g_pollable_stream_write (io->ostream,
@@ -607,13 +515,17 @@ static gboolean
io_read (SoupMessage *msg, gboolean blocking,
GCancellable *cancellable, GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOData *io = &client_io->base;
guint status;
switch (io->read_state) {
case SOUP_MESSAGE_IO_STATE_HEADERS:
- if (!soup_message_io_read_headers (msg, io->istream, io->read_header_buf, blocking, cancellable, error))
+ if (!soup_message_io_data_read_headers (io, blocking, cancellable, error)) {
+ if (g_error_matches (*error, G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT))
+ soup_message_set_status (msg, SOUP_STATUS_MALFORMED);
return FALSE;
+ }
status = parse_headers (msg,
(char *)io->read_header_buf->data,
@@ -658,7 +570,7 @@ io_read (SoupMessage *msg, gboolean blocking,
/* If this was "101 Switching Protocols", then
* the session may have stolen the connection...
*/
- if (io != soup_message_get_io_data (msg))
+ if (client_io != soup_message_get_io_data (msg))
return FALSE;
soup_message_cleanup_response (msg);
@@ -698,7 +610,7 @@ io_read (SoupMessage *msg, gboolean blocking,
io->read_length);
io->body_istream = soup_message_setup_body_istream (body_istream, msg,
- io->item->session,
+ client_io->item->session,
SOUP_STAGE_MESSAGE_BODY);
g_object_unref (body_istream);
}
@@ -753,148 +665,18 @@ io_read (SoupMessage *msg, gboolean blocking,
return TRUE;
}
-typedef struct {
- GSource source;
- SoupMessage *msg;
- gboolean paused;
-} SoupMessageSource;
-
-static gboolean
-message_source_check (GSource *source)
-{
- SoupMessageSource *message_source = (SoupMessageSource *)source;
-
- if (message_source->paused) {
- SoupMessageIOData *io = soup_message_get_io_data (message_source->msg);
-
- if (io && io->paused)
- return FALSE;
- else
- return TRUE;
- } else
- return FALSE;
-}
-
-static gboolean
-message_source_prepare (GSource *source,
- gint *timeout)
-{
- *timeout = -1;
- return message_source_check (source);
-}
-
-static gboolean
-message_source_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data)
-{
- SoupMessageSourceFunc func = (SoupMessageSourceFunc)callback;
- SoupMessageSource *message_source = (SoupMessageSource *)source;
-
- return (*func) (message_source->msg, user_data);
-}
-
-static void
-message_source_finalize (GSource *source)
-{
- SoupMessageSource *message_source = (SoupMessageSource *)source;
-
- g_object_unref (message_source->msg);
-}
-
-static gboolean
-message_source_closure_callback (SoupMessage *msg,
- gpointer data)
-{
- GClosure *closure = data;
- GValue param = G_VALUE_INIT;
- GValue result_value = G_VALUE_INIT;
- gboolean result;
-
- g_value_init (&result_value, G_TYPE_BOOLEAN);
-
- g_value_init (&param, SOUP_TYPE_MESSAGE);
- g_value_set_object (&param, msg);
-
- g_closure_invoke (closure, &result_value, 1, &param, NULL);
-
- result = g_value_get_boolean (&result_value);
- g_value_unset (&result_value);
- g_value_unset (&param);
-
- return result;
-}
-
-static GSourceFuncs message_source_funcs =
-{
- message_source_prepare,
- message_source_check,
- message_source_dispatch,
- message_source_finalize,
- (GSourceFunc)message_source_closure_callback,
- (GSourceDummyMarshal)g_cclosure_marshal_generic,
-};
-
-GSource *
-soup_message_io_get_source (SoupMessage *msg, GCancellable *cancellable,
- SoupMessageSourceFunc callback, gpointer user_data)
-{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
- GSource *base_source, *source;
- SoupMessageSource *message_source;
-
- if (!io) {
- base_source = g_timeout_source_new (0);
- } else if (io->paused) {
- base_source = NULL;
- } else if (io->async_wait) {
- base_source = g_cancellable_source_new (io->async_wait);
- } else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->read_state)) {
- GPollableInputStream *istream;
-
- if (io->body_istream)
- istream = G_POLLABLE_INPUT_STREAM (io->body_istream);
- else
- istream = G_POLLABLE_INPUT_STREAM (io->istream);
- base_source = g_pollable_input_stream_create_source (istream, cancellable);
- } else if (SOUP_MESSAGE_IO_STATE_POLLABLE (io->write_state)) {
- GPollableOutputStream *ostream;
-
- if (io->body_ostream)
- ostream = G_POLLABLE_OUTPUT_STREAM (io->body_ostream);
- else
- ostream = G_POLLABLE_OUTPUT_STREAM (io->ostream);
- base_source = g_pollable_output_stream_create_source (ostream, cancellable);
- } else
- base_source = g_timeout_source_new (0);
-
- source = g_source_new (&message_source_funcs,
- sizeof (SoupMessageSource));
- g_source_set_name (source, "SoupMessageSource");
- message_source = (SoupMessageSource *)source;
- message_source->msg = g_object_ref (msg);
- message_source->paused = io && io->paused;
-
- if (base_source) {
- g_source_set_dummy_callback (base_source);
- g_source_add_child_source (source, base_source);
- g_source_unref (base_source);
- }
- g_source_set_callback (source, (GSourceFunc) callback, user_data, NULL);
- return source;
-}
-
static gboolean
request_is_restartable (SoupMessage *msg, GError *error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOData *io = &client_io->base;
- if (!io)
+ if (!client_io)
return FALSE;
return (io->read_state <= SOUP_MESSAGE_IO_STATE_HEADERS &&
io->read_header_buf->len == 0 &&
- soup_connection_get_ever_used (io->item->conn) &&
+ soup_connection_get_ever_used (client_io->item->conn) &&
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_TIMED_OUT) &&
!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK) &&
error->domain != G_TLS_ERROR &&
@@ -906,7 +688,8 @@ io_run_until (SoupMessage *msg, gboolean blocking,
SoupMessageIOState read_state, SoupMessageIOState write_state,
GCancellable *cancellable, GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOData *io = &client_io->base;
gboolean progress = TRUE, done;
GError *my_error = NULL;
@@ -921,7 +704,7 @@ io_run_until (SoupMessage *msg, gboolean blocking,
g_object_ref (msg);
- while (progress && soup_message_get_io_data (msg) == io && !io->paused && !io->async_wait &&
+ while (progress && soup_message_get_io_data (msg) == client_io && !io->paused && !io->async_wait &&
(io->read_state < read_state || io->write_state < write_state)) {
if (SOUP_MESSAGE_IO_STATE_ACTIVE (io->read_state))
@@ -945,7 +728,7 @@ io_run_until (SoupMessage *msg, gboolean blocking,
g_propagate_error (error, my_error);
g_object_unref (msg);
return FALSE;
- } else if (soup_message_get_io_data (msg) != io) {
+ } else if (soup_message_get_io_data (msg) != client_io) {
g_set_error_literal (error, G_IO_ERROR,
G_IO_ERROR_CANCELLED,
_("Operation was cancelled"));
@@ -979,7 +762,8 @@ io_run_until (SoupMessage *msg, gboolean blocking,
/* FIXME: Expand and generalise sysprof support:
* https://gitlab.gnome.org/GNOME/sysprof/-/issues/43 */
- sysprof_collector_mark_printf (io->begin_time_nsec, SYSPROF_CAPTURE_CURRENT_TIME - io->begin_time_nsec,
+ sysprof_collector_mark_printf (client_io->begin_time_nsec,
+ SYSPROF_CAPTURE_CURRENT_TIME - client_io->begin_time_nsec,
"libsoup", "message",
"%s request/response to %s: "
"read %" G_GOFFSET_FORMAT "B, "
@@ -1003,7 +787,7 @@ soup_message_io_update_status (SoupMessage *msg,
GError *error)
{
if (g_error_matches (error, SOUP_HTTP_ERROR, SOUP_STATUS_TRY_AGAIN)) {
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
io->item->state = SOUP_MESSAGE_RESTARTING;
} else if (error->domain == G_TLS_ERROR) {
@@ -1029,7 +813,8 @@ void
soup_message_io_run (SoupMessage *msg,
gboolean blocking)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOData *io = &client_io->base;
GError *error = NULL;
GCancellable *cancellable;
@@ -1040,7 +825,7 @@ soup_message_io_run (SoupMessage *msg,
}
g_object_ref (msg);
- cancellable = io->cancellable ? g_object_ref (io->cancellable) : NULL;
+ cancellable = client_io->cancellable ? g_object_ref (client_io->cancellable) : NULL;
if (io_run_until (msg, blocking,
SOUP_MESSAGE_IO_STATE_DONE,
@@ -1049,10 +834,12 @@ soup_message_io_run (SoupMessage *msg,
soup_message_io_finished (msg);
} else if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
g_clear_error (&error);
- io->io_source = soup_message_io_get_source (msg, NULL, io_run_ready, msg);
+ io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg), NULL,
+ (SoupMessageIOSourceFunc)io_run_ready,
+ NULL);
g_source_attach (io->io_source, io->async_context);
} else {
- if (soup_message_get_io_data (msg) == io)
+ if (soup_message_get_io_data (msg) == client_io)
soup_message_io_update_status (msg, error);
g_error_free (error);
@@ -1067,7 +854,7 @@ soup_message_io_run_until_read (SoupMessage *msg,
GCancellable *cancellable,
GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
if (io_run_until (msg, TRUE,
SOUP_MESSAGE_IO_STATE_BODY,
@@ -1098,7 +885,8 @@ static void
io_run_until_read_async (SoupMessage *msg,
GTask *task)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *client_io = soup_message_get_io_data (msg);
+ SoupMessageIOData *io = &client_io->base;
GError *error = NULL;
if (io->io_source) {
@@ -1119,12 +907,14 @@ io_run_until_read_async (SoupMessage *msg,
if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK)) {
g_error_free (error);
- io->io_source = soup_message_io_get_source (msg, NULL, io_run_until_read_ready, task);
+ io->io_source = soup_message_io_data_get_source (io, G_OBJECT (msg), NULL,
+ (SoupMessageIOSourceFunc)io_run_until_read_ready,
+ task);
g_source_attach (io->io_source, io->async_context);
return;
}
- if (soup_message_get_io_data (msg) == io)
+ if (soup_message_get_io_data (msg) == client_io)
soup_message_io_update_status (msg, error);
g_task_return_error (task, error);
@@ -1157,14 +947,14 @@ soup_message_io_run_until_finish (SoupMessage *msg,
GCancellable *cancellable,
GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
gboolean success;
g_object_ref (msg);
if (io) {
- if (io->read_state < SOUP_MESSAGE_IO_STATE_BODY_DONE)
- io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
+ if (io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY_DONE)
+ io->base.read_state = SOUP_MESSAGE_IO_STATE_FINISHING;
}
success = io_run_until (msg, blocking,
@@ -1180,17 +970,17 @@ static void
client_stream_eof (SoupClientInputStream *stream, gpointer user_data)
{
SoupMessage *msg = user_data;
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
- if (io && io->read_state == SOUP_MESSAGE_IO_STATE_BODY)
- io->read_state = SOUP_MESSAGE_IO_STATE_BODY_DONE;
+ if (io && io->base.read_state == SOUP_MESSAGE_IO_STATE_BODY)
+ io->base.read_state = SOUP_MESSAGE_IO_STATE_BODY_DONE;
}
GInputStream *
soup_message_io_get_response_istream (SoupMessage *msg,
GError **error)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
GInputStream *client_stream;
if (SOUP_STATUS_IS_TRANSPORT_ERROR (msg->status_code)) {
@@ -1199,7 +989,7 @@ soup_message_io_get_response_istream (SoupMessage *msg,
return NULL;
}
- client_stream = soup_client_input_stream_new (io->body_istream, msg);
+ client_stream = soup_client_input_stream_new (io->base.body_istream, msg);
g_signal_connect (client_stream, "eof",
G_CALLBACK (client_stream_eof), msg);
@@ -1208,28 +998,28 @@ soup_message_io_get_response_istream (SoupMessage *msg,
void
soup_message_send_request (SoupMessageQueueItem *item,
- SoupMessageCompletionFn completion_cb,
+ SoupMessageIOCompletionFn completion_cb,
gpointer user_data)
{
- SoupMessageIOData *io;
+ SoupClientMessageIOData *io;
- io = g_slice_new0 (SoupMessageIOData);
- io->completion_cb = completion_cb;
- io->completion_data = user_data;
+ io = g_slice_new0 (SoupClientMessageIOData);
+ io->base.completion_cb = completion_cb;
+ io->base.completion_data = user_data;
io->item = item;
soup_message_queue_item_ref (item);
io->cancellable = io->item->cancellable;
- io->iostream = g_object_ref (soup_socket_get_iostream (soup_connection_get_socket (io->item->conn)));
- io->istream = SOUP_FILTER_INPUT_STREAM (g_io_stream_get_input_stream (io->iostream));
- io->ostream = g_io_stream_get_output_stream (io->iostream);
- io->async_context = g_main_context_ref_thread_default ();
+ io->base.iostream = g_object_ref (soup_socket_get_iostream (soup_connection_get_socket (io->item->conn)));
+ io->base.istream = SOUP_FILTER_INPUT_STREAM (g_io_stream_get_input_stream (io->base.iostream));
+ io->base.ostream = g_io_stream_get_output_stream (io->base.iostream);
+ io->base.async_context = g_main_context_ref_thread_default ();
- io->read_header_buf = g_byte_array_new ();
- io->write_buf = g_string_new (NULL);
+ io->base.read_header_buf = g_byte_array_new ();
+ io->base.write_buf = g_string_new (NULL);
- io->read_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
- io->write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
+ io->base.read_state = SOUP_MESSAGE_IO_STATE_NOT_STARTED;
+ io->base.write_state = SOUP_MESSAGE_IO_STATE_HEADERS;
#ifdef HAVE_SYSPROF
io->begin_time_nsec = SYSPROF_CAPTURE_CURRENT_TIME;
@@ -1238,65 +1028,25 @@ soup_message_send_request (SoupMessageQueueItem *item,
soup_message_set_io_data (io->item->msg, io);
}
-void
+void
soup_message_io_pause (SoupMessage *msg)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
g_return_if_fail (io != NULL);
+ g_return_if_fail (io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY);
- if (io->item)
- g_return_if_fail (io->read_state < SOUP_MESSAGE_IO_STATE_BODY);
-
- if (io->io_source) {
- g_source_destroy (io->io_source);
- g_source_unref (io->io_source);
- io->io_source = NULL;
- }
-
- if (io->unpause_source) {
- g_source_destroy (io->unpause_source);
- g_source_unref (io->unpause_source);
- io->unpause_source = NULL;
- }
-
- io->paused = TRUE;
-}
-
-static gboolean
-io_unpause_internal (gpointer msg)
-{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
-
- g_return_val_if_fail (io != NULL, FALSE);
-
- g_clear_pointer (&io->unpause_source, g_source_unref);
- io->paused = FALSE;
-
- if (io->io_source)
- return FALSE;
-
- soup_message_io_run (msg, FALSE);
- return FALSE;
+ soup_message_io_data_pause (&io->base);
}
void
soup_message_io_unpause (SoupMessage *msg)
{
- SoupMessageIOData *io = soup_message_get_io_data (msg);
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
g_return_if_fail (io != NULL);
-
- if (io->item) {
- g_return_if_fail (io->read_state < SOUP_MESSAGE_IO_STATE_BODY);
- io->paused = FALSE;
- return;
- }
-
- if (!io->unpause_source) {
- io->unpause_source = soup_add_completion_reffed (io->async_context,
- io_unpause_internal, msg, NULL);
- }
+ g_return_if_fail (io->base.read_state < SOUP_MESSAGE_IO_STATE_BODY);
+ io->base.paused = FALSE;
}
/**
@@ -1312,3 +1062,11 @@ soup_message_io_in_progress (SoupMessage *msg)
{
return soup_message_get_io_data (msg) != NULL;
}
+
+gboolean
+soup_message_is_io_paused (SoupMessage *msg)
+{
+ SoupClientMessageIOData *io = soup_message_get_io_data (msg);
+
+ return io && io->base.paused;
+}
diff --git a/libsoup/soup-message-private.h b/libsoup/soup-message-private.h
index 1200adba..0ce07e8f 100644
--- a/libsoup/soup-message-private.h
+++ b/libsoup/soup-message-private.h
@@ -8,13 +8,17 @@
#include "soup-filter-input-stream.h"
#include "soup-message.h"
+#include "soup-message-io-data.h"
#include "auth/soup-auth.h"
#include "content-sniffer/soup-content-processor.h"
#include "content-sniffer/soup-content-sniffer.h"
#include "soup-session.h"
+typedef struct _SoupClientMessageIOData SoupClientMessageIOData;
+void soup_client_message_io_data_free (SoupClientMessageIOData *io);
+
typedef struct {
- gpointer io_data;
+ SoupClientMessageIOData *io_data;
guint msg_flags;
gboolean server_side;
@@ -46,12 +50,6 @@ typedef struct {
void soup_message_cleanup_response (SoupMessage *msg);
-typedef enum {
- SOUP_MESSAGE_IO_COMPLETE,
- SOUP_MESSAGE_IO_INTERRUPTED,
- SOUP_MESSAGE_IO_STOLEN
-} SoupMessageIOCompletion;
-
typedef void (*SoupMessageGetHeadersFn) (SoupMessage *msg,
GString *headers,
SoupEncoding *encoding,
@@ -62,17 +60,9 @@ typedef guint (*SoupMessageParseHeadersFn)(SoupMessage *msg,
SoupEncoding *encoding,
gpointer user_data,
GError **error);
-typedef void (*SoupMessageCompletionFn) (SoupMessage *msg,
- SoupMessageIOCompletion completion,
- gpointer user_data);
-
void soup_message_send_request (SoupMessageQueueItem *item,
- SoupMessageCompletionFn completion_cb,
- gpointer user_data);
-void soup_message_read_request (SoupMessage *msg,
- SoupSocket *sock,
- SoupMessageCompletionFn completion_cb,
+ SoupMessageIOCompletionFn completion_cb,
gpointer user_data);
/* Auth handling */
@@ -84,77 +74,13 @@ void soup_message_set_proxy_auth (SoupMessage *msg,
SoupAuth *soup_message_get_proxy_auth (SoupMessage *msg);
/* I/O */
-typedef enum {
- SOUP_MESSAGE_IO_STATE_NOT_STARTED,
- SOUP_MESSAGE_IO_STATE_ANY = SOUP_MESSAGE_IO_STATE_NOT_STARTED,
- SOUP_MESSAGE_IO_STATE_HEADERS,
- SOUP_MESSAGE_IO_STATE_BLOCKING,
- SOUP_MESSAGE_IO_STATE_BODY_START,
- SOUP_MESSAGE_IO_STATE_BODY,
- SOUP_MESSAGE_IO_STATE_BODY_DATA,
- SOUP_MESSAGE_IO_STATE_BODY_FLUSH,
- SOUP_MESSAGE_IO_STATE_BODY_DONE,
- SOUP_MESSAGE_IO_STATE_FINISHING,
- SOUP_MESSAGE_IO_STATE_DONE
-} SoupMessageIOState;
-
-#define SOUP_MESSAGE_IO_STATE_ACTIVE(state) \
- (state != SOUP_MESSAGE_IO_STATE_NOT_STARTED && \
- state != SOUP_MESSAGE_IO_STATE_BLOCKING && \
- state != SOUP_MESSAGE_IO_STATE_DONE)
-#define SOUP_MESSAGE_IO_STATE_POLLABLE(state) \
- (SOUP_MESSAGE_IO_STATE_ACTIVE (state) && \
- state != SOUP_MESSAGE_IO_STATE_BODY_DONE)
-
-typedef struct {
- /* Client only */
- SoupMessageQueueItem *item;
- GCancellable *cancellable;
-
- /* Server only */
- SoupSocket *sock;
-
- GIOStream *iostream;
- SoupFilterInputStream *istream;
- GInputStream *body_istream;
- GOutputStream *ostream;
- GOutputStream *body_ostream;
- GMainContext *async_context;
-
- SoupMessageIOState read_state;
- SoupEncoding read_encoding;
- GByteArray *read_header_buf;
- goffset read_length;
-
- SoupMessageIOState write_state;
- SoupEncoding write_encoding;
- GString *write_buf;
- GBytes *write_chunk;
- goffset write_body_offset;
- goffset write_length;
- goffset written;
-
- GSource *io_source;
- GSource *unpause_source;
- gboolean paused;
-
- GCancellable *async_wait;
- GError *async_error;
-
- SoupMessageCompletionFn completion_cb;
- gpointer completion_data;
-
-#ifdef HAVE_SYSPROF
- gint64 begin_time_nsec;
-#endif
-} SoupMessageIOData;
-
void soup_message_io_run (SoupMessage *msg,
gboolean blocking);
void soup_message_io_finished (SoupMessage *msg);
void soup_message_io_cleanup (SoupMessage *msg);
void soup_message_io_pause (SoupMessage *msg);
void soup_message_io_unpause (SoupMessage *msg);
+gboolean soup_message_is_io_paused (SoupMessage *msg);
gboolean soup_message_io_in_progress (SoupMessage *msg);
GIOStream *soup_message_io_steal (SoupMessage *msg);
@@ -214,9 +140,9 @@ SoupConnection *soup_message_get_connection (SoupMessage *msg);
void soup_message_set_connection (SoupMessage *msg,
SoupConnection *conn);
-gpointer soup_message_get_io_data (SoupMessage *msg);
-void soup_message_set_io_data (SoupMessage *msg,
- gpointer io);
+SoupClientMessageIOData *soup_message_get_io_data (SoupMessage *msg);
+void soup_message_set_io_data (SoupMessage *msg,
+ SoupClientMessageIOData *io);
SoupContentSniffer *soup_message_get_content_sniffer (SoupMessage *msg);
void soup_message_set_content_sniffer (SoupMessage *msg,
@@ -224,7 +150,4 @@ void soup_message_set_content_sniffer (SoupMessage *msg
void soup_message_set_bytes_for_sniffing (SoupMessage *msg,
gsize bytes);
-const char *soup_http_version_to_string (SoupHTTPVersion version);
-
-
#endif /* __SOUP_MESSAGE_PRIVATE_H__ */
diff --git a/libsoup/soup-message.c b/libsoup/soup-message.c
index 5ead16d9..0a265dea 100644
--- a/libsoup/soup-message.c
+++ b/libsoup/soup-message.c
@@ -19,13 +19,13 @@
/**
* SECTION:soup-message
* @short_description: An HTTP request and response.
- * @see_also: #SoupMessageHeaders, #SoupMessageBody
+ * @see_also: #SoupMessageHeaders
*
* A #SoupMessage represents an HTTP message that is being sent or
* received.
*
- * For client-side usage, you would create a #SoupMessage with
- * soup_message_new() or soup_message_new_from_uri(), set up its
+ * You would create a #SoupMessage with soup_message_new() or
+ * soup_message_new_from_uri(), set up its
* fields appropriately, and send it. If you are using the newer
* #SoupRequest API, you would create a request with
* soup_session_request_http() or soup_session_request_http_uri(), and
@@ -33,10 +33,6 @@
* #SoupMessage that you can retrieve via
* soup_request_http_get_message().
*
- * For server-side usage, #SoupServer will create #SoupMessage<!--
- * -->s automatically for incoming requests, which your application
- * will receive via handlers.
- *
* Note that libsoup's terminology here does not quite match the HTTP
* specification: in RFC 2616, an "HTTP-message" is
* <emphasis>either</emphasis> a Request, <emphasis>or</emphasis> a
@@ -49,9 +45,7 @@
* @method: the HTTP method
* @status_code: the HTTP status code
* @reason_phrase: the status phrase associated with @status_code
- * @request_body: the request body
* @request_headers: the request headers
- * @response_body: the response body
* @response_headers: the response headers
*
* Represents an HTTP message being sent or received.
@@ -66,48 +60,17 @@
* messages. Rather, you should look at @status_code, and determine an
* end-user-appropriate message based on that and on what you were
* trying to do.
- *
- * As described in the #SoupMessageBody documentation, the
- * @request_body and @response_body <literal>data</literal> fields
- * will not necessarily be filled in at all times. When the body
- * fields are filled in, they will be terminated with a '\0' byte
- * (which is not included in the <literal>length</literal>), so you
- * can use them as ordinary C strings (assuming that you know that the
- * body doesn't have any other '\0' bytes).
- *
- * For a client-side #SoupMessage, @request_body's
- * <literal>data</literal> is usually filled in right before libsoup
- * writes the request to the network, but you should not count on
- * this; use soup_message_body_flatten() if you want to ensure that
- * <literal>data</literal> is filled in. If you are not using
- * #SoupRequest to read the response, then @response_body's
- * <literal>data</literal> will be filled in before
- * #SoupMessage::finished is emitted. (If you are using #SoupRequest,
- * then the message body is not accumulated by default, so
- * @response_body's <literal>data</literal> will always be %NULL.)
- *
- * For a server-side #SoupMessage, @request_body's %data will be
- * filled in before #SoupMessage::got_body is emitted.
- *
- * To prevent the %data field from being filled in at all (eg, if you
- * are handling the data from a #SoupMessage::got_chunk, and so don't
- * need to see it all at the end), call
- * soup_message_body_set_accumulate() on @response_body or
- * @request_body as appropriate, passing %FALSE.
- **/
+ */
G_DEFINE_TYPE_WITH_PRIVATE (SoupMessage, soup_message, G_TYPE_OBJECT)
enum {
- WROTE_INFORMATIONAL,
WROTE_HEADERS,
- WROTE_CHUNK,
WROTE_BODY_DATA,
WROTE_BODY,
GOT_INFORMATIONAL,
GOT_HEADERS,
- GOT_CHUNK,
GOT_BODY,
CONTENT_SNIFFED,
@@ -129,15 +92,10 @@ enum {
PROP_URI,
PROP_HTTP_VERSION,
PROP_FLAGS,
- PROP_SERVER_SIDE,
PROP_STATUS_CODE,
PROP_REASON_PHRASE,
PROP_FIRST_PARTY,
- PROP_REQUEST_BODY,
- PROP_REQUEST_BODY_DATA,
PROP_REQUEST_HEADERS,
- PROP_RESPONSE_BODY,
- PROP_RESPONSE_BODY_DATA,
PROP_RESPONSE_HEADERS,
PROP_TLS_CERTIFICATE,
PROP_TLS_ERRORS,
@@ -156,9 +114,7 @@ soup_message_init (SoupMessage *msg)
priv->http_version = priv->orig_http_version = SOUP_HTTP_1_1;
priv->priority = SOUP_MESSAGE_PRIORITY_NORMAL;
- msg->request_body = soup_message_body_new ();
msg->request_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_REQUEST);
- msg->response_body = soup_message_body_new ();
msg->response_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_RESPONSE);
}
@@ -168,7 +124,7 @@ soup_message_finalize (GObject *object)
SoupMessage *msg = SOUP_MESSAGE (object);
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
- soup_message_io_cleanup (msg);
+ soup_client_message_io_data_free (priv->io_data);
g_clear_pointer (&priv->uri, soup_uri_free);
g_clear_pointer (&priv->first_party, soup_uri_free);
@@ -181,11 +137,9 @@ soup_message_finalize (GObject *object)
g_clear_object (&priv->tls_certificate);
- soup_message_body_free (msg->request_body);
soup_message_headers_free (msg->request_headers);
- g_clear_object (&msg->request_body_stream);
- soup_message_body_free (msg->response_body);
soup_message_headers_free (msg->response_headers);
+ g_clear_object (&msg->request_body_stream);
g_free (msg->reason_phrase);
@@ -218,13 +172,6 @@ soup_message_set_property (GObject *object, guint prop_id,
case PROP_FLAGS:
soup_message_set_flags (msg, g_value_get_flags (value));
break;
- case PROP_SERVER_SIDE:
- priv->server_side = g_value_get_boolean (value);
- if (priv->server_side) {
- soup_message_headers_set_encoding (msg->response_headers,
- SOUP_ENCODING_CONTENT_LENGTH);
- }
- break;
case PROP_STATUS_CODE:
soup_message_set_status (msg, g_value_get_uint (value));
break;
@@ -266,7 +213,6 @@ soup_message_get_property (GObject *object, guint prop_id,
{
SoupMessage *msg = SOUP_MESSAGE (object);
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
- GBytes *buf;
switch (prop_id) {
case PROP_METHOD:
@@ -287,9 +233,6 @@ soup_message_get_property (GObject *object, guint prop_id,
case PROP_FLAGS:
g_value_set_flags (value, priv->msg_flags);
break;
- case PROP_SERVER_SIDE:
- g_value_set_boolean (value, priv->server_side);
- break;
case PROP_STATUS_CODE:
g_value_set_uint (value, msg->status_code);
break;
@@ -299,23 +242,9 @@ soup_message_get_property (GObject *object, guint prop_id,
case PROP_FIRST_PARTY:
g_value_set_boxed (value, priv->first_party);
break;
- case PROP_REQUEST_BODY:
- g_value_set_boxed (value, msg->request_body);
- break;
- case PROP_REQUEST_BODY_DATA:
- buf = soup_message_body_flatten (msg->request_body);
- g_value_take_boxed (value, buf);
- break;
case PROP_REQUEST_HEADERS:
g_value_set_boxed (value, msg->request_headers);
break;
- case PROP_RESPONSE_BODY:
- g_value_set_boxed (value, msg->response_body);
- break;
- case PROP_RESPONSE_BODY_DATA:
- buf = soup_message_body_flatten (msg->response_body);
- g_value_take_boxed (value, buf);
- break;
case PROP_RESPONSE_HEADERS:
g_value_set_boxed (value, msg->response_headers);
break;
@@ -335,26 +264,10 @@ soup_message_get_property (GObject *object, guint prop_id,
}
static void
-soup_message_real_got_body (SoupMessage *msg)
-{
- SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
- SoupMessageBody *body;
-
- body = priv->server_side ? msg->request_body : msg->response_body;
- if (soup_message_body_get_accumulate (body)) {
- GBytes *buffer = soup_message_body_flatten (body);
- g_bytes_unref (buffer);
- }
-}
-
-static void
soup_message_class_init (SoupMessageClass *message_class)
{
GObjectClass *object_class = G_OBJECT_CLASS (message_class);
- /* virtual method definition */
- message_class->got_body = soup_message_real_got_body;
-
/* virtual method override */
object_class->finalize = soup_message_finalize;
object_class->set_property = soup_message_set_property;
@@ -363,29 +276,11 @@ soup_message_class_init (SoupMessageClass *message_class)
/* signals */
/**
- * SoupMessage::wrote-informational:
- * @msg: the message
- *
- * Emitted immediately after writing a 1xx (Informational)
- * response for a (server-side) message.
- **/
- signals[WROTE_INFORMATIONAL] =
- g_signal_new ("wrote_informational",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SoupMessageClass, wrote_informational),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
-
- /**
* SoupMessage::wrote-headers:
* @msg: the message
*
- * Emitted immediately after writing the headers for a
- * message. (For a client-side message, this is after writing
- * the request headers; for a server-side message, it is after
- * writing the response headers.)
+ * Emitted immediately after writing the request headers for a
+ * message.
**/
signals[WROTE_HEADERS] =
g_signal_new ("wrote_headers",
@@ -397,28 +292,6 @@ soup_message_class_init (SoupMessageClass *message_class)
G_TYPE_NONE, 0);
/**
- * SoupMessage::wrote-chunk:
- * @msg: the message
- *
- * Emitted immediately after writing a body chunk for a message.
- *
- * Note that this signal is not parallel to
- * #SoupMessage::got_chunk; it is emitted only when a complete
- * chunk (added with soup_message_body_append() or
- * soup_message_body_append_bytes()) has been written. To get
- * more useful continuous progress information, use
- * #SoupMessage::wrote_body_data.
- **/
- signals[WROTE_CHUNK] =
- g_signal_new ("wrote_chunk",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SoupMessageClass, wrote_chunk),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 0);
-
- /**
* SoupMessage::wrote-body-data:
* @msg: the message
* @chunk: the data written
@@ -426,10 +299,6 @@ soup_message_class_init (SoupMessageClass *message_class)
* Emitted immediately after writing a portion of the message
* body to the network.
*
- * Unlike #SoupMessage::wrote_chunk, this is emitted after
- * every successful write() call, not only after finishing a
- * complete "chunk".
- *
* Since: 2.24
**/
signals[WROTE_BODY_DATA] =
@@ -447,11 +316,7 @@ soup_message_class_init (SoupMessageClass *message_class)
* @msg: the message
*
* Emitted immediately after writing the complete body for a
- * message. (For a client-side message, this means that
- * libsoup is done writing and is now waiting for the response
- * from the server. For a server-side message, this means that
- * libsoup has finished writing the response and is nearly
- * done with the message.)
+ * message.
**/
signals[WROTE_BODY] =
g_signal_new ("wrote_body",
@@ -489,11 +354,7 @@ soup_message_class_init (SoupMessageClass *message_class)
* SoupMessage::got-headers:
* @msg: the message
*
- * Emitted after receiving all message headers for a message.
- * (For a client-side message, this is after receiving the
- * Status-Line and response headers; for a server-side
- * message, it is after receiving the Request-Line and request
- * headers.)
+ * Emitted after receiving the Status-Line and response headers.
*
* See also soup_message_add_header_handler() and
* soup_message_add_status_code_handler(), which can be used
@@ -518,37 +379,10 @@ soup_message_class_init (SoupMessageClass *message_class)
G_TYPE_NONE, 0);
/**
- * SoupMessage::got-chunk:
- * @msg: the message
- * @chunk: the just-read chunk
- *
- * Emitted after receiving a chunk of a message body. Note
- * that "chunk" in this context means any subpiece of the
- * body, not necessarily the specific HTTP 1.1 chunks sent by
- * the other side.
- *
- * If you cancel or requeue @msg while processing this signal,
- * then the current HTTP I/O will be stopped after this signal
- * emission finished, and @msg's connection will be closed.
- **/
- signals[GOT_CHUNK] =
- g_signal_new ("got_chunk",
- G_OBJECT_CLASS_TYPE (object_class),
- G_SIGNAL_RUN_FIRST,
- G_STRUCT_OFFSET (SoupMessageClass, got_chunk),
- NULL, NULL,
- NULL,
- G_TYPE_NONE, 1,
- G_TYPE_BYTES);
-
- /**
* SoupMessage::got-body:
* @msg: the message
*
- * Emitted after receiving the complete message body. (For a
- * server-side message, this means it has received the request
- * body. For a client-side message, this means it has received
- * the response body and is nearly done with the message.)
+ * Emitted after receiving the complete message request body.
*
* See also soup_message_add_header_handler() and
* soup_message_add_status_code_handler(), which can be used
@@ -642,8 +476,7 @@ soup_message_class_init (SoupMessageClass *message_class)
* @msg: the message
*
* Emitted when all HTTP processing is finished for a message.
- * (After #SoupMessage::got_body for client-side messages, or
- * after #SoupMessage::wrote_body for server-side messages.)
+ * (After #SoupMessage::got_body).
**/
signals[FINISHED] =
g_signal_new ("finished",
@@ -746,20 +579,6 @@ soup_message_class_init (SoupMessageClass *message_class)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/**
- * SOUP_MESSAGE_SERVER_SIDE:
- *
- * Alias for the #SoupMessage:server-side property. (%TRUE if
- * the message was created by #SoupServer.)
- **/
- g_object_class_install_property (
- object_class, PROP_SERVER_SIDE,
- g_param_spec_boolean (SOUP_MESSAGE_SERVER_SIDE,
- "Server-side",
- "Whether or not the message is server-side rather than client-side",
- FALSE,
- G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY |
- G_PARAM_STATIC_STRINGS));
- /**
* SOUP_MESSAGE_STATUS_CODE:
*
* Alias for the #SoupMessage:status-code property. (The
@@ -841,43 +660,6 @@ soup_message_class_init (SoupMessageClass *message_class)
FALSE,
G_PARAM_READWRITE));
/**
- * SOUP_MESSAGE_REQUEST_BODY:
- *
- * Alias for the #SoupMessage:request-body property. (The
- * message's HTTP request body.)
- **/
- g_object_class_install_property (
- object_class, PROP_REQUEST_BODY,
- g_param_spec_boxed (SOUP_MESSAGE_REQUEST_BODY,
- "Request Body",
- "The HTTP request content",
- SOUP_TYPE_MESSAGE_BODY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- /**
- * SOUP_MESSAGE_REQUEST_BODY_DATA:
- *
- * Alias for the #SoupMessage:request-body-data property. (The
- * message's HTTP request body, as a #GBytes.)
- *
- * Since: 2.46
- **/
- /**
- * SoupMessage:request-body-data:
- *
- * The message's HTTP request body, as a #GBytes.
- *
- * Since: 2.46
- **/
- g_object_class_install_property (
- object_class, PROP_REQUEST_BODY_DATA,
- g_param_spec_boxed (SOUP_MESSAGE_REQUEST_BODY_DATA,
- "Request Body Data",
- "The HTTP request body",
- G_TYPE_BYTES,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- /**
* SOUP_MESSAGE_REQUEST_HEADERS:
*
* Alias for the #SoupMessage:request-headers property. (The
@@ -892,43 +674,6 @@ soup_message_class_init (SoupMessageClass *message_class)
G_PARAM_READABLE |
G_PARAM_STATIC_STRINGS));
/**
- * SOUP_MESSAGE_RESPONSE_BODY:
- *
- * Alias for the #SoupMessage:response-body property. (The
- * message's HTTP response body.)
- **/
- g_object_class_install_property (
- object_class, PROP_RESPONSE_BODY,
- g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_BODY,
- "Response Body",
- "The HTTP response content",
- SOUP_TYPE_MESSAGE_BODY,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- /**
- * SOUP_MESSAGE_RESPONSE_BODY_DATA:
- *
- * Alias for the #SoupMessage:response-body-data property. (The
- * message's HTTP response body, as a #GBytes.)
- *
- * Since: 2.46
- **/
- /**
- * SoupMessage:response-body-data:
- *
- * The message's HTTP response body, as a #GBytes.
- *
- * Since: 2.46
- **/
- g_object_class_install_property (
- object_class, PROP_RESPONSE_BODY_DATA,
- g_param_spec_boxed (SOUP_MESSAGE_RESPONSE_BODY_DATA,
- "Response Body Data",
- "The HTTP response body",
- G_TYPE_BYTES,
- G_PARAM_READABLE |
- G_PARAM_STATIC_STRINGS));
- /**
* SOUP_MESSAGE_RESPONSE_HEADERS:
*
* Alias for the #SoupMessage:response-headers property. (The
@@ -1059,42 +804,6 @@ soup_message_new_from_uri (const char *method, SoupURI *uri)
}
/**
- * soup_message_set_response:
- * @msg: the message
- * @content_type: (allow-none): MIME Content-Type of the body
- * @resp_use: a #SoupMemoryUse describing how to handle @resp_body
- * @resp_body: (allow-none) (array length=resp_length) (element-type guint8):
- * a data buffer containing the body of the message response.
- * @resp_length: the byte length of @resp_body.
- *
- * Convenience function to set the response body of a #SoupMessage. If
- * @content_type is %NULL, the response body must be empty as well.
- */
-void
-soup_message_set_response (SoupMessage *msg,
- const char *content_type,
- SoupMemoryUse resp_use,
- const char *resp_body,
- gsize resp_length)
-{
- g_return_if_fail (SOUP_IS_MESSAGE (msg));
- g_return_if_fail (content_type != NULL || resp_length == 0);
-
- if (content_type) {
- g_warn_if_fail (strchr (content_type, '/') != NULL);
-
- soup_message_headers_replace (msg->response_headers,
- "Content-Type", content_type);
- soup_message_body_append (msg->response_body, resp_use,
- resp_body, resp_length);
- } else {
- soup_message_headers_remove (msg->response_headers,
- "Content-Type");
- soup_message_body_truncate (msg->response_body);
- }
-}
-
-/**
* soup_message_set_request_body:
* @msg: the message
* @content_type: (allow-none): MIME Content-Type of the body
@@ -1165,24 +874,12 @@ soup_message_set_request_body_from_bytes (SoupMessage *msg,
}
void
-soup_message_wrote_informational (SoupMessage *msg)
-{
- g_signal_emit (msg, signals[WROTE_INFORMATIONAL], 0);
-}
-
-void
soup_message_wrote_headers (SoupMessage *msg)
{
g_signal_emit (msg, signals[WROTE_HEADERS], 0);
}
void
-soup_message_wrote_chunk (SoupMessage *msg)
-{
- g_signal_emit (msg, signals[WROTE_CHUNK], 0);
-}
-
-void
soup_message_wrote_body_data (SoupMessage *msg, GBytes *chunk)
{
g_signal_emit (msg, signals[WROTE_BODY_DATA], 0, chunk);
@@ -1207,12 +904,6 @@ soup_message_got_headers (SoupMessage *msg)
}
void
-soup_message_got_chunk (SoupMessage *msg, GBytes *chunk)
-{
- g_signal_emit (msg, signals[GOT_CHUNK], 0, chunk);
-}
-
-void
soup_message_got_body (SoupMessage *msg)
{
g_signal_emit (msg, signals[GOT_BODY], 0);
@@ -1233,11 +924,6 @@ soup_message_starting (SoupMessage *msg)
void
soup_message_restarted (SoupMessage *msg)
{
- SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
-
- if (priv->msg_flags & SOUP_MESSAGE_CAN_REBUILD)
- soup_message_body_truncate (msg->request_body);
-
g_clear_object (&msg->request_body_stream);
g_signal_emit (msg, signals[RESTARTED], 0);
@@ -1270,12 +956,9 @@ header_handler_metamarshal (GClosure *closure, GValue *return_value,
gpointer invocation_hint, gpointer marshal_data)
{
SoupMessage *msg = g_value_get_object (&param_values[0]);
- SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
const char *header_name = marshal_data;
- SoupMessageHeaders *hdrs;
- hdrs = priv->server_side ? msg->request_headers : msg->response_headers;
- if (soup_message_headers_get_one (hdrs, header_name)) {
+ if (soup_message_headers_get_one (msg->response_headers, header_name)) {
closure->marshal (closure, return_value, n_param_values,
param_values, invocation_hint,
((GCClosure *)closure)->callback);
@@ -1292,9 +975,7 @@ header_handler_metamarshal (GClosure *closure, GValue *return_value,
*
* Adds a signal handler to @msg for @signal, as with
* g_signal_connect(), but the @callback will only be run if @msg's
- * incoming messages headers (that is, the
- * <literal>request_headers</literal> for a client #SoupMessage, or
- * the <literal>response_headers</literal> for a server #SoupMessage)
+ * incoming messages headers (that is, the <literal>request_headers</literal>)
* contain a header named @header.
*
* Return value: the handler ID from g_signal_connect()
@@ -1353,9 +1034,7 @@ status_handler_metamarshal (GClosure *closure, GValue *return_value,
* the status @status_code.
*
* @signal must be a signal that will be emitted after @msg's status
- * is set. For a client #SoupMessage, this means it can't be a "wrote"
- * signal. For a server #SoupMessage, this means it can't be a "got"
- * signal.
+ * is set (this means it can't be a "wrote" signal).
*
* Return value: the handler ID from g_signal_connect()
**/
@@ -1379,7 +1058,6 @@ soup_message_add_status_code_handler (SoupMessage *msg,
return g_signal_connect_closure (msg, signal, closure, FALSE);
}
-
void
soup_message_set_auth (SoupMessage *msg, SoupAuth *auth)
{
@@ -1470,12 +1148,7 @@ soup_message_cleanup_response (SoupMessage *msg)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
- soup_message_body_truncate (msg->response_body);
soup_message_headers_clear (msg->response_headers);
- if (priv->server_side) {
- soup_message_headers_set_encoding (msg->response_headers,
- SOUP_ENCODING_CONTENT_LENGTH);
- }
priv->msg_flags &= ~SOUP_MESSAGE_CONTENT_DECODED;
@@ -1498,9 +1171,6 @@ soup_message_cleanup_response (SoupMessage *msg)
* SoupMessageFlags:
* @SOUP_MESSAGE_NO_REDIRECT: The session should not follow redirect
* (3xx) responses received by this message.
- * @SOUP_MESSAGE_CAN_REBUILD: The caller will rebuild the request
- * body if the message is restarted; see
- * soup_message_body_set_accumulate() for more details.
* @SOUP_MESSAGE_CONTENT_DECODED: Set by #SoupContentDecoder to
* indicate that it has removed the Content-Encoding on a message (and
* so headers such as Content-Length may no longer accurately describe
@@ -1575,14 +1245,6 @@ soup_message_get_flags (SoupMessage *msg)
}
/**
- * 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.
- **/
-
-/**
* soup_message_set_http_version:
* @msg: a #SoupMessage
* @version: the HTTP version
@@ -2061,9 +1723,6 @@ soup_message_set_https_status (SoupMessage *msg, SoupConnection *conn)
* showing what problems, if any, have been found with that
* certificate.
*
- * <note><para>This is only meaningful with messages processed by a #SoupSession and is
- * not useful for messages received by a #SoupServer</para></note>
- *
* Return value: %TRUE if @msg used/attempted https, %FALSE if not
*
* Since: 2.34
@@ -2086,41 +1745,6 @@ soup_message_get_https_status (SoupMessage *msg,
return priv->tls_certificate != NULL;
}
-/**
- * soup_message_set_redirect:
- * @msg: a #SoupMessage
- * @status_code: a 3xx status code
- * @redirect_uri: the URI to redirect @msg to
- *
- * Sets @msg's status_code to @status_code and adds a Location header
- * pointing to @redirect_uri. Use this from a #SoupServer when you
- * want to redirect the client to another URI.
- *
- * @redirect_uri can be a relative URI, in which case it is
- * interpreted relative to @msg's current URI. In particular, if
- * @redirect_uri is just a path, it will replace the path
- * <emphasis>and query</emphasis> of @msg's URI.
- *
- * Since: 2.38
- */
-void
-soup_message_set_redirect (SoupMessage *msg, guint status_code,
- const char *redirect_uri)
-{
- SoupURI *location;
- char *location_str;
-
- location = soup_uri_new_with_base (soup_message_get_uri (msg), redirect_uri);
- g_return_if_fail (location != NULL);
-
- soup_message_set_status (msg, status_code);
- location_str = soup_uri_to_string (location, FALSE);
- soup_message_headers_replace (msg->response_headers, "Location",
- location_str);
- g_free (location_str);
- soup_uri_free (location);
-}
-
void
soup_message_set_soup_request (SoupMessage *msg,
SoupRequest *req)
@@ -2223,7 +1847,7 @@ soup_message_get_priority (SoupMessage *msg)
return priv->priority;
}
-gpointer
+SoupClientMessageIOData *
soup_message_get_io_data (SoupMessage *msg)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
@@ -2232,11 +1856,12 @@ soup_message_get_io_data (SoupMessage *msg)
}
void
-soup_message_set_io_data (SoupMessage *msg, gpointer io)
+soup_message_set_io_data (SoupMessage *msg,
+ SoupClientMessageIOData *io)
{
SoupMessagePrivate *priv = soup_message_get_instance_private (msg);
- soup_message_io_cleanup (msg);
+ soup_client_message_io_data_free (priv->io_data);
priv->io_data = io;
}
@@ -2266,17 +1891,3 @@ soup_message_set_bytes_for_sniffing (SoupMessage *msg, gsize bytes)
priv->bytes_for_sniffing = bytes;
}
-
-const char *
-soup_http_version_to_string (SoupHTTPVersion version)
-{
- switch (version) {
- case SOUP_HTTP_1_0:
- return "HTTP/1.0";
- case SOUP_HTTP_1_1:
- return "HTTP/1.1";
- }
-
- g_assert_not_reached ();
- return "";
-}
diff --git a/libsoup/soup-message.h b/libsoup/soup-message.h
index 35560bf9..01664ab6 100644
--- a/libsoup/soup-message.h
+++ b/libsoup/soup-message.h
@@ -29,11 +29,8 @@ struct _SoupMessage {
guint status_code;
char *reason_phrase;
- SoupMessageBody *request_body;
GInputStream *request_body_stream;
SoupMessageHeaders *request_headers;
-
- SoupMessageBody *response_body;
SoupMessageHeaders *response_headers;
};
@@ -41,13 +38,10 @@ 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, GBytes *chunk);
void (*got_body) (SoupMessage *msg);
void (*restarted) (SoupMessage *msg);
void (*finished) (SoupMessage *msg);
@@ -89,12 +83,6 @@ SOUP_AVAILABLE_IN_2_4
SoupMessage *soup_message_new_from_uri (const char *method,
SoupURI *uri);
-SOUP_AVAILABLE_IN_2_4
-void soup_message_set_response (SoupMessage *msg,
- const char *content_type,
- SoupMemoryUse resp_use,
- const char *resp_body,
- gsize resp_length);
SOUP_AVAILABLE_IN_ALL
void soup_message_set_request_body (SoupMessage *msg,
const char *content_type,
@@ -105,11 +93,6 @@ void soup_message_set_request_body_from_bytes (SoupMessage *msg,
const char *content_type,
GBytes *bytes);
-typedef enum {
- SOUP_HTTP_1_0 = 0, /*< nick=http-1-0 >*/
- SOUP_HTTP_1_1 = 1 /*< nick=http-1-1 >*/
-} SoupHTTPVersion;
-
SOUP_AVAILABLE_IN_2_4
void soup_message_set_http_version (SoupMessage *msg,
SoupHTTPVersion version);
@@ -142,13 +125,12 @@ gboolean soup_message_get_is_top_level_navigation (SoupMessage *msg
typedef enum {
SOUP_MESSAGE_NO_REDIRECT = (1 << 1),
- SOUP_MESSAGE_CAN_REBUILD = (1 << 2),
- SOUP_MESSAGE_CONTENT_DECODED = (1 << 3),
- SOUP_MESSAGE_CERTIFICATE_TRUSTED = (1 << 4),
- SOUP_MESSAGE_NEW_CONNECTION = (1 << 5),
- SOUP_MESSAGE_IDEMPOTENT = (1 << 6),
- SOUP_MESSAGE_IGNORE_CONNECTION_LIMITS = (1 << 7),
- SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE = (1 << 8)
+ SOUP_MESSAGE_CONTENT_DECODED = (1 << 2),
+ SOUP_MESSAGE_CERTIFICATE_TRUSTED = (1 << 3),
+ SOUP_MESSAGE_NEW_CONNECTION = (1 << 4),
+ SOUP_MESSAGE_IDEMPOTENT = (1 << 5),
+ SOUP_MESSAGE_IGNORE_CONNECTION_LIMITS = (1 << 6),
+ SOUP_MESSAGE_DO_NOT_USE_AUTH_CACHE = (1 << 7)
} SoupMessageFlags;
SOUP_AVAILABLE_IN_2_4
@@ -192,11 +174,6 @@ void soup_message_set_status_full (SoupMessage *msg,
guint status_code,
const char *reason_phrase);
-SOUP_AVAILABLE_IN_2_38
-void soup_message_set_redirect (SoupMessage *msg,
- guint status_code,
- const char *redirect_uri);
-
SOUP_AVAILABLE_IN_2_28
void soup_message_disable_feature (SoupMessage *msg,
GType feature_type);
@@ -226,12 +203,8 @@ SOUP_AVAILABLE_IN_2_44
SoupMessagePriority soup_message_get_priority (SoupMessage *msg);
SOUP_AVAILABLE_IN_2_4
-void soup_message_wrote_informational (SoupMessage *msg);
-SOUP_AVAILABLE_IN_2_4
void soup_message_wrote_headers (SoupMessage *msg);
SOUP_AVAILABLE_IN_2_4
-void soup_message_wrote_chunk (SoupMessage *msg);
-SOUP_AVAILABLE_IN_2_4
void soup_message_wrote_body_data (SoupMessage *msg, GBytes *chunk);
SOUP_AVAILABLE_IN_2_4
void soup_message_wrote_body (SoupMessage *msg);
@@ -240,8 +213,6 @@ void soup_message_got_informational (SoupMessage *msg);
SOUP_AVAILABLE_IN_2_4
void soup_message_got_headers (SoupMessage *msg);
SOUP_AVAILABLE_IN_2_4
-void soup_message_got_chunk (SoupMessage *msg, GBytes *chunk);
-SOUP_AVAILABLE_IN_2_4
void soup_message_got_body (SoupMessage *msg);
SOUP_AVAILABLE_IN_2_4
void soup_message_content_sniffed (SoupMessage *msg, const char *content_type, GHashTable *params);
diff --git a/libsoup/soup-session.c b/libsoup/soup-session.c
index ce7dc713..d336a62d 100644
--- a/libsoup/soup-session.c
+++ b/libsoup/soup-session.c
@@ -1013,7 +1013,7 @@ soup_session_append_queue_item (SoupSession *session,
static void
soup_session_send_queue_item (SoupSession *session,
SoupMessageQueueItem *item,
- SoupMessageCompletionFn completion_cb)
+ SoupMessageIOCompletionFn completion_cb)
{
SoupSessionPrivate *priv = soup_session_get_instance_private (session);
@@ -1389,7 +1389,7 @@ tunnel_message_completed (SoupMessage *msg, SoupMessageIOCompletion completion,
if (tunnel_item->conn) {
tunnel_item->state = SOUP_MESSAGE_RUNNING;
soup_session_send_queue_item (session, tunnel_item,
- tunnel_message_completed);
+ (SoupMessageIOCompletionFn)tunnel_message_completed);
soup_message_io_run (msg, !tunnel_item->async);
return;
}
@@ -1443,7 +1443,7 @@ tunnel_connect (SoupMessageQueueItem *item)
g_signal_emit (session, signals[TUNNELING], 0, tunnel_item->conn);
soup_session_send_queue_item (session, tunnel_item,
- tunnel_message_completed);
+ (SoupMessageIOCompletionFn)tunnel_message_completed);
soup_message_io_run (msg, !item->async);
g_object_unref (msg);
}
@@ -1709,7 +1709,8 @@ soup_session_process_queue_item (SoupSession *session,
item->state = SOUP_MESSAGE_RUNNING;
- soup_session_send_queue_item (session, item, message_completed);
+ soup_session_send_queue_item (session, item,
+ (SoupMessageIOCompletionFn)message_completed);
if (item->async)
async_send_request_running (session, item);
diff --git a/libsoup/soup-status.c b/libsoup/soup-status.c
index d4ed5c41..5eb1f635 100644
--- a/libsoup/soup-status.c
+++ b/libsoup/soup-status.c
@@ -304,3 +304,11 @@ soup_status_proxify (guint status_code)
}
G_DEFINE_QUARK (soup-http-error-quark, soup_http_error)
+
+/**
+ * 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.
+ */
diff --git a/libsoup/soup-status.h b/libsoup/soup-status.h
index 040a858c..cc7512f9 100644
--- a/libsoup/soup-status.h
+++ b/libsoup/soup-status.h
@@ -93,6 +93,11 @@ typedef enum {
SOUP_STATUS_NOT_EXTENDED = 510 /* RFC 2774 */
} SoupStatus;
+typedef enum {
+ SOUP_HTTP_1_0 = 0, /*< nick=http-1-0 >*/
+ SOUP_HTTP_1_1 = 1 /*< nick=http-1-1 >*/
+} SoupHTTPVersion;
+
SOUP_AVAILABLE_IN_2_4
const char *soup_status_get_phrase (guint status_code);
SOUP_AVAILABLE_IN_2_26
diff --git a/libsoup/soup-types.h b/libsoup/soup-types.h
index abd7ea21..49a6c9c4 100644
--- a/libsoup/soup-types.h
+++ b/libsoup/soup-types.h
@@ -25,6 +25,7 @@ typedef struct _SoupMessage SoupMessage;
typedef struct _SoupRequest SoupRequest;
typedef struct _SoupRequestHTTP SoupRequestHTTP;
typedef struct _SoupServer SoupServer;
+typedef struct _SoupServerMessage SoupServerMessage;
typedef struct _SoupSession SoupSession;
typedef struct _SoupSessionFeature SoupSessionFeature;
typedef struct _SoupSocket SoupSocket;
diff --git a/libsoup/soup.h b/libsoup/soup.h
index 36485dc2..bd95488e 100644
--- a/libsoup/soup.h
+++ b/libsoup/soup.h
@@ -45,6 +45,7 @@ extern "C" {
#include "server/soup-auth-domain-basic.h"
#include "server/soup-auth-domain-digest.h"
#include "server/soup-server.h"
+#include "server/soup-server-message.h"
#include "soup-session.h"
#include "soup-session-feature.h"
#include "soup-socket.h"
diff --git a/libsoup/websocket/soup-websocket.c b/libsoup/websocket/soup-websocket.c
index e7f29f49..48f9a7bd 100644
--- a/libsoup/websocket/soup-websocket.c
+++ b/libsoup/websocket/soup-websocket.c
@@ -27,6 +27,7 @@
#include "soup-websocket.h"
#include "soup-headers.h"
#include "soup-message-private.h"
+#include "soup-server-message.h"
#include "soup-websocket-extension.h"
#define FIXED_DIGEST_LEN 20
@@ -205,9 +206,9 @@ compute_accept_key (const char *key)
}
static gboolean
-choose_subprotocol (SoupMessage *msg,
- const char **server_protocols,
- const char **chosen_protocol)
+choose_subprotocol (SoupServerMessage *msg,
+ const char **server_protocols,
+ const char **chosen_protocol)
{
const char *client_protocols_str;
char **client_protocols;
@@ -219,8 +220,9 @@ choose_subprotocol (SoupMessage *msg,
if (!server_protocols)
return TRUE;
- client_protocols_str = soup_message_headers_get_one (msg->request_headers,
- "Sec-Websocket-Protocol");
+ client_protocols_str =
+ soup_message_headers_get_one (soup_server_message_get_request_headers (msg),
+ "Sec-Websocket-Protocol");
if (!client_protocols_str)
return TRUE;
@@ -406,10 +408,10 @@ soup_websocket_client_prepare_handshake_with_extensions (SoupMessage *msg,
* Since: 2.50
*/
gboolean
-soup_websocket_server_check_handshake (SoupMessage *msg,
- const char *expected_origin,
- char **protocols,
- GError **error)
+soup_websocket_server_check_handshake (SoupServerMessage *msg,
+ const char *expected_origin,
+ char **protocols,
+ GError **error)
{
return soup_websocket_server_check_handshake_with_extensions (msg, expected_origin, protocols, NULL, error);
}
@@ -460,15 +462,15 @@ extract_extension_names_from_request (SoupMessage *msg)
}
static gboolean
-process_extensions (SoupMessage *msg,
- const char *extensions,
- gboolean is_server,
+process_extensions (const char *extensions,
+ SoupMessage *msg,
GPtrArray *supported_extensions,
GList **accepted_extensions,
GError **error)
{
GSList *extension_list, *l;
GHashTable *requested_extensions = NULL;
+ gboolean is_server = msg == NULL;
if (!supported_extensions || supported_extensions->len == 0) {
if (is_server)
@@ -608,7 +610,7 @@ process_extensions (SoupMessage *msg,
/**
* soup_websocket_server_check_handshake_with_extensions:
- * @msg: #SoupMessage containing the client side of a WebSocket handshake
+ * @msg: #SoupServerMessage containing the client side of a WebSocket handshake
* @origin: (nullable): expected Origin header
* @protocols: (nullable) (array zero-terminated=1): allowed WebSocket
* protocols.
@@ -640,19 +642,20 @@ process_extensions (SoupMessage *msg,
* Since: 2.68
*/
gboolean
-soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
- const char *expected_origin,
- char **protocols,
- GPtrArray *supported_extensions,
- GError **error)
+soup_websocket_server_check_handshake_with_extensions (SoupServerMessage *msg,
+ const char *expected_origin,
+ char **protocols,
+ GPtrArray *supported_extensions,
+ GError **error)
{
const char *origin;
const char *key;
const char *extensions;
+ SoupMessageHeaders *request_headers;
- g_return_val_if_fail (SOUP_IS_MESSAGE (msg), FALSE);
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), FALSE);
- if (msg->method != SOUP_METHOD_GET) {
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_GET) {
g_set_error_literal (error,
SOUP_WEBSOCKET_ERROR,
SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET,
@@ -660,8 +663,9 @@ soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
return FALSE;
}
- if (!soup_message_headers_header_equals (msg->request_headers, "Upgrade", "websocket") ||
- !soup_message_headers_header_contains (msg->request_headers, "Connection", "upgrade")) {
+ request_headers = soup_server_message_get_request_headers (msg);
+ if (!soup_message_headers_header_equals (request_headers, "Upgrade", "websocket") ||
+ !soup_message_headers_header_contains (request_headers, "Connection", "upgrade")) {
g_set_error_literal (error,
SOUP_WEBSOCKET_ERROR,
SOUP_WEBSOCKET_ERROR_NOT_WEBSOCKET,
@@ -669,7 +673,7 @@ soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
return FALSE;
}
- if (!soup_message_headers_header_equals (msg->request_headers, "Sec-WebSocket-Version", "13")) {
+ if (!soup_message_headers_header_equals (request_headers, "Sec-WebSocket-Version", "13")) {
g_set_error_literal (error,
SOUP_WEBSOCKET_ERROR,
SOUP_WEBSOCKET_ERROR_BAD_HANDSHAKE,
@@ -677,7 +681,7 @@ soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
return FALSE;
}
- key = soup_message_headers_get_one (msg->request_headers, "Sec-WebSocket-Key");
+ key = soup_message_headers_get_one (request_headers, "Sec-WebSocket-Key");
if (key == NULL || !validate_key (key)) {
g_set_error_literal (error,
SOUP_WEBSOCKET_ERROR,
@@ -687,7 +691,7 @@ soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
}
if (expected_origin) {
- origin = soup_message_headers_get_one (msg->request_headers, "Origin");
+ origin = soup_message_headers_get_one (request_headers, "Origin");
if (!origin || g_ascii_strcasecmp (origin, expected_origin) != 0) {
g_set_error (error,
SOUP_WEBSOCKET_ERROR,
@@ -705,9 +709,9 @@ soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
return FALSE;
}
- extensions = soup_message_headers_get_list (msg->request_headers, "Sec-WebSocket-Extensions");
+ extensions = soup_message_headers_get_list (request_headers, "Sec-WebSocket-Extensions");
if (extensions && *extensions) {
- if (!process_extensions (msg, extensions, TRUE, supported_extensions, NULL, error))
+ if (!process_extensions (extensions, NULL, supported_extensions, NULL, error))
return FALSE;
}
@@ -718,32 +722,35 @@ soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
"<body>Received invalid WebSocket request</body></html>\r\n"
static void
-respond_handshake_forbidden (SoupMessage *msg)
+respond_handshake_forbidden (SoupServerMessage *msg)
{
- soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
- soup_message_headers_append (msg->response_headers, "Connection", "close");
- soup_message_set_response (msg, "text/html", SOUP_MEMORY_COPY,
- RESPONSE_FORBIDDEN, strlen (RESPONSE_FORBIDDEN));
+ soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN, NULL);
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
+ "Connection", "close");
+ soup_server_message_set_response (msg, "text/html", SOUP_MEMORY_COPY,
+ RESPONSE_FORBIDDEN, strlen (RESPONSE_FORBIDDEN));
}
#define RESPONSE_BAD "<html><head><title>400 Bad Request</title></head>\r\n" \
"<body>Received invalid WebSocket request: %s</body></html>\r\n"
static void
-respond_handshake_bad (SoupMessage *msg, const char *why)
+respond_handshake_bad (SoupServerMessage *msg,
+ const char *why)
{
char *text;
text = g_strdup_printf (RESPONSE_BAD, why);
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
- soup_message_headers_append (msg->response_headers, "Connection", "close");
- soup_message_set_response (msg, "text/html", SOUP_MEMORY_TAKE,
- text, strlen (text));
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
+ "Connection", "close");
+ soup_server_message_set_response (msg, "text/html", SOUP_MEMORY_TAKE,
+ text, strlen (text));
}
/**
* soup_websocket_server_process_handshake:
- * @msg: #SoupMessage containing the client side of a WebSocket handshake
+ * @msg: #SoupServerMessage containing the client side of a WebSocket handshake
* @expected_origin: (allow-none): expected Origin header
* @protocols: (allow-none) (array zero-terminated=1): allowed WebSocket
* protocols.
@@ -773,16 +780,16 @@ respond_handshake_bad (SoupMessage *msg, const char *why)
* Since: 2.50
*/
gboolean
-soup_websocket_server_process_handshake (SoupMessage *msg,
- const char *expected_origin,
- char **protocols)
+soup_websocket_server_process_handshake (SoupServerMessage *msg,
+ const char *expected_origin,
+ char **protocols)
{
return soup_websocket_server_process_handshake_with_extensions (msg, expected_origin, protocols, NULL, NULL);
}
/**
* soup_websocket_server_process_handshake_with_extensions:
- * @msg: #SoupMessage containing the client side of a WebSocket handshake
+ * @msg: #SoupServerMessage containing the client side of a WebSocket handshake
* @expected_origin: (nullable): expected Origin header
* @protocols: (nullable) (array zero-terminated=1): allowed WebSocket
* protocols.
@@ -813,18 +820,21 @@ soup_websocket_server_process_handshake (SoupMessage *msg,
* Since: 2.68
*/
gboolean
-soup_websocket_server_process_handshake_with_extensions (SoupMessage *msg,
- const char *expected_origin,
- char **protocols,
- GPtrArray *supported_extensions,
- GList **accepted_extensions)
+soup_websocket_server_process_handshake_with_extensions (SoupServerMessage *msg,
+ const char *expected_origin,
+ char **protocols,
+ GPtrArray *supported_extensions,
+ GList **accepted_extensions)
{
const char *chosen_protocol = NULL;
const char *key;
const char *extensions;
char *accept_key;
GError *error = NULL;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ g_return_val_if_fail (SOUP_IS_SERVER_MESSAGE (msg), FALSE);
g_return_val_if_fail (accepted_extensions == NULL || *accepted_extensions == NULL, FALSE);
if (!soup_websocket_server_check_handshake_with_extensions (msg, expected_origin, protocols, supported_extensions, &error)) {
@@ -838,25 +848,27 @@ soup_websocket_server_process_handshake_with_extensions (SoupMessage *msg,
return FALSE;
}
- soup_message_set_status (msg, SOUP_STATUS_SWITCHING_PROTOCOLS);
- soup_message_headers_replace (msg->response_headers, "Upgrade", "websocket");
- soup_message_headers_append (msg->response_headers, "Connection", "Upgrade");
+ soup_server_message_set_status (msg, SOUP_STATUS_SWITCHING_PROTOCOLS, NULL);
+ response_headers = soup_server_message_get_response_headers (msg);
+ soup_message_headers_replace (response_headers, "Upgrade", "websocket");
+ soup_message_headers_append (response_headers, "Connection", "Upgrade");
- key = soup_message_headers_get_one (msg->request_headers, "Sec-WebSocket-Key");
+ request_headers = soup_server_message_get_request_headers (msg);
+ key = soup_message_headers_get_one (request_headers, "Sec-WebSocket-Key");
accept_key = compute_accept_key (key);
- soup_message_headers_append (msg->response_headers, "Sec-WebSocket-Accept", accept_key);
+ soup_message_headers_append (response_headers, "Sec-WebSocket-Accept", accept_key);
g_free (accept_key);
choose_subprotocol (msg, (const char **) protocols, &chosen_protocol);
if (chosen_protocol)
- soup_message_headers_append (msg->response_headers, "Sec-WebSocket-Protocol", chosen_protocol);
+ soup_message_headers_append (response_headers, "Sec-WebSocket-Protocol", chosen_protocol);
- extensions = soup_message_headers_get_list (msg->request_headers, "Sec-WebSocket-Extensions");
+ extensions = soup_message_headers_get_list (request_headers, "Sec-WebSocket-Extensions");
if (extensions && *extensions) {
GList *websocket_extensions = NULL;
GList *l;
- process_extensions (msg, extensions, TRUE, supported_extensions, &websocket_extensions, NULL);
+ process_extensions (extensions, NULL, supported_extensions, &websocket_extensions, NULL);
if (websocket_extensions) {
GString *response_extensions;
@@ -878,11 +890,11 @@ soup_websocket_server_process_handshake_with_extensions (SoupMessage *msg,
}
if (response_extensions->len > 0) {
- soup_message_headers_replace (msg->response_headers,
+ soup_message_headers_replace (response_headers,
"Sec-WebSocket-Extensions",
response_extensions->str);
} else {
- soup_message_headers_remove (msg->response_headers,
+ soup_message_headers_remove (response_headers,
"Sec-WebSocket-Extensions");
}
g_string_free (response_extensions, TRUE);
@@ -1009,7 +1021,7 @@ soup_websocket_client_verify_handshake_with_extensions (SoupMessage *msg,
extensions = soup_message_headers_get_list (msg->response_headers, "Sec-WebSocket-Extensions");
if (extensions && *extensions) {
- if (!process_extensions (msg, extensions, FALSE, supported_extensions, accepted_extensions, error))
+ if (!process_extensions (extensions, msg, supported_extensions, accepted_extensions, error))
return FALSE;
}
diff --git a/libsoup/websocket/soup-websocket.h b/libsoup/websocket/soup-websocket.h
index 9f265e0a..d347c213 100644
--- a/libsoup/websocket/soup-websocket.h
+++ b/libsoup/websocket/soup-websocket.h
@@ -87,28 +87,28 @@ gboolean soup_websocket_client_verify_handshake_with_extensions (SoupMessage *ms
GError **error);
SOUP_AVAILABLE_IN_2_50
-gboolean soup_websocket_server_check_handshake (SoupMessage *msg,
- const char *origin,
- char **protocols,
- GError **error);
+gboolean soup_websocket_server_check_handshake (SoupServerMessage *msg,
+ const char *origin,
+ char **protocols,
+ GError **error);
SOUP_AVAILABLE_IN_2_68
gboolean
-soup_websocket_server_check_handshake_with_extensions (SoupMessage *msg,
- const char *origin,
- char **protocols,
- GPtrArray *supported_extensions,
- GError **error);
+soup_websocket_server_check_handshake_with_extensions (SoupServerMessage *msg,
+ const char *origin,
+ char **protocols,
+ GPtrArray *supported_extensions,
+ GError **error);
SOUP_AVAILABLE_IN_2_50
-gboolean soup_websocket_server_process_handshake (SoupMessage *msg,
- const char *expected_origin,
- char **protocols);
+gboolean soup_websocket_server_process_handshake (SoupServerMessage *msg,
+ const char *expected_origin,
+ char **protocols);
SOUP_AVAILABLE_IN_2_68
gboolean
-soup_websocket_server_process_handshake_with_extensions (SoupMessage *msg,
- const char *expected_origin,
- char **protocols,
- GPtrArray *supported_extensions,
- GList **accepted_extensions);
+soup_websocket_server_process_handshake_with_extensions (SoupServerMessage *msg,
+ const char *expected_origin,
+ char **protocols,
+ GPtrArray *supported_extensions,
+ GList **accepted_extensions);
G_END_DECLS
diff --git a/tests/auth-test.c b/tests/auth-test.c
index 9f7720ab..1f3ba064 100644
--- a/tests/auth-test.c
+++ b/tests/auth-test.c
@@ -838,19 +838,24 @@ select_auth_test_one (SoupURI *uri,
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "OK\r\n", 4);
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "OK\r\n", 4);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
static gboolean
-server_basic_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
- const char *username, const char *password, gpointer data)
+server_basic_auth_callback (SoupAuthDomain *auth_domain,
+ SoupServerMessage *msg,
+ const char *username,
+ const char *password,
+ gpointer data)
{
if (strcmp (username, "user") != 0)
return FALSE;
@@ -858,8 +863,10 @@ server_basic_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
}
static char *
-server_digest_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
- const char *username, gpointer data)
+server_digest_auth_callback (SoupAuthDomain *auth_domain,
+ SoupServerMessage *msg,
+ const char *username,
+ gpointer data)
{
if (strcmp (username, "user") != 0)
return NULL;
@@ -974,19 +981,21 @@ do_select_auth_test (void)
}
static void
-sneakily_close_connection (SoupMessage *msg, gpointer user_data)
+sneakily_close_connection (SoupServerMessage *msg,
+ gpointer user_data)
{
/* Sneakily close the connection after the response, by
* tricking soup-message-io into thinking that had been
* the plan all along.
*/
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
"Connection", "close");
}
static void
-auth_close_request_started (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client, gpointer user_data)
+auth_close_request_started (SoupServer *server,
+ SoupServerMessage *msg,
+ gpointer user_data)
{
g_signal_connect (msg, "wrote-headers",
G_CALLBACK (sneakily_close_connection), NULL);
@@ -1112,13 +1121,20 @@ do_infinite_auth_test (void)
}
static void
-disappear_request_read (SoupServer *server, SoupMessage *msg,
- SoupClientContext *context, gpointer user_data)
+disappear_request_read (SoupServer *server,
+ SoupServerMessage *msg,
+ gpointer user_data)
{
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+
+ request_headers = soup_server_message_get_request_headers (msg);
+ response_headers = soup_server_message_get_response_headers (msg);
+
/* Remove the WWW-Authenticate header if this was a failed attempt */
- if (soup_message_headers_get_one (msg->request_headers, "Authorization") &&
- msg->status_code == SOUP_STATUS_UNAUTHORIZED)
- soup_message_headers_remove (msg->response_headers, "WWW-Authenticate");
+ if (soup_message_headers_get_one (request_headers, "Authorization") &&
+ soup_server_message_get_status (msg, NULL) == SOUP_STATUS_UNAUTHORIZED)
+ soup_message_headers_remove (response_headers, "WWW-Authenticate");
}
static void
diff --git a/tests/cache-test.c b/tests/cache-test.c
index 34e26be8..a048db57 100644
--- a/tests/cache-test.c
+++ b/tests/cache-test.c
@@ -6,53 +6,62 @@
#include "test-utils.h"
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
const char *last_modified, *etag;
const char *header;
+ const char *method;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
guint status = SOUP_STATUS_OK;
- if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ method = soup_server_message_get_method (msg);
+
+ if (method != SOUP_METHOD_GET && method != SOUP_METHOD_POST) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
- header = soup_message_headers_get_one (msg->request_headers,
+ request_headers = soup_server_message_get_request_headers (msg);
+ response_headers = soup_server_message_get_response_headers (msg);
+ header = soup_message_headers_get_one (request_headers,
"Test-Set-Expires");
if (header) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Expires",
header);
}
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (request_headers,
"Test-Set-Cache-Control");
if (header) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Cache-Control",
header);
}
- last_modified = soup_message_headers_get_one (msg->request_headers,
+ last_modified = soup_message_headers_get_one (request_headers,
"Test-Set-Last-Modified");
if (last_modified) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Last-Modified",
last_modified);
}
- etag = soup_message_headers_get_one (msg->request_headers,
+ etag = soup_message_headers_get_one (request_headers,
"Test-Set-ETag");
if (etag) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"ETag",
etag);
}
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (request_headers,
"If-Modified-Since");
if (header && last_modified) {
GDateTime *modified_date, *header_date;
@@ -67,17 +76,17 @@ server_callback (SoupServer *server, SoupMessage *msg,
g_date_time_unref (header_date);
}
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (request_headers,
"If-None-Match");
if (header && etag) {
if (!strcmp (header, etag))
status = SOUP_STATUS_NOT_MODIFIED;
}
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (request_headers,
"Test-Set-My-Header");
if (header) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"My-Header",
header);
}
@@ -93,12 +102,12 @@ server_callback (SoupServer *server, SoupMessage *msg,
if (etag)
g_checksum_update (sum, (guchar *)etag, strlen (etag));
body = g_checksum_get_string (sum);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_COPY,
- body, strlen (body) + 1);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_COPY,
+ body, strlen (body) + 1);
g_checksum_free (sum);
}
- soup_message_set_status (msg, status);
+ soup_server_message_set_status (msg, status, NULL);
}
static gboolean
diff --git a/tests/coding-test.c b/tests/coding-test.c
index 696f46f5..75233351 100644
--- a/tests/coding-test.c
+++ b/tests/coding-test.c
@@ -10,26 +10,34 @@ SoupServer *server;
SoupURI *base_uri;
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
const char *accept_encoding, *options;
GSList *codings;
GBytes *response = NULL;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageBody *response_body;
- options = soup_message_headers_get_one (msg->request_headers,
+ request_headers = soup_server_message_get_request_headers (msg);
+ options = soup_message_headers_get_one (request_headers,
"X-Test-Options");
if (!options)
options = "";
- accept_encoding = soup_message_headers_get_list (msg->request_headers,
+ accept_encoding = soup_message_headers_get_list (request_headers,
"Accept-Encoding");
if (accept_encoding && !soup_header_contains (options, "force-encode"))
codings = soup_header_parse_quality_list (accept_encoding, NULL);
else
codings = NULL;
+ response_headers = soup_server_message_get_response_headers (msg);
+
if (codings) {
gboolean claim_deflate, claim_gzip;
const char *extension = NULL, *encoding = NULL;
@@ -58,7 +66,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
response = soup_test_load_resource (resource, NULL);
if (response) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Encoding",
encoding);
}
@@ -75,7 +83,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
* the error with "Content-Encoding: gzip" but there's
* no body, so, eh.
*/
- soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND, NULL);
return;
}
@@ -86,34 +94,35 @@ server_callback (SoupServer *server, SoupMessage *msg,
soup_header_contains (options, "prefer-deflate-raw"))
encoding = "deflate";
- soup_message_headers_replace (msg->response_headers,
+ soup_message_headers_replace (response_headers,
"Content-Encoding",
encoding);
}
/* Content-Type matches the "real" format, not the sent format */
if (g_str_has_suffix (path, ".gz")) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type",
"application/gzip");
} else {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type",
"text/plain");
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_headers_set_encoding (msg->response_headers, SOUP_ENCODING_CHUNKED);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_message_headers_set_encoding (response_headers, SOUP_ENCODING_CHUNKED);
+ response_body = soup_server_message_get_response_body (msg);
if (!soup_header_contains (options, "empty"))
- soup_message_body_append_bytes (msg->response_body, response);
+ soup_message_body_append_bytes (response_body, response);
g_bytes_unref (response);
if (soup_header_contains (options, "trailing-junk")) {
- soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY,
+ soup_message_body_append (response_body, SOUP_MEMORY_COPY,
options, strlen (options));
}
- soup_message_body_complete (msg->response_body);
+ soup_message_body_complete (response_body);
}
typedef struct {
diff --git a/tests/connection-test.c b/tests/connection-test.c
index d267c3ec..f694bf94 100644
--- a/tests/connection-test.c
+++ b/tests/connection-test.c
@@ -7,7 +7,7 @@
#include "soup-connection.h"
#include "soup-socket-private.h"
-#include "soup-server-private.h"
+#include "soup-server-message-private.h"
#include <gio/gnetworking.h>
@@ -16,15 +16,17 @@ SoupURI *base_uri;
GMutex server_mutex;
static void
-forget_close (SoupMessage *msg, gpointer user_data)
+forget_close (SoupServerMessage *msg,
+ gpointer user_data)
{
- soup_message_headers_remove (msg->response_headers, "Connection");
+ soup_message_headers_remove (soup_server_message_get_response_headers (msg),
+ "Connection");
}
static void
-close_socket (SoupMessage *msg, gpointer user_data)
+close_socket (SoupServerMessage *msg,
+ SoupSocket *sock)
{
- SoupSocket *sock = user_data;
GSocket *gsocket;
int sockfd;
@@ -42,7 +44,8 @@ close_socket (SoupMessage *msg, gpointer user_data)
/* Then add the missing data to the message now, so SoupServer
* can clean up after itself properly.
*/
- soup_message_body_append (msg->response_body, SOUP_MEMORY_STATIC,
+ soup_message_body_append (soup_server_message_get_response_body (msg),
+ SOUP_MEMORY_STATIC,
"foo", 3);
}
@@ -53,8 +56,9 @@ timeout_socket (SoupSocket *sock, gpointer user_data)
}
static void
-timeout_request_started (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client, gpointer user_data)
+timeout_request_started (SoupServer *server,
+ SoupServerMessage *msg,
+ gpointer user_data)
{
SoupSocket *sock;
GMainContext *context = g_main_context_get_thread_default ();
@@ -62,7 +66,7 @@ timeout_request_started (SoupServer *server, SoupMessage *msg,
g_signal_handlers_disconnect_by_func (server, timeout_request_started, NULL);
- sock = soup_client_context_get_soup_socket (client);
+ sock = soup_server_message_get_soup_socket (msg);
readable = g_signal_connect (sock, "readable",
G_CALLBACK (timeout_socket), NULL);
@@ -104,10 +108,14 @@ setup_timeout_persistent (SoupServer *server, SoupSocket *sock)
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
+ const char *method;
+
/* The way this gets used in the tests, we don't actually
* need to hold it through the whole function, so it's simpler
* to just release it right away.
@@ -115,21 +123,25 @@ server_callback (SoupServer *server, SoupMessage *msg,
g_mutex_lock (&server_mutex);
g_mutex_unlock (&server_mutex);
- if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ method = soup_server_message_get_method (msg);
+ if (method != SOUP_METHOD_GET && method != SOUP_METHOD_POST) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
if (g_str_has_prefix (path, "/content-length/")) {
gboolean too_long = strcmp (path, "/content-length/long") == 0;
gboolean no_close = strcmp (path, "/content-length/noclose") == 0;
+ SoupMessageHeaders *response_headers;
+
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC, "foobar", 6);
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC, "foobar", 6);
+ response_headers = soup_server_message_get_response_headers (msg);
if (too_long)
- soup_message_headers_set_content_length (msg->response_headers, 9);
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_set_content_length (response_headers, 9);
+ soup_message_headers_append (response_headers,
"Connection", "close");
if (too_long) {
@@ -140,7 +152,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
* the declared Content-Length. Instead, we
* forcibly close the socket at that point.
*/
- sock = soup_client_context_get_soup_socket (context);
+ sock = soup_server_message_get_soup_socket (msg);
g_signal_connect (msg, "wrote-chunk",
G_CALLBACK (close_socket), sock);
} else if (no_close) {
@@ -158,13 +170,13 @@ server_callback (SoupServer *server, SoupMessage *msg,
if (!strcmp (path, "/timeout-persistent")) {
SoupSocket *sock;
- sock = soup_client_context_get_soup_socket (context);
+ sock = soup_server_message_get_soup_socket (msg);
setup_timeout_persistent (server, sock);
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC, "index", 5);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC, "index", 5);
return;
}
diff --git a/tests/context-test.c b/tests/context-test.c
index a47a3142..e8c55dc8 100644
--- a/tests/context-test.c
+++ b/tests/context-test.c
@@ -10,12 +10,13 @@ static char *base_uri;
typedef struct {
SoupServer *server;
- SoupMessage *msg;
+ SoupServerMessage *msg;
GSource *timeout;
} SlowData;
static void
-request_finished (SoupMessage *msg, gpointer data)
+request_finished (SoupServerMessage *msg,
+ gpointer data)
{
SlowData *sd = data;
@@ -28,10 +29,12 @@ static gboolean
add_body_chunk (gpointer data)
{
SlowData *sd = data;
+ SoupMessageBody *response_body;
- soup_message_body_append (sd->msg->response_body,
+ response_body = soup_server_message_get_response_body (sd->msg);
+ soup_message_body_append (response_body,
SOUP_MEMORY_STATIC, "OK\r\n", 4);
- soup_message_body_complete (sd->msg->response_body);
+ soup_message_body_complete (response_body);
soup_server_unpause_message (sd->server, sd->msg);
g_object_unref (sd->msg);
@@ -39,25 +42,29 @@ add_body_chunk (gpointer data)
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
SlowData *sd;
+ SoupMessageHeaders *response_headers;
- if (msg->method != SOUP_METHOD_GET) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_GET) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
if (!strcmp (path, "/fast")) {
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC, "OK\r\n", 4);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC, "OK\r\n", 4);
return;
}
- soup_message_headers_set_encoding (msg->response_headers,
+ response_headers = soup_server_message_get_response_headers (msg);
+ soup_message_headers_set_encoding (response_headers,
SOUP_ENCODING_CHUNKED);
g_object_ref (msg);
soup_server_pause_message (server, msg);
diff --git a/tests/continue-test.c b/tests/continue-test.c
index 85d1a4e6..2b63b1b7 100644
--- a/tests/continue-test.c
+++ b/tests/continue-test.c
@@ -14,37 +14,65 @@ static SoupURI *base_uri;
static GSList *events;
static void
-event (SoupMessage *msg, const char *side, const char *message)
+client_event (SoupMessage *msg,
+ const char *message)
{
- char *data = g_strdup_printf ("%s-%s", side, message);
+ char *data = g_strdup_printf ("client-%s", message);
+
+ debug_printf (2, " %s", data);
+ debug_printf (2, "\n");
+
+ events = g_slist_append (events, data);
+}
+
+static void
+server_event (SoupServerMessage *msg,
+ const char *message)
+{
+ char *data = g_strdup_printf ("server-%s", message);
gboolean record_status =
(!strcmp (data, "server-wrote_headers") ||
!strcmp (data, "server-wrote_informational"));
+ const char *reason_phrase;
+ guint status_code = soup_server_message_get_status (msg, &reason_phrase);
debug_printf (2, " %s", data);
if (record_status)
- debug_printf (2, " (%s)", msg->reason_phrase);
+ debug_printf (2, " (%s)", reason_phrase);
debug_printf (2, "\n");
events = g_slist_append (events, data);
if (record_status)
- events = g_slist_append (events, GUINT_TO_POINTER (msg->status_code));
+ events = g_slist_append (events, GUINT_TO_POINTER (status_code));
}
-#define EVENT_HANDLER(name) \
+#define CLIENT_EVENT_HANDLER(name) \
static void \
-name (SoupMessage *msg, gpointer side) \
+client_##name (SoupMessage *msg, gpointer side) \
{ \
- event (msg, side, #name); \
+ client_event (msg, #name); \
}
-EVENT_HANDLER (got_informational)
-EVENT_HANDLER (got_headers)
-EVENT_HANDLER (got_body)
-EVENT_HANDLER (wrote_informational)
-EVENT_HANDLER (wrote_headers)
-EVENT_HANDLER (wrote_body)
-EVENT_HANDLER (finished)
+#define SERVER_EVENT_HANDLER(name) \
+static void \
+server_##name (SoupServerMessage *msg, gpointer side) \
+{ \
+ server_event (msg, #name); \
+}
+
+CLIENT_EVENT_HANDLER (got_informational)
+CLIENT_EVENT_HANDLER (got_headers)
+CLIENT_EVENT_HANDLER (got_body)
+CLIENT_EVENT_HANDLER (wrote_headers)
+CLIENT_EVENT_HANDLER (wrote_body)
+CLIENT_EVENT_HANDLER (finished)
+
+SERVER_EVENT_HANDLER (got_headers)
+SERVER_EVENT_HANDLER (got_body)
+SERVER_EVENT_HANDLER (wrote_informational)
+SERVER_EVENT_HANDLER (wrote_headers)
+SERVER_EVENT_HANDLER (wrote_body)
+SERVER_EVENT_HANDLER (finished)
static void
restarted (SoupMessage *msg,
@@ -76,7 +104,6 @@ do_message (const char *path, gboolean long_body,
}
soup_uri_set_path (uri, path);
msg = soup_message_new_from_uri ("POST", uri);
- g_print ("DBG: soup_message_new_from_uri: %p\n", msg);
soup_uri_free (uri);
body = long_body ? LONG_BODY : SHORT_BODY;
@@ -88,20 +115,18 @@ do_message (const char *path, gboolean long_body,
SOUP_EXPECTATION_CONTINUE);
}
- g_signal_connect (msg, "got_informational",
- G_CALLBACK (got_informational), "client");
- g_signal_connect (msg, "got_headers",
- G_CALLBACK (got_headers), "client");
- g_signal_connect (msg, "got_body",
- G_CALLBACK (got_body), "client");
- g_signal_connect (msg, "wrote_informational",
- G_CALLBACK (wrote_informational), "client");
- g_signal_connect (msg, "wrote_headers",
- G_CALLBACK (wrote_headers), "client");
- g_signal_connect (msg, "wrote_body",
- G_CALLBACK (wrote_body), "client");
+ g_signal_connect (msg, "got-informational",
+ G_CALLBACK (client_got_informational), NULL);
+ g_signal_connect (msg, "got-headers",
+ G_CALLBACK (client_got_headers), NULL);
+ g_signal_connect (msg, "got-body",
+ G_CALLBACK (client_got_body), NULL);
+ g_signal_connect (msg, "wrote-headers",
+ G_CALLBACK (client_wrote_headers), NULL);
+ g_signal_connect (msg, "wrote-body",
+ G_CALLBACK (client_wrote_body), NULL);
g_signal_connect (msg, "finished",
- G_CALLBACK (finished), "client");
+ G_CALLBACK (client_finished), NULL);
g_signal_connect (msg, "restarted",
G_CALLBACK (restarted), request_body);
@@ -401,47 +426,54 @@ do_test_auth_long_expect_pass (void)
/* SERVER */
static void
-server_got_headers (SoupMessage *msg, gpointer server)
+_server_got_headers (SoupServerMessage *msg,
+ gpointer server)
{
+ guint status_code;
+ SoupMessageHeaders *request_headers;
+
+ status_code = soup_server_message_get_status (msg, NULL);
/* FIXME */
- if (msg->status_code != SOUP_STATUS_CONTINUE &&
- msg->status_code != 0)
+ if (status_code != SOUP_STATUS_CONTINUE && status_code != 0)
return;
- if (soup_message_headers_get_expectations (msg->request_headers) &
+ request_headers = soup_server_message_get_request_headers (msg);
+ if (soup_message_headers_get_expectations (request_headers) &
SOUP_EXPECTATION_CONTINUE) {
const char *length;
- length = soup_message_headers_get_one (msg->request_headers,
+ length = soup_message_headers_get_one (request_headers,
"Content-Length");
if (length && atoi (length) > MAX_POST_LENGTH) {
- soup_message_set_status (msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE);
- soup_message_headers_append (msg->response_headers, "Connection", "close");
+ SoupMessageHeaders *response_headers;
+
+ response_headers = soup_server_message_get_response_headers (msg);
+ soup_server_message_set_status (msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE, NULL);
+ soup_message_headers_append (response_headers, "Connection", "close");
}
}
-}
+}
static void
-request_started (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client, gpointer user_data)
+request_started (SoupServer *server,
+ SoupServerMessage *msg,
+ gpointer user_data)
{
- g_signal_connect (msg, "got_headers",
- G_CALLBACK (server_got_headers), server);
-
- g_signal_connect (msg, "got_informational",
- G_CALLBACK (got_informational), "server");
- g_signal_connect (msg, "got_headers",
- G_CALLBACK (got_headers), "server");
- g_signal_connect (msg, "got_body",
- G_CALLBACK (got_body), "server");
- g_signal_connect (msg, "wrote_informational",
- G_CALLBACK (wrote_informational), "server");
- g_signal_connect (msg, "wrote_headers",
- G_CALLBACK (wrote_headers), "server");
- g_signal_connect (msg, "wrote_body",
- G_CALLBACK (wrote_body), "server");
+ g_signal_connect (msg, "got-headers",
+ G_CALLBACK (_server_got_headers), server);
+
+ g_signal_connect (msg, "got-headers",
+ G_CALLBACK (server_got_headers), NULL);
+ g_signal_connect (msg, "got-body",
+ G_CALLBACK (server_got_body), NULL);
+ g_signal_connect (msg, "wrote-informational",
+ G_CALLBACK (server_wrote_informational), NULL);
+ g_signal_connect (msg, "wrote-headers",
+ G_CALLBACK (server_wrote_headers), NULL);
+ g_signal_connect (msg, "wrote-body",
+ G_CALLBACK (server_wrote_body), NULL);
g_signal_connect (msg, "finished",
- G_CALLBACK (finished), "server");
+ G_CALLBACK (server_finished), NULL);
}
static gboolean
@@ -452,18 +484,25 @@ auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- if (msg->method != SOUP_METHOD_POST) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
- soup_message_headers_append (msg->response_headers, "Connection", "close");
- } else if (msg->request_body->length > MAX_POST_LENGTH) {
- soup_message_set_status (msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE);
- soup_message_headers_append (msg->response_headers, "Connection", "close");
+ SoupMessageHeaders *response_headers;
+ SoupMessageBody *request_body;
+
+ response_headers = soup_server_message_get_response_headers (msg);
+ request_body = soup_server_message_get_request_body (msg);
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_POST) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
+ soup_message_headers_append (response_headers, "Connection", "close");
+ } else if (request_body->length > MAX_POST_LENGTH) {
+ soup_server_message_set_status (msg, SOUP_STATUS_REQUEST_ENTITY_TOO_LARGE, NULL);
+ soup_message_headers_append (response_headers, "Connection", "close");
} else
- soup_message_set_status (msg, SOUP_STATUS_CREATED);
+ soup_server_message_set_status (msg, SOUP_STATUS_CREATED, NULL);
}
static SoupServer *
diff --git a/tests/cookies-test.c b/tests/cookies-test.c
index 63c9e711..163f4f42 100644
--- a/tests/cookies-test.c
+++ b/tests/cookies-test.c
@@ -11,27 +11,34 @@ const char *first_party = "http://127.0.0.1/";
const char *third_party = "http://localhost/";
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
+ SoupMessageHeaders *response_headers;
+ SoupMessageHeaders *request_headers;
+
+ response_headers = soup_server_message_get_response_headers (msg);
+ request_headers = soup_server_message_get_request_headers (msg);
if (g_str_equal (path, "/index.html")) {
- soup_message_headers_replace (msg->response_headers,
+ soup_message_headers_replace (response_headers,
"Set-Cookie",
"foo=bar");
} else if (g_str_equal (path, "/foo.jpg")) {
- soup_message_headers_replace (msg->response_headers,
+ soup_message_headers_replace (response_headers,
"Set-Cookie",
"baz=qux");
- } else if (soup_message_headers_get_one (msg->request_headers,
+ } else if (soup_message_headers_get_one (request_headers,
"Echo-Set-Cookie")) {
- soup_message_headers_replace (msg->response_headers,
+ soup_message_headers_replace (response_headers,
"Set-Cookie",
- soup_message_headers_get_one (msg->request_headers,
+ soup_message_headers_get_one (request_headers,
"Echo-Set-Cookie"));
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
typedef struct {
diff --git a/tests/forms-test.c b/tests/forms-test.c
index 1a07fa00..9d069a4c 100644
--- a/tests/forms-test.c
+++ b/tests/forms-test.c
@@ -250,16 +250,20 @@ do_form_decode_test (void)
}
static void
-hello_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+hello_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
char *title, *name, *fmt;
const char *content_type;
GString *buf;
+ const char *method;
- if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_HEAD) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ method = soup_server_message_get_method (msg);
+ if (method != SOUP_METHOD_GET && method != SOUP_METHOD_HEAD) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
@@ -296,17 +300,19 @@ hello_callback (SoupServer *server, SoupMessage *msg,
}
}
- soup_message_set_response (msg, content_type,
- SOUP_MEMORY_TAKE,
- buf->str, buf->len);
+ soup_server_message_set_response (msg, content_type,
+ SOUP_MEMORY_TAKE,
+ buf->str, buf->len);
g_string_free (buf, FALSE);
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
static void
-md5_get_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+md5_get_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
const char *file = NULL, *md5sum = NULL, *fmt;
const char *content_type;
@@ -340,17 +346,19 @@ md5_get_callback (SoupServer *server, SoupMessage *msg,
g_string_append_printf (buf, "%s", md5sum);
}
- soup_message_set_response (msg, content_type,
- SOUP_MEMORY_TAKE,
- buf->str, buf->len);
+ soup_server_message_set_response (msg, content_type,
+ SOUP_MEMORY_TAKE,
+ buf->str, buf->len);
g_string_free (buf, FALSE);
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
static void
-md5_post_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+md5_post_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
const char *content_type;
GHashTable *params;
@@ -358,17 +366,23 @@ md5_post_callback (SoupServer *server, SoupMessage *msg,
char *filename, *md5sum, *redirect_uri;
GBytes *file;
SoupURI *uri;
+ SoupMultipart *multipart;
+ GBytes *body;
+ SoupMessageHeaders *request_headers;
- content_type = soup_message_headers_get_content_type (msg->request_headers, NULL);
+ request_headers = soup_server_message_get_request_headers (msg);
+ content_type = soup_message_headers_get_content_type (request_headers, NULL);
if (!content_type || strcmp (content_type, "multipart/form-data") != 0) {
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
return;
}
- params = soup_form_decode_multipart (msg, "file",
- &filename, NULL, &file);
+ body = soup_message_body_flatten (soup_server_message_get_request_body (msg));
+ multipart = soup_multipart_new_from_message (request_headers, body);
+ g_bytes_unref (body);
+ params = multipart ? soup_form_decode_multipart (multipart, "file", &filename, NULL, &file) : NULL;
if (!params) {
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
return;
}
fmt = g_hash_table_lookup (params, "fmt");
@@ -376,7 +390,7 @@ md5_post_callback (SoupServer *server, SoupMessage *msg,
md5sum = g_compute_checksum_for_bytes (G_CHECKSUM_MD5, file);
g_bytes_unref (file);
- uri = soup_uri_copy (soup_message_get_uri (msg));
+ uri = soup_uri_copy (soup_server_message_get_uri (msg));
soup_uri_set_query_from_fields (uri,
"file", filename ? filename : "",
"md5sum", md5sum,
@@ -384,7 +398,7 @@ md5_post_callback (SoupServer *server, SoupMessage *msg,
NULL);
redirect_uri = soup_uri_to_string (uri, FALSE);
- soup_message_set_redirect (msg, SOUP_STATUS_SEE_OTHER, redirect_uri);
+ soup_server_message_set_redirect (msg, SOUP_STATUS_SEE_OTHER, redirect_uri);
g_free (redirect_uri);
soup_uri_free (uri);
@@ -394,16 +408,22 @@ md5_post_callback (SoupServer *server, SoupMessage *msg,
}
static void
-md5_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+md5_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- if (msg->method == SOUP_METHOD_GET || msg->method == SOUP_METHOD_HEAD)
- md5_get_callback (server, msg, path, query, context, data);
- else if (msg->method == SOUP_METHOD_POST)
- md5_post_callback (server, msg, path, query, context, data);
+ const char *method;
+
+ method = soup_server_message_get_method (msg);
+
+ if (method == SOUP_METHOD_GET || method == SOUP_METHOD_HEAD)
+ md5_get_callback (server, msg, path, query, data);
+ else if (method == SOUP_METHOD_POST)
+ md5_post_callback (server, msg, path, query, data);
else
- soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);
+ soup_server_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED, NULL);
}
static gboolean run_tests = TRUE;
diff --git a/tests/hsts-db-test.c b/tests/hsts-db-test.c
index f45e355d..2adc05b7 100644
--- a/tests/hsts-db-test.c
+++ b/tests/hsts-db-test.c
@@ -13,42 +13,47 @@ SoupURI *https_uri;
test the Soup HSTS feature.
*/
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
+ SoupMessageHeaders *response_headers;
const char *server_protocol = data;
+ response_headers = soup_server_message_get_response_headers (msg);
+
if (strcmp (server_protocol, "http") == 0) {
char *uri_string;
SoupURI *uri = soup_uri_new ("https://localhost");
soup_uri_set_path (uri, path);
uri_string = soup_uri_to_string (uri, FALSE);
fprintf (stderr, "server is redirecting to HTTPS\n");
- soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, uri_string);
+ soup_server_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, uri_string);
soup_uri_free (uri);
g_free (uri_string);
} else if (strcmp (server_protocol, "https") == 0) {
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
if (strcmp (path, "/long-lasting") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=31536000");
} else if (strcmp (path, "/two-seconds") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=2");
} else if (strcmp (path, "/delete") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=0");
} else if (strcmp (path, "/subdomains") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=31536000; includeSubDomains");
}
else if (strcmp (path, "/very-long-lasting") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=631138519");
}
diff --git a/tests/hsts-test.c b/tests/hsts-test.c
index e8c7d877..9bb36edf 100644
--- a/tests/hsts-test.c
+++ b/tests/hsts-test.c
@@ -13,88 +13,93 @@ SoupURI *https_uri;
test the Soup HSTS feature.
*/
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
+ SoupMessageHeaders *response_headers;
const char *server_protocol = data;
+ response_headers = soup_server_message_get_response_headers (msg);
+
if (strcmp (server_protocol, "http") == 0) {
if (strcmp (path, "/insecure") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=31536000");
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
} else {
char *uri_string;
SoupURI *uri = soup_uri_new ("https://localhost");
soup_uri_set_path (uri, path);
uri_string = soup_uri_to_string (uri, FALSE);
- soup_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, uri_string);
+ soup_server_message_set_redirect (msg, SOUP_STATUS_MOVED_PERMANENTLY, uri_string);
soup_uri_free (uri);
g_free (uri_string);
}
} else if (strcmp (server_protocol, "https") == 0) {
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
if (strcmp (path, "/long-lasting") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=31536000");
} else if (strcmp (path, "/two-seconds") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=2");
} else if (strcmp (path, "/three-seconds") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=3");
} else if (strcmp (path, "/delete") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=0");
} else if (strcmp (path, "/subdomains") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=31536000; includeSubDomains");
} else if (strcmp (path, "/no-sts-header") == 0) {
/* Do not add anything */
} else if (strcmp (path, "/multiple-headers") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=31536000; includeSubDomains");
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=1; includeSubDomains");
} else if (strcmp (path, "/missing-values") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"");
} else if (strcmp (path, "/invalid-values") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=foo");
} else if (strcmp (path, "/extra-values-0") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=3600; foo");
} else if (strcmp (path, "/extra-values-1") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
" max-age=3600; includeDomains; foo");
} else if (strcmp (path, "/duplicated-directives") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=3600; includeDomains; includeDomains");
} else if (strcmp (path, "/case-insensitive-header") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"STRICT-TRANSPORT-SECURITY",
"max-age=3600");
} else if (strcmp (path, "/case-insensitive-directives") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"MAX-AGE=3600; includesubdomains");
} else if (strcmp (path, "/optional-quotations") == 0) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Strict-Transport-Security",
"max-age=\"31536000\"");
}
diff --git a/tests/misc-test.c b/tests/misc-test.c
index 759c2abf..beb586ba 100644
--- a/tests/misc-test.c
+++ b/tests/misc-test.c
@@ -27,29 +27,37 @@ timeout_finish_message (gpointer msg)
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
-{
- SoupURI *uri = soup_message_get_uri (msg);
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
+{
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ const char *method = soup_server_message_get_method (msg);
+ SoupURI *uri = soup_server_message_get_uri (msg);
const char *server_protocol = data;
- if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ if (method != SOUP_METHOD_GET && method != SOUP_METHOD_POST) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
if (!strcmp (path, "/redirect")) {
- soup_message_set_redirect (msg, SOUP_STATUS_FOUND, "/");
+ soup_server_message_set_redirect (msg, SOUP_STATUS_FOUND, "/");
return;
}
+ request_headers = soup_server_message_get_request_headers (msg);
+ response_headers = soup_server_message_get_response_headers (msg);
+
if (!strcmp (path, "/alias-redirect")) {
SoupURI *redirect_uri;
char *redirect_string;
const char *redirect_protocol;
- redirect_protocol = soup_message_headers_get_one (msg->request_headers, "X-Redirect-Protocol");
+ redirect_protocol = soup_message_headers_get_one (request_headers, "X-Redirect-Protocol");
redirect_uri = soup_uri_copy (uri);
soup_uri_set_scheme (redirect_uri, "foo");
@@ -60,13 +68,13 @@ server_callback (SoupServer *server, SoupMessage *msg,
soup_uri_set_path (redirect_uri, "/alias-redirected");
redirect_string = soup_uri_to_string (redirect_uri, FALSE);
- soup_message_set_redirect (msg, SOUP_STATUS_FOUND, redirect_string);
+ soup_server_message_set_redirect (msg, SOUP_STATUS_FOUND, redirect_string);
g_free (redirect_string);
soup_uri_free (redirect_uri);
return;
} else if (!strcmp (path, "/alias-redirected")) {
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_headers_append (msg->response_headers,
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_message_headers_append (response_headers,
"X-Redirected-Protocol",
server_protocol);
return;
@@ -79,14 +87,14 @@ server_callback (SoupServer *server, SoupMessage *msg,
1000, timeout_finish_message, msg);
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
if (!strcmp (uri->host, "foo")) {
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC, "foo-index", 9);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC, "foo-index", 9);
return;
} else {
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC, "index", 5);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC, "index", 5);
return;
}
}
diff --git a/tests/multipart-test.c b/tests/multipart-test.c
index c0c09dc8..d9a00ae1 100644
--- a/tests/multipart-test.c
+++ b/tests/multipart-test.c
@@ -58,26 +58,33 @@ const char *payload = \
"\r\n--cut-here--";
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- if (msg->method != SOUP_METHOD_GET) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ SoupMessageHeaders *response_headers;
+ SoupMessageBody *response_body;
+
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_GET) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
- soup_message_headers_append (msg->response_headers,
+ response_headers = soup_server_message_get_response_headers (msg);
+ soup_message_headers_append (response_headers,
"Content-Type", "multipart/x-mixed-replace; boundary=cut-here");
- soup_message_body_append (msg->response_body,
+ response_body = soup_server_message_get_response_body (msg);
+ soup_message_body_append (response_body,
SOUP_MEMORY_STATIC,
payload,
strlen (payload));
- soup_message_body_complete (msg->response_body);
+ soup_message_body_complete (response_body);
}
static void
diff --git a/tests/no-ssl-test.c b/tests/no-ssl-test.c
index b92dd2c2..02bec973 100644
--- a/tests/no-ssl-test.c
+++ b/tests/no-ssl-test.c
@@ -38,16 +38,15 @@ do_ssl_tests (gconstpointer data)
static void
server_handler (SoupServer *server,
- SoupMessage *msg,
+ SoupServerMessage *msg,
const char *path,
GHashTable *query,
- SoupClientContext *client,
gpointer user_data)
{
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "ok\r\n", 4);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "ok\r\n", 4);
}
int
diff --git a/tests/ntlm-test.c b/tests/ntlm-test.c
index 0a980f9b..c3d69c9b 100644
--- a/tests/ntlm-test.c
+++ b/tests/ntlm-test.c
@@ -55,19 +55,22 @@ clear_state (gpointer connections, GObject *ex_connection)
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *client, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
TestServer *ts = data;
GSocket *socket;
const char *auth;
+ SoupMessageHeaders *request_headers;
NTLMServerState state, required_user = 0;
gboolean auth_required, not_found = FALSE;
gboolean basic_allowed = TRUE, ntlm_allowed = TRUE;
- if (msg->method != SOUP_METHOD_GET) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_GET) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
@@ -86,10 +89,10 @@ server_callback (SoupServer *server, SoupMessage *msg,
if (strstr (path, "/404"))
not_found = TRUE;
- socket = soup_client_context_get_socket (client);
+ socket = soup_server_message_get_socket (msg);
state = GPOINTER_TO_INT (g_hash_table_lookup (ts->connections, socket));
- auth = soup_message_headers_get_one (msg->request_headers,
- "Authorization");
+ request_headers = soup_server_message_get_request_headers (msg);
+ auth = soup_message_headers_get_one (request_headers, "Authorization");
if (auth) {
if (!strncmp (auth, "NTLM ", 5)) {
@@ -126,33 +129,36 @@ server_callback (SoupServer *server, SoupMessage *msg,
auth_required = FALSE;
if (auth_required) {
- soup_message_set_status (msg, SOUP_STATUS_UNAUTHORIZED);
+ SoupMessageHeaders *response_headers;
+ soup_server_message_set_status (msg, SOUP_STATUS_UNAUTHORIZED, NULL);
+
+ response_headers = soup_server_message_get_response_headers (msg);
if (basic_allowed && state != NTLM_RECEIVED_REQUEST) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"WWW-Authenticate",
"Basic realm=\"ntlm-test\"");
}
if (ntlm_allowed && state == NTLM_RECEIVED_REQUEST) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"WWW-Authenticate",
ts->ntlmssp ? ("NTLM " NTLMSSP_CHALLENGE) : ts->ntlmv2 ? ("NTLM " NTLMV2_CHALLENGE) : ("NTLM " NTLMV1_CHALLENGE));
state = NTLM_SENT_CHALLENGE;
} else if (ntlm_allowed) {
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"WWW-Authenticate", "NTLM");
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Connection", "close");
}
} else {
if (not_found)
- soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND, NULL);
else {
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "OK\r\n", 4);
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "OK\r\n", 4);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
}
diff --git a/tests/proxy-test.c b/tests/proxy-test.c
index a17671d4..03c79377 100644
--- a/tests/proxy-test.c
+++ b/tests/proxy-test.c
@@ -238,13 +238,15 @@ do_async_proxy_test (gconstpointer data)
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- SoupURI *uri = soup_message_get_uri (msg);
+ SoupURI *uri = soup_server_message_get_uri (msg);
- soup_message_set_status (msg, uri->fragment ? SOUP_STATUS_BAD_REQUEST : SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, uri->fragment ? SOUP_STATUS_BAD_REQUEST : SOUP_STATUS_OK, NULL);
}
static void
diff --git a/tests/pull-api-test.c b/tests/pull-api-test.c
index f73d8cee..36d44a5e 100644
--- a/tests/pull-api-test.c
+++ b/tests/pull-api-test.c
@@ -52,8 +52,6 @@ typedef struct {
} FullyAsyncData;
static void fully_async_got_headers (SoupMessage *msg, gpointer user_data);
-static void fully_async_got_chunk (SoupMessage *msg, GBytes *chunk,
- gpointer user_data);
static gboolean fully_async_request_chunk (gpointer user_data);
static void
@@ -99,12 +97,6 @@ do_fully_async_test (SoupSession *session,
ad.read_so_far = 0;
ad.expected_status = expected_status;
- /* Since we aren't going to look at the final value of
- * msg->response_body, we tell libsoup to not even bother
- * generating it.
- */
- soup_message_body_set_accumulate (msg->response_body, FALSE);
-
/* Connect to "got_headers", from which we'll decide where to
* go next.
*/
@@ -187,45 +179,11 @@ fully_async_got_headers (SoupMessage *msg, gpointer user_data)
* until one is requested.
*/
ad->chunks_ready = TRUE;
- g_signal_connect (msg, "got_chunk",
- G_CALLBACK (fully_async_got_chunk), ad);
if (!ad->chunk_wanted)
soup_session_pause_message (ad->session, msg);
}
static void
-fully_async_got_chunk (SoupMessage *msg, GBytes *chunk, gpointer user_data)
-{
- FullyAsyncData *ad = user_data;
-
- debug_printf (2, " got chunk from %lu - %lu\n",
- (unsigned long) ad->read_so_far,
- (unsigned long) ad->read_so_far + g_bytes_get_size (chunk));
-
- /* We've got a chunk, let's process it. In the case of the
- * test program, that means comparing it against
- * correct_response to make sure that we got the right data.
- */
- gsize chunk_length = g_bytes_get_size (chunk);
- g_assert_cmpint (ad->read_so_far + chunk_length, <=, g_bytes_get_size (correct_response));
- soup_assert_cmpmem (g_bytes_get_data (chunk, NULL), chunk_length,
- (guchar*)g_bytes_get_data (correct_response, NULL) + ad->read_so_far,
- chunk_length);
- ad->read_so_far += chunk_length;
-
- /* Now pause I/O, and prepare to read another chunk later.
- * (Again, the timeout just abstractly represents the idea of
- * the application requesting another chunk at some random
- * point in the future. You wouldn't be using a timeout in a
- * real program.)
- */
- soup_session_pause_message (ad->session, msg);
- ad->chunk_wanted = FALSE;
-
- ad->timeout = g_timeout_add (10, fully_async_request_chunk, ad);
-}
-
-static void
do_fast_async_test (gconstpointer data)
{
const char *base_uri = data;
diff --git a/tests/range-test.c b/tests/range-test.c
index ce8a744b..bf97f958 100644
--- a/tests/range-test.c
+++ b/tests/range-test.c
@@ -349,15 +349,14 @@ do_apache_range_test (void)
static void
server_handler (SoupServer *server,
- SoupMessage *msg,
+ SoupServerMessage *msg,
const char *path,
GHashTable *query,
- SoupClientContext *client,
gpointer user_data)
{
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_body_append_bytes (msg->response_body,
- full_response);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_message_body_append_bytes (soup_server_message_get_response_body (msg),
+ full_response);
}
static void
diff --git a/tests/redirect-test.c b/tests/redirect-test.c
index d360065a..9ecc2e2d 100644
--- a/tests/redirect-test.c
+++ b/tests/redirect-test.c
@@ -287,72 +287,82 @@ do_async_req_api_test (gconstpointer test)
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
char *remainder;
guint status_code;
+ SoupMessageHeaders *response_headers;
+ const char *method;
/* Make sure that a HTTP/1.0 redirect doesn't cause an
* HTTP/1.0 re-request. (#521848)
*/
- if (soup_message_get_http_version (msg) == SOUP_HTTP_1_0) {
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ if (soup_server_message_get_http_version (msg) == SOUP_HTTP_1_0) {
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
return;
}
+ method = soup_server_message_get_method (msg);
+ response_headers = soup_server_message_get_response_headers (msg);
+
if (g_str_has_prefix (path, "/bad")) {
if (!strcmp (path, "/bad")) {
- soup_message_set_status (msg, SOUP_STATUS_FOUND);
- soup_message_headers_replace (msg->response_headers,
+ soup_server_message_set_status (msg, SOUP_STATUS_FOUND, NULL);
+ soup_message_headers_replace (response_headers,
"Location",
"/bad with spaces");
} else if (!strcmp (path, "/bad-recursive")) {
- soup_message_set_status (msg, SOUP_STATUS_FOUND);
- soup_message_headers_replace (msg->response_headers,
+ soup_server_message_set_status (msg, SOUP_STATUS_FOUND, NULL);
+ soup_message_headers_replace (response_headers,
"Location",
"/bad-recursive");
} else if (!strcmp (path, "/bad-no-host")) {
- soup_message_set_status (msg, SOUP_STATUS_FOUND);
- soup_message_headers_replace (msg->response_headers,
+ soup_server_message_set_status (msg, SOUP_STATUS_FOUND, NULL);
+ soup_message_headers_replace (response_headers,
"Location",
"about:blank");
} else if (!strcmp (path, "/bad with spaces"))
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
else
- soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND, NULL);
return;
} else if (!strcmp (path, "/server2")) {
- soup_message_set_status (msg, SOUP_STATUS_FOUND);
- soup_message_headers_replace (msg->response_headers,
+ soup_server_message_set_status (msg, SOUP_STATUS_FOUND, NULL);
+ soup_message_headers_replace (response_headers,
"Location",
server2_uri);
return;
} else if (!strcmp (path, "/")) {
- if (msg->method != SOUP_METHOD_GET &&
- msg->method != SOUP_METHOD_HEAD) {
- soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);
+ SoupMessageBody *request_body;
+
+ if (method != SOUP_METHOD_GET &&
+ method != SOUP_METHOD_HEAD) {
+ soup_server_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED, NULL);
return;
}
/* Make sure that redirecting a POST clears the body */
- if (msg->request_body->length) {
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ request_body = soup_server_message_get_request_body (msg);
+ if (request_body->length) {
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
/* FIXME: this is wrong, though it doesn't matter for
* the purposes of this test, and to do the right
* thing currently we'd have to set Content-Length by
* hand.
*/
- if (msg->method != SOUP_METHOD_HEAD) {
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "OK\r\n", 4);
+ if (method != SOUP_METHOD_HEAD) {
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "OK\r\n", 4);
}
return;
}
@@ -360,7 +370,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
status_code = strtoul (path + 1, &remainder, 10);
if (!SOUP_STATUS_IS_REDIRECTION (status_code) ||
(*remainder && *remainder != '/')) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND, NULL);
return;
}
@@ -369,18 +379,20 @@ server_callback (SoupServer *server, SoupMessage *msg,
* the rest of the time.
*/
if (*remainder == '/')
- soup_message_set_http_version (msg, SOUP_HTTP_1_0);
+ soup_server_message_set_http_version (msg, SOUP_HTTP_1_0);
- soup_message_set_redirect (msg, status_code,
- *remainder ? remainder : "/");
+ soup_server_message_set_redirect (msg, status_code,
+ *remainder ? remainder : "/");
}
static void
-server2_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server2_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
int
diff --git a/tests/request-body-test.c b/tests/request-body-test.c
index fb5cd31d..fad90c7f 100644
--- a/tests/request-body-test.c
+++ b/tests/request-body-test.c
@@ -138,30 +138,32 @@ do_request_test (gconstpointer data)
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
SoupMessageBody *md5_body;
char *md5;
if (g_str_has_prefix (path, "/redirect")) {
- soup_message_set_redirect (msg, SOUP_STATUS_FOUND, "/");
+ soup_server_message_set_redirect (msg, SOUP_STATUS_FOUND, "/");
return;
}
- if (msg->method == SOUP_METHOD_PUT) {
- soup_message_set_status (msg, SOUP_STATUS_CREATED);
- md5_body = msg->request_body;
+ if (soup_server_message_get_method (msg) == SOUP_METHOD_PUT) {
+ soup_server_message_set_status (msg, SOUP_STATUS_CREATED, NULL);
+ md5_body = soup_server_message_get_request_body (msg);
} else {
- soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);
+ soup_server_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED, NULL);
return;
}
md5 = g_compute_checksum_for_data (G_CHECKSUM_MD5,
(guchar *)md5_body->data,
md5_body->length);
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
"Content-MD5", md5);
g_free (md5);
}
diff --git a/tests/server-auth-test.c b/tests/server-auth-test.c
index dd92f1a6..54910967 100644
--- a/tests/server-auth-test.c
+++ b/tests/server-auth-test.c
@@ -227,15 +227,20 @@ do_server_auth_test (gconstpointer data)
}
static gboolean
-basic_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
- const char *username, const char *password, gpointer data)
+basic_auth_callback (SoupAuthDomain *auth_domain,
+ SoupServerMessage *msg,
+ const char *username,
+ const char *password,
+ gpointer data)
{
return !strcmp (username, "user") && !strcmp (password, "password");
}
static char *
-digest_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
- const char *username, gpointer data)
+digest_auth_callback (SoupAuthDomain *auth_domain,
+ SoupServerMessage *msg,
+ const char *username,
+ gpointer data)
{
if (strcmp (username, "user") != 0)
return NULL;
@@ -251,27 +256,33 @@ digest_auth_callback (SoupAuthDomain *auth_domain, SoupMessage *msg,
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_HEAD) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ const char *method;
+
+ method = soup_server_message_get_method (msg);
+ if (method != SOUP_METHOD_GET && method != SOUP_METHOD_HEAD) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "OK\r\n", 4);
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "OK\r\n", 4);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
static void
-got_headers_callback (SoupMessage *msg, gpointer data)
+got_headers_callback (SoupServerMessage *msg,
+ gpointer data)
{
const char *header;
- header = soup_message_headers_get_one (msg->request_headers,
+ header = soup_message_headers_get_one (soup_server_message_get_request_headers (msg),
"Authorization");
if (header) {
if (strstr (header, "Basic "))
@@ -282,11 +293,12 @@ got_headers_callback (SoupMessage *msg, gpointer data)
}
static void
-wrote_headers_callback (SoupMessage *msg, gpointer data)
+wrote_headers_callback (SoupServerMessage *msg,
+ gpointer data)
{
const char *header;
- header = soup_message_headers_get_list (msg->response_headers,
+ header = soup_message_headers_get_list (soup_server_message_get_response_headers (msg),
"WWW-Authenticate");
if (header) {
if (strstr (header, "Basic "))
@@ -297,12 +309,13 @@ wrote_headers_callback (SoupMessage *msg, gpointer data)
}
static void
-request_started_callback (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client, gpointer data)
+request_started_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ gpointer data)
{
- g_signal_connect (msg, "got_headers",
+ g_signal_connect (msg, "got-headers",
G_CALLBACK (got_headers_callback), NULL);
- g_signal_connect (msg, "wrote_headers",
+ g_signal_connect (msg, "wrote-headers",
G_CALLBACK (wrote_headers_callback), NULL);
}
diff --git a/tests/server-test.c b/tests/server-test.c
index 3c5a1cab..8b18f8a7 100644
--- a/tests/server-test.c
+++ b/tests/server-test.c
@@ -14,27 +14,32 @@ typedef struct {
} ServerData;
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- soup_message_headers_append (msg->response_headers,
+ const char *method;
+
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
"X-Handled-By", "server_callback");
if (!strcmp (path, "*")) {
soup_test_assert (FALSE, "default server_callback got request for '*'");
- soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, NULL);
return;
}
- if (msg->method != SOUP_METHOD_GET && msg->method != SOUP_METHOD_POST) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ method = soup_server_message_get_method (msg);
+ if (method != SOUP_METHOD_GET && method != SOUP_METHOD_POST) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC, "index", 5);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC, "index", 5);
}
static void
@@ -90,25 +95,27 @@ server_teardown (ServerData *sd, gconstpointer test_data)
}
static void
-server_star_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_star_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
"X-Handled-By", "star_callback");
if (strcmp (path, "*") != 0) {
soup_test_assert (FALSE, "server_star_callback got request for '%s'", path);
- soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR);
+ soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, NULL);
return;
}
- if (msg->method != SOUP_METHOD_OPTIONS) {
- soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_OPTIONS) {
+ soup_server_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED, NULL);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
/* Server handlers for "*" work but are separate from handlers for
@@ -345,26 +352,28 @@ do_dot_dot_test (ServerData *sd, gconstpointer test_data)
}
static void
-ipv6_server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+ipv6_server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
const char *host;
GSocketAddress *addr;
char expected_host[128];
- addr = soup_client_context_get_local_address (context);
+ addr = soup_server_message_get_local_address (msg);
g_snprintf (expected_host, sizeof (expected_host),
"[::1]:%d",
g_inet_socket_address_get_port (G_INET_SOCKET_ADDRESS (addr)));
- host = soup_message_headers_get_one (msg->request_headers, "Host");
+ host = soup_message_headers_get_one (soup_server_message_get_request_headers (msg), "Host");
g_assert_cmpstr (host, ==, expected_host);
if (g_test_failed ())
- soup_message_set_status (msg, SOUP_STATUS_BAD_REQUEST);
+ soup_server_message_set_status (msg, SOUP_STATUS_BAD_REQUEST, NULL);
else
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
static void
@@ -413,19 +422,21 @@ do_ipv6_test (ServerData *sd, gconstpointer test_data)
}
static void
-multi_server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+multi_server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
GSocketAddress *addr;
GInetSocketAddress *iaddr;
SoupURI *uri;
char *uristr, *addrstr;
- addr = soup_client_context_get_local_address (context);
+ addr = soup_server_message_get_local_address (msg);
iaddr = G_INET_SOCKET_ADDRESS (addr);
- uri = soup_message_get_uri (msg);
+ uri = soup_server_message_get_uri (msg);
uristr = soup_uri_to_string (uri, FALSE);
addrstr = g_inet_address_to_string (g_inet_socket_address_get_address (iaddr));
@@ -436,9 +447,9 @@ multi_server_callback (SoupServer *server, SoupMessage *msg,
/* FIXME ssl */
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_TAKE, uristr, strlen (uristr));
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_TAKE, uristr, strlen (uristr));
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
}
static void
@@ -794,27 +805,29 @@ g_test_io_stream_new (GInputStream *input, GOutputStream *output)
}
static void
-mem_server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+mem_server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
GSocketAddress *addr;
GSocket *sock;
const char *host;
- addr = soup_client_context_get_local_address (context);
+ addr = soup_server_message_get_local_address (msg);
g_assert_nonnull (addr);
- addr = soup_client_context_get_remote_address (context);
+ addr = soup_server_message_get_remote_address (msg);
g_assert_nonnull (addr);
- sock = soup_client_context_get_socket (context);
+ sock = soup_server_message_get_socket (msg);
g_assert_null (sock);
- host = soup_client_context_get_host (context);
+ host = soup_server_message_get_remote_host (msg);
g_assert_cmpstr (host, ==, "127.0.0.1");
- server_callback (server, msg, path, query, context, data);
+ server_callback (server, msg, path, query, data);
}
static void
@@ -858,7 +871,7 @@ do_iostream_accept_test (void)
typedef struct {
SoupServer *server;
- SoupMessage *smsg;
+ SoupServerMessage *smsg;
gboolean handler_called;
gboolean paused;
} UnhandledServerData;
@@ -873,15 +886,17 @@ idle_unpause_message (gpointer user_data)
}
static void
-unhandled_server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+unhandled_server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
UnhandledServerData *usd = data;
usd->handler_called = TRUE;
- if (soup_message_headers_get_one (msg->request_headers, "X-Test-Server-Pause")) {
+ if (soup_message_headers_get_one (soup_server_message_get_request_headers (msg), "X-Test-Server-Pause")) {
usd->paused = TRUE;
usd->server = server;
usd->smsg = msg;
@@ -946,7 +961,9 @@ do_fail_500_test (ServerData *sd, gconstpointer pause)
}
static void
-stream_got_chunk (SoupMessage *msg, GBytes *chunk, gpointer user_data)
+stream_got_chunk (SoupServerMessage *msg,
+ GBytes *chunk,
+ gpointer user_data)
{
GChecksum *checksum = user_data;
@@ -954,26 +971,29 @@ stream_got_chunk (SoupMessage *msg, GBytes *chunk, gpointer user_data)
}
static void
-stream_got_body (SoupMessage *msg, gpointer user_data)
+stream_got_body (SoupServerMessage *msg,
+ gpointer user_data)
{
GChecksum *checksum = user_data;
const char *md5 = g_checksum_get_string (checksum);
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY,
- md5, strlen (md5));
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY,
+ md5, strlen (md5));
g_checksum_free (checksum);
}
static void
-early_stream_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+early_stream_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
GChecksum *checksum;
- if (msg->method != SOUP_METHOD_POST) {
- soup_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED);
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_POST) {
+ soup_server_message_set_status (msg, SOUP_STATUS_METHOD_NOT_ALLOWED, NULL);
return;
}
@@ -983,7 +1003,7 @@ early_stream_callback (SoupServer *server, SoupMessage *msg,
g_signal_connect (msg, "got-body",
G_CALLBACK (stream_got_body), checksum);
- soup_message_body_set_accumulate (msg->request_body, TRUE);
+ soup_message_body_set_accumulate (soup_server_message_get_request_body (msg), TRUE);
}
static void
@@ -1016,12 +1036,14 @@ do_early_stream_test (ServerData *sd, gconstpointer test_data)
}
static void
-early_respond_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+early_respond_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
if (!strcmp (path, "/"))
- soup_message_set_status (msg, SOUP_STATUS_FORBIDDEN);
+ soup_server_message_set_status (msg, SOUP_STATUS_FORBIDDEN, NULL);
}
static void
@@ -1040,7 +1062,6 @@ do_early_respond_test (ServerData *sd, gconstpointer test_data)
msg = soup_message_new_from_uri ("GET", sd->base_uri);
soup_test_session_send_message (session, msg);
soup_test_assert_message_status (msg, SOUP_STATUS_FORBIDDEN);
- g_assert_cmpint (msg->response_body->length, ==, 0);
g_object_unref (msg);
/* The early handler will ignore this one */
@@ -1057,11 +1078,13 @@ do_early_respond_test (ServerData *sd, gconstpointer test_data)
}
static void
-early_multi_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+early_multi_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
- soup_message_headers_append (msg->response_headers, "X-Early", "yes");
+ soup_message_headers_append (soup_server_message_get_response_headers (msg), "X-Early", "yes");
}
static void
@@ -1147,8 +1170,7 @@ typedef struct {
typedef struct {
SoupServer *self;
- SoupMessage *msg;
- SoupClientContext *context;
+ SoupServerMessage *msg;
GCancellable *cancellable;
TunnelEnd client, server;
@@ -1272,11 +1294,12 @@ tunnel_read_cb (GObject *object,
}
static void
-start_tunnel (SoupMessage *msg, gpointer user_data)
+start_tunnel (SoupServerMessage *msg,
+ gpointer user_data)
{
Tunnel *tunnel = user_data;
- tunnel->client.iostream = soup_client_context_steal_connection (tunnel->context);
+ tunnel->client.iostream = soup_server_message_steal_connection (msg);
tunnel->client.istream = g_io_stream_get_input_stream (tunnel->client.iostream);
tunnel->client.ostream = g_io_stream_get_output_stream (tunnel->client.iostream);
g_clear_object (&tunnel->self);
@@ -1309,10 +1332,10 @@ tunnel_connected_cb (GObject *object,
tunnel->server.iostream = (GIOStream *)
g_socket_client_connect_to_host_finish (G_SOCKET_CLIENT (object), result, &error);
if (!tunnel->server.iostream) {
- soup_message_set_status (tunnel->msg, SOUP_STATUS_BAD_GATEWAY);
- soup_message_set_response (tunnel->msg, "text/plain",
- SOUP_MEMORY_COPY,
- error->message, strlen (error->message));
+ soup_server_message_set_status (tunnel->msg, SOUP_STATUS_BAD_GATEWAY, NULL);
+ soup_server_message_set_response (tunnel->msg, "text/plain",
+ SOUP_MEMORY_COPY,
+ error->message, strlen (error->message));
g_error_free (error);
soup_server_unpause_message (tunnel->self, tunnel->msg);
tunnel_close (tunnel);
@@ -1322,23 +1345,25 @@ tunnel_connected_cb (GObject *object,
tunnel->server.istream = g_io_stream_get_input_stream (tunnel->server.iostream);
tunnel->server.ostream = g_io_stream_get_output_stream (tunnel->server.iostream);
- soup_message_set_status (tunnel->msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (tunnel->msg, SOUP_STATUS_OK, NULL);
soup_server_unpause_message (tunnel->self, tunnel->msg);
g_signal_connect (tunnel->msg, "wrote-body",
G_CALLBACK (start_tunnel), tunnel);
}
static void
-proxy_server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+proxy_server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
GSocketClient *sclient;
SoupURI *dest_uri;
Tunnel *tunnel;
- if (msg->method != SOUP_METHOD_CONNECT) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_CONNECT) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
@@ -1347,9 +1372,8 @@ proxy_server_callback (SoupServer *server, SoupMessage *msg,
tunnel = g_new0 (Tunnel, 1);
tunnel->self = g_object_ref (server);
tunnel->msg = g_object_ref (msg);
- tunnel->context = context;
- dest_uri = soup_message_get_uri (msg);
+ dest_uri = soup_server_message_get_uri (msg);
sclient = g_socket_client_new ();
g_socket_client_connect_to_host_async (sclient, dest_uri->host, dest_uri->port,
NULL, tunnel_connected_cb, tunnel);
diff --git a/tests/session-test.c b/tests/session-test.c
index a3952f7d..be85d669 100644
--- a/tests/session-test.c
+++ b/tests/session-test.c
@@ -18,10 +18,9 @@ timeout_cb (gpointer user_data)
static void
server_handler (SoupServer *server,
- SoupMessage *msg,
+ SoupServerMessage *msg,
const char *path,
GHashTable *query,
- SoupClientContext *client,
gpointer user_data)
{
if (!strcmp (path, "/request-timeout")) {
@@ -35,10 +34,10 @@ server_handler (SoupServer *server,
} else
server_processed_message = TRUE;
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "ok\r\n", 4);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "ok\r\n", 4);
}
static void
diff --git a/tests/sniffing-test.c b/tests/sniffing-test.c
index 98547a34..e81811b0 100644
--- a/tests/sniffing-test.c
+++ b/tests/sniffing-test.c
@@ -10,27 +10,32 @@ SoupURI *base_uri;
SoupMessageBody *chunk_data;
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
GError *error = NULL;
char *query_key;
GBytes *response = NULL;
gsize offset;
+ SoupMessageHeaders *response_headers;
+ SoupMessageBody *response_body;
gboolean empty_response = FALSE;
- if (msg->method != SOUP_METHOD_GET) {
- soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
+ if (soup_server_message_get_method (msg) != SOUP_METHOD_GET) {
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ response_headers = soup_server_message_get_response_headers (msg);
if (query) {
query_key = g_hash_table_lookup (query, "chunked");
if (query_key && g_str_equal (query_key, "yes")) {
- soup_message_headers_set_encoding (msg->response_headers,
+ soup_message_headers_set_encoding (response_headers,
SOUP_ENCODING_CHUNKED);
}
@@ -45,7 +50,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
g_assert_no_error (error);
}
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type", "text/plain");
}
@@ -56,10 +61,10 @@ server_callback (SoupServer *server, SoupMessage *msg,
g_assert_no_error (error);
g_free (base_name);
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"X-Content-Type-Options", "nosniff");
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type", "no/sniffing-allowed");
}
@@ -70,7 +75,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
g_assert_no_error (error);
g_free (base_name);
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type", "text/plain");
}
@@ -81,7 +86,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
g_assert_no_error (error);
g_free (base_name);
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type", "UNKNOWN/unknown");
}
@@ -99,7 +104,7 @@ server_callback (SoupServer *server, SoupMessage *msg,
ptr = g_strrstr (components[2], "_");
*ptr = '/';
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type", components[2]);
g_strfreev (components);
}
@@ -111,24 +116,25 @@ server_callback (SoupServer *server, SoupMessage *msg,
g_assert_no_error (error);
g_free (base_name);
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type", "text/xml");
- soup_message_headers_append (msg->response_headers,
+ soup_message_headers_append (response_headers,
"Content-Type", "text/plain");
}
+ response_body = soup_server_message_get_response_body (msg);
if (response) {
- gsize response_size = g_bytes_get_size (response);
+ gsize response_size = g_bytes_get_size (response);
for (offset = 0; offset < response_size; offset += 500) {
GBytes *chunk = g_bytes_new_from_bytes (response, offset, MIN (500, response_size - offset));
- soup_message_body_append_bytes (msg->response_body, chunk);
+ soup_message_body_append_bytes (response_body, chunk);
g_bytes_unref (chunk);
}
g_bytes_unref (response);
}
- soup_message_body_complete (msg->response_body);
+ soup_message_body_complete (response_body);
}
static gboolean
@@ -229,7 +235,9 @@ do_signals_test (gboolean should_content_sniff,
soup_message_set_uri (msg, uri);
+#if 0
soup_message_body_set_accumulate (msg->response_body, should_accumulate);
+#endif
g_object_connect (msg,
"signal::got-headers", got_headers, GINT_TO_POINTER (should_pause),
@@ -258,8 +266,10 @@ do_signals_test (gboolean should_content_sniff,
if (!should_accumulate && chunk_data)
body = soup_message_body_flatten (chunk_data);
+#if 0
else if (msg->response_body)
body = soup_message_body_flatten (msg->response_body);
+#endif
if (body) {
//g_message ("|||body (%zu): %s", g_bytes_get_size (body), (char*)g_bytes_get_data (body, NULL));
diff --git a/tests/ssl-test.c b/tests/ssl-test.c
index 1422834a..c314b2d7 100644
--- a/tests/ssl-test.c
+++ b/tests/ssl-test.c
@@ -238,16 +238,15 @@ do_tls_interaction_test (void)
static void
server_handler (SoupServer *server,
- SoupMessage *msg,
+ SoupServerMessage *msg,
const char *path,
GHashTable *query,
- SoupClientContext *client,
gpointer user_data)
{
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "ok\r\n", 4);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "ok\r\n", 4);
}
int
diff --git a/tests/streaming-test.c b/tests/streaming-test.c
index b1a10d54..a9280cb8 100644
--- a/tests/streaming-test.c
+++ b/tests/streaming-test.c
@@ -11,16 +11,20 @@ GBytes *full_response;
char *full_response_md5;
static void
-write_next_chunk (SoupMessage *msg, gpointer user_data)
+write_next_chunk (SoupServerMessage *msg,
+ gpointer user_data)
{
gsize *offset = user_data;
gsize chunk_length;
+ SoupMessageBody *response_body;
+
+ response_body = soup_server_message_get_response_body (msg);
chunk_length = MIN (RESPONSE_CHUNK_SIZE, g_bytes_get_size (full_response) - *offset);
if (chunk_length > 0) {
debug_printf (2, " writing chunk\n");
GBytes *chunk = g_bytes_new_from_bytes (full_response, *offset, chunk_length);
- soup_message_body_append_bytes (msg->response_body, chunk);
+ soup_message_body_append_bytes (response_body, chunk);
g_bytes_unref (chunk);
*offset += chunk_length;
} else {
@@ -29,44 +33,49 @@ write_next_chunk (SoupMessage *msg, gpointer user_data)
* cases, but it's harmless in the content-length
* case.
*/
- soup_message_body_complete (msg->response_body);
+ soup_message_body_complete (response_body);
}
}
static void
-free_offset (SoupMessage *msg, gpointer offset)
+free_offset (SoupServerMessage *msg,
+ gpointer offset)
{
g_free (offset);
}
static void
-server_callback (SoupServer *server, SoupMessage *msg,
- const char *path, GHashTable *query,
- SoupClientContext *context, gpointer data)
+server_callback (SoupServer *server,
+ SoupServerMessage *msg,
+ const char *path,
+ GHashTable *query,
+ gpointer data)
{
gsize *offset;
+ SoupMessageHeaders *response_headers;
+ response_headers = soup_server_message_get_response_headers (msg);
if (!strcmp (path, "/chunked")) {
- soup_message_headers_set_encoding (msg->response_headers,
+ soup_message_headers_set_encoding (response_headers,
SOUP_ENCODING_CHUNKED);
} else if (!strcmp (path, "/content-length")) {
- soup_message_headers_set_encoding (msg->response_headers,
+ soup_message_headers_set_encoding (response_headers,
SOUP_ENCODING_CONTENT_LENGTH);
- soup_message_headers_set_content_length (msg->response_headers,
+ soup_message_headers_set_content_length (response_headers,
g_bytes_get_size (full_response));
} else if (!strcmp (path, "/eof")) {
- soup_message_headers_set_encoding (msg->response_headers,
+ soup_message_headers_set_encoding (response_headers,
SOUP_ENCODING_EOF);
} else {
- soup_message_set_status (msg, SOUP_STATUS_NOT_FOUND);
+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_FOUND, NULL);
return;
}
- soup_message_set_status (msg, SOUP_STATUS_OK);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
offset = g_new0 (gsize, 1);
- g_signal_connect (msg, "wrote_headers",
+ g_signal_connect (msg, "wrote-headers",
G_CALLBACK (write_next_chunk), offset);
- g_signal_connect (msg, "wrote_chunk",
+ g_signal_connect (msg, "wrote-chunk",
G_CALLBACK (write_next_chunk), offset);
g_signal_connect (msg, "finished",
G_CALLBACK (free_offset), offset);
diff --git a/tests/timeout-test.c b/tests/timeout-test.c
index 17977434..b3325e42 100644
--- a/tests/timeout-test.c
+++ b/tests/timeout-test.c
@@ -287,16 +287,15 @@ timeout_finish_message (gpointer msg)
static void
server_handler (SoupServer *server,
- SoupMessage *msg,
+ SoupServerMessage *msg,
const char *path,
GHashTable *query,
- SoupClientContext *client,
gpointer user_data)
{
- soup_message_set_status (msg, SOUP_STATUS_OK);
- soup_message_set_response (msg, "text/plain",
- SOUP_MEMORY_STATIC,
- "ok\r\n", 4);
+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL);
+ soup_server_message_set_response (msg, "text/plain",
+ SOUP_MEMORY_STATIC,
+ "ok\r\n", 4);
if (!strcmp (path, "/slow")) {
soup_server_pause_message (server, msg);
diff --git a/tests/websocket-test.c b/tests/websocket-test.c
index 5e40cf36..c3a401ce 100644
--- a/tests/websocket-test.c
+++ b/tests/websocket-test.c
@@ -19,7 +19,7 @@
*/
#include "test-utils.h"
-
+#include "soup-server-message-private.h"
#include <zlib.h>
typedef struct {
@@ -291,9 +291,9 @@ client_connect (Test *test,
static void
got_server_connection (SoupServer *server,
- SoupWebsocketConnection *connection,
+ SoupServerMessage *msg,
const char *path,
- SoupClientContext *client,
+ SoupWebsocketConnection *connection,
gpointer user_data)
{
Test *test = user_data;
@@ -415,10 +415,12 @@ test_handshake (Test *test,
}
static void
-websocket_server_request_started (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client, gpointer user_data)
+websocket_server_request_started (SoupServer *server,
+ SoupServerMessage *msg,
+ gpointer user_data)
{
- soup_message_headers_append (msg->response_headers, "Sec-WebSocket-Extensions", "x-foo");
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
+ "Sec-WebSocket-Extensions", "x-foo");
}
static void
@@ -639,6 +641,11 @@ test_protocol_negotiate_direct (Test *test,
gconstpointer unused)
{
SoupMessage *msg;
+ SoupServerMessage *server_msg;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageHeadersIter iter;
+ const char *name, *value;
gboolean ok;
const char *protocol;
GError *error = NULL;
@@ -647,16 +654,28 @@ test_protocol_negotiate_direct (Test *test,
soup_websocket_client_prepare_handshake (msg, NULL,
(char **) negotiate_client_protocols);
- ok = soup_websocket_server_check_handshake (msg, NULL,
+ server_msg = g_object_new (SOUP_TYPE_SERVER_MESSAGE, NULL);
+ soup_server_message_set_method (server_msg, msg->method);
+ soup_server_message_set_uri (server_msg, soup_message_get_uri (msg));
+ request_headers = soup_server_message_get_request_headers (server_msg);
+ soup_message_headers_iter_init (&iter, msg->request_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (request_headers, name, value);
+ ok = soup_websocket_server_check_handshake (server_msg, NULL,
(char **) negotiate_server_protocols,
&error);
g_assert_no_error (error);
g_assert_true (ok);
- ok = soup_websocket_server_process_handshake (msg, NULL,
+ ok = soup_websocket_server_process_handshake (server_msg, NULL,
(char **) negotiate_server_protocols);
g_assert_true (ok);
+ msg->status_code = soup_server_message_get_status (server_msg, NULL);
+ response_headers = soup_server_message_get_response_headers (server_msg);
+ soup_message_headers_iter_init (&iter, response_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (msg->response_headers, name, value);
protocol = soup_message_headers_get_one (msg->response_headers, "Sec-WebSocket-Protocol");
g_assert_cmpstr (protocol, ==, negotiated_protocol);
@@ -665,6 +684,7 @@ test_protocol_negotiate_direct (Test *test,
g_assert_true (ok);
g_object_unref (msg);
+ g_object_unref (server_msg);
}
static void
@@ -689,6 +709,11 @@ test_protocol_mismatch_direct (Test *test,
gconstpointer unused)
{
SoupMessage *msg;
+ SoupServerMessage *server_msg;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageHeadersIter iter;
+ const char *name, *value;
gboolean ok;
const char *protocol;
GError *error = NULL;
@@ -697,18 +722,30 @@ test_protocol_mismatch_direct (Test *test,
soup_websocket_client_prepare_handshake (msg, NULL,
(char **) mismatch_client_protocols);
- ok = soup_websocket_server_check_handshake (msg, NULL,
+ server_msg = g_object_new (SOUP_TYPE_SERVER_MESSAGE, NULL);
+ soup_server_message_set_method (server_msg, msg->method);
+ soup_server_message_set_uri (server_msg, soup_message_get_uri (msg));
+ request_headers = soup_server_message_get_request_headers (server_msg);
+ soup_message_headers_iter_init (&iter, msg->request_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (request_headers, name, value);
+ ok = soup_websocket_server_check_handshake (server_msg, NULL,
(char **) mismatch_server_protocols,
&error);
g_assert_error (error, SOUP_WEBSOCKET_ERROR, SOUP_WEBSOCKET_ERROR_BAD_HANDSHAKE);
g_clear_error (&error);
g_assert_false (ok);
- ok = soup_websocket_server_process_handshake (msg, NULL,
+ ok = soup_websocket_server_process_handshake (server_msg, NULL,
(char **) mismatch_server_protocols);
g_assert_false (ok);
+ msg->status_code = soup_server_message_get_status (server_msg, NULL);
soup_test_assert_message_status (msg, SOUP_STATUS_BAD_REQUEST);
+ response_headers = soup_server_message_get_response_headers (server_msg);
+ soup_message_headers_iter_init (&iter, response_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (msg->response_headers, name, value);
protocol = soup_message_headers_get_one (msg->response_headers, "Sec-WebSocket-Protocol");
g_assert_cmpstr (protocol, ==, NULL);
@@ -718,6 +755,7 @@ test_protocol_mismatch_direct (Test *test,
g_assert_false (ok);
g_object_unref (msg);
+ g_object_unref (server_msg);
}
static void
@@ -738,6 +776,11 @@ test_protocol_server_any_direct (Test *test,
gconstpointer unused)
{
SoupMessage *msg;
+ SoupServerMessage *server_msg;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageHeadersIter iter;
+ const char *name, *value;
gboolean ok;
const char *protocol;
GError *error = NULL;
@@ -745,13 +788,25 @@ test_protocol_server_any_direct (Test *test,
msg = soup_message_new ("GET", "http://127.0.0.1");
soup_websocket_client_prepare_handshake (msg, NULL, (char **) all_protocols);
- ok = soup_websocket_server_check_handshake (msg, NULL, NULL, &error);
+ server_msg = g_object_new (SOUP_TYPE_SERVER_MESSAGE, NULL);
+ soup_server_message_set_method (server_msg, msg->method);
+ soup_server_message_set_uri (server_msg, soup_message_get_uri (msg));
+ request_headers = soup_server_message_get_request_headers (server_msg);
+ soup_message_headers_iter_init (&iter, msg->request_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (request_headers, name, value);
+ ok = soup_websocket_server_check_handshake (server_msg, NULL, NULL, &error);
g_assert_no_error (error);
g_assert_true (ok);
- ok = soup_websocket_server_process_handshake (msg, NULL, NULL);
+ ok = soup_websocket_server_process_handshake (server_msg, NULL, NULL);
g_assert_true (ok);
+ msg->status_code = soup_server_message_get_status (server_msg, NULL);
+ response_headers = soup_server_message_get_response_headers (server_msg);
+ soup_message_headers_iter_init (&iter, response_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (msg->response_headers, name, value);
protocol = soup_message_headers_get_one (msg->response_headers, "Sec-WebSocket-Protocol");
g_assert_cmpstr (protocol, ==, NULL);
@@ -760,6 +815,7 @@ test_protocol_server_any_direct (Test *test,
g_assert_true (ok);
g_object_unref (msg);
+ g_object_unref (server_msg);
}
static void
@@ -782,6 +838,11 @@ test_protocol_client_any_direct (Test *test,
gconstpointer unused)
{
SoupMessage *msg;
+ SoupServerMessage *server_msg;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageHeadersIter iter;
+ const char *name, *value;
gboolean ok;
const char *protocol;
GError *error = NULL;
@@ -789,13 +850,25 @@ test_protocol_client_any_direct (Test *test,
msg = soup_message_new ("GET", "http://127.0.0.1");
soup_websocket_client_prepare_handshake (msg, NULL, NULL);
- ok = soup_websocket_server_check_handshake (msg, NULL, (char **) all_protocols, &error);
+ server_msg = g_object_new (SOUP_TYPE_SERVER_MESSAGE, NULL);
+ soup_server_message_set_method (server_msg, msg->method);
+ soup_server_message_set_uri (server_msg, soup_message_get_uri (msg));
+ request_headers = soup_server_message_get_request_headers (server_msg);
+ soup_message_headers_iter_init (&iter, msg->request_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (request_headers, name, value);
+ ok = soup_websocket_server_check_handshake (server_msg, NULL, (char **) all_protocols, &error);
g_assert_no_error (error);
g_assert_true (ok);
- ok = soup_websocket_server_process_handshake (msg, NULL, (char **) all_protocols);
+ ok = soup_websocket_server_process_handshake (server_msg, NULL, (char **) all_protocols);
g_assert_true (ok);
+ msg->status_code = soup_server_message_get_status (server_msg, NULL);
+ response_headers = soup_server_message_get_response_headers (server_msg);
+ soup_message_headers_iter_init (&iter, response_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (msg->response_headers, name, value);
protocol = soup_message_headers_get_one (msg->response_headers, "Sec-WebSocket-Protocol");
g_assert_cmpstr (protocol, ==, NULL);
@@ -804,6 +877,7 @@ test_protocol_client_any_direct (Test *test,
g_assert_true (ok);
g_object_unref (msg);
+ g_object_unref (server_msg);
}
static void
@@ -1431,9 +1505,9 @@ test_server_receive_unmasked_frame (Test *test,
static void
test_client_context_got_server_connection (SoupServer *server,
- SoupWebsocketConnection *connection,
+ SoupServerMessage *msg,
const char *path,
- SoupClientContext *client,
+ SoupWebsocketConnection *connection,
gpointer user_data)
{
Test *test = user_data;
@@ -1442,7 +1516,7 @@ test_client_context_got_server_connection (SoupServer *server,
char *str;
const char *remote_ip;
- addr = soup_client_context_get_local_address (client);
+ addr = soup_server_message_get_local_address (msg);
iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
str = g_inet_address_to_string (iaddr);
if (g_inet_address_get_family (iaddr) == G_SOCKET_FAMILY_IPV4)
@@ -1451,7 +1525,7 @@ test_client_context_got_server_connection (SoupServer *server,
g_assert_cmpstr (str, ==, "::1");
g_free (str);
- addr = soup_client_context_get_remote_address (client);
+ addr = soup_server_message_get_remote_address (msg);
iaddr = g_inet_socket_address_get_address (G_INET_SOCKET_ADDRESS (addr));
str = g_inet_address_to_string (iaddr);
if (g_inet_address_get_family (iaddr) == G_SOCKET_FAMILY_IPV4)
@@ -1459,7 +1533,7 @@ test_client_context_got_server_connection (SoupServer *server,
else
g_assert_cmpstr (str, ==, "::1");
- remote_ip = soup_client_context_get_host (client);
+ remote_ip = soup_server_message_get_remote_host (msg);
g_assert_cmpstr (remote_ip, ==, str);
g_free (str);
@@ -1610,6 +1684,11 @@ test_deflate_negotiate_direct (Test *test,
for (i = 0; i < G_N_ELEMENTS (deflate_negotiate_tests); i++) {
SoupMessage *msg;
+ SoupServerMessage *server_msg;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageHeadersIter iter;
+ const char *name, *value;
gboolean result;
GList *accepted_extensions = NULL;
GError *error = NULL;
@@ -1618,7 +1697,15 @@ test_deflate_negotiate_direct (Test *test,
soup_websocket_client_prepare_handshake (msg, NULL, NULL);
soup_message_headers_append (msg->request_headers, "Sec-WebSocket-Extensions", deflate_negotiate_tests[i].client_extension);
- result = soup_websocket_server_check_handshake_with_extensions (msg, NULL, NULL,
+
+ server_msg = g_object_new (SOUP_TYPE_SERVER_MESSAGE, NULL);
+ soup_server_message_set_method (server_msg, msg->method);
+ soup_server_message_set_uri (server_msg, soup_message_get_uri (msg));
+ request_headers = soup_server_message_get_request_headers (server_msg);
+ soup_message_headers_iter_init (&iter, msg->request_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (request_headers, name, value);
+ result = soup_websocket_server_check_handshake_with_extensions (server_msg, NULL, NULL,
deflate_negotiate_tests[i].server_supports_extensions ?
supported_extensions : NULL,
&error);
@@ -1630,11 +1717,17 @@ test_deflate_negotiate_direct (Test *test,
g_clear_error (&error);
}
- result = soup_websocket_server_process_handshake_with_extensions (msg, NULL, NULL,
+ result = soup_websocket_server_process_handshake_with_extensions (server_msg, NULL, NULL,
deflate_negotiate_tests[i].server_supports_extensions ?
supported_extensions : NULL,
&accepted_extensions);
g_assert (result == deflate_negotiate_tests[i].expected_check_result);
+
+ msg->status_code = soup_server_message_get_status (server_msg, NULL);
+ response_headers = soup_server_message_get_response_headers (server_msg);
+ soup_message_headers_iter_init (&iter, response_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (msg->response_headers, name, value);
if (deflate_negotiate_tests[i].expected_accepted_extension) {
const char *extension;
@@ -1668,6 +1761,7 @@ test_deflate_negotiate_direct (Test *test,
}
g_object_unref (msg);
+ g_object_unref (server_msg);
}
g_ptr_array_unref (supported_extensions);
@@ -1678,6 +1772,11 @@ test_deflate_disabled_in_message_direct (Test *test,
gconstpointer unused)
{
SoupMessage *msg;
+ SoupServerMessage *server_msg;
+ SoupMessageHeaders *request_headers;
+ SoupMessageHeaders *response_headers;
+ SoupMessageHeadersIter iter;
+ const char *name, *value;
GPtrArray *supported_extensions;
GList *accepted_extensions = NULL;
GError *error = NULL;
@@ -1690,11 +1789,24 @@ test_deflate_disabled_in_message_direct (Test *test,
soup_websocket_client_prepare_handshake_with_extensions (msg, NULL, NULL, supported_extensions);
g_assert_cmpstr (soup_message_headers_get_one (msg->request_headers, "Sec-WebSocket-Extensions"), ==, NULL);
- g_assert_true (soup_websocket_server_check_handshake_with_extensions (msg, NULL, NULL, supported_extensions, &error));
+ server_msg = g_object_new (SOUP_TYPE_SERVER_MESSAGE, NULL);
+ soup_server_message_set_method (server_msg, msg->method);
+ soup_server_message_set_uri (server_msg, soup_message_get_uri (msg));
+ request_headers = soup_server_message_get_request_headers (server_msg);
+ soup_message_headers_iter_init (&iter, msg->request_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (request_headers, name, value);
+
+ g_assert_true (soup_websocket_server_check_handshake_with_extensions (server_msg, NULL, NULL, supported_extensions, &error));
g_assert_no_error (error);
- g_assert_true (soup_websocket_server_process_handshake_with_extensions (msg, NULL, NULL, supported_extensions, &accepted_extensions));
+ g_assert_true (soup_websocket_server_process_handshake_with_extensions (server_msg, NULL, NULL, supported_extensions, &accepted_extensions));
g_assert_null (accepted_extensions);
+ msg->status_code = soup_server_message_get_status (server_msg, NULL);
+ response_headers = soup_server_message_get_response_headers (server_msg);
+ soup_message_headers_iter_init (&iter, response_headers);
+ while (soup_message_headers_iter_next (&iter, &name, &value))
+ soup_message_headers_append (msg->response_headers, name, value);
g_assert_cmpstr (soup_message_headers_get_one (msg->response_headers, "Sec-WebSocket-Extensions"), ==, NULL);
g_assert_true (soup_websocket_client_verify_handshake_with_extensions (msg, supported_extensions, &accepted_extensions, &error));
@@ -1702,6 +1814,7 @@ test_deflate_disabled_in_message_direct (Test *test,
g_assert_null (accepted_extensions);
g_object_unref (msg);
+ g_object_unref (server_msg);
g_ptr_array_unref (supported_extensions);
}
@@ -1828,10 +1941,12 @@ test_cookies_in_request (Test *test,
}
static void
-cookies_test_websocket_server_request_started (SoupServer *server, SoupMessage *msg,
- SoupClientContext *client, gpointer user_data)
+cookies_test_websocket_server_request_started (SoupServer *server,
+ SoupServerMessage *msg,
+ gpointer user_data)
{
- soup_message_headers_append (msg->response_headers, "Set-Cookie", "foo=bar; Path=/");
+ soup_message_headers_append (soup_server_message_get_response_headers (msg),
+ "Set-Cookie", "foo=bar; Path=/");
}
static void