1From 3dc630ae5b9dc6cda1ba318de2cd654aaba7b4a2 Mon Sep 17 00:00:00 2001 2From: Carlos Garcia Campos <cgarcia@igalia.com> 3Date: Tue, 8 Jun 2021 17:44:04 +0200 4Subject: [PATCH 2/2] Port to libsoup3 5 6Upstream-Status: Submitted [https://gitlab.gnome.org/GNOME/librest/-/merge_requests/6] 7--- 8 configure.ac | 39 ++++- 9 rest-extras.pc.in | 2 +- 10 rest-extras/youtube-proxy.c | 110 +++++++++++--- 11 rest.pc.in | 2 +- 12 rest/rest-private.h | 22 ++- 13 rest/rest-proxy-auth.c | 16 ++ 14 rest/rest-proxy-call.c | 296 +++++++++++++++++++++++++++++------- 15 rest/rest-proxy.c | 209 ++++++++++++++++++++++--- 16 tests/custom-serialize.c | 18 +++ 17 tests/proxy-continuous.c | 37 ++++- 18 tests/proxy.c | 63 +++++++- 19 tests/threaded.c | 17 +++ 20 12 files changed, 719 insertions(+), 112 deletions(-) 21 22diff --git a/configure.ac b/configure.ac 23index d586e69..75c02fe 100644 24--- a/configure.ac 25+++ b/configure.ac 26@@ -20,12 +20,6 @@ AM_INIT_AUTOMAKE([1.11 foreign -Wno-portability no-define dist-xz]) 27 28 AM_SILENT_RULES([yes]) 29 30-API_MAJOR=1 31-API_MINOR=0 32-AC_SUBST([API_VERSION],[$API_MAJOR.$API_MINOR]) 33-AC_SUBST([API_VERSION_AM],[$API_MAJOR\_$API_MINOR]) 34-AC_DEFINE_UNQUOTED(API_VERSION, [$API_VERSION], [API version]) 35- 36 AC_CANONICAL_HOST 37 38 AC_PROG_CC 39@@ -41,7 +35,6 @@ LT_PREREQ([2.2.6]) 40 LT_INIT([disable-static]) 41 42 PKG_CHECK_MODULES(GLIB, glib-2.0 >= 2.67.4) 43-PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.42) 44 PKG_CHECK_MODULES(XML, libxml-2.0) 45 PKG_CHECK_MODULES(GTHREAD, gthread-2.0) 46 47@@ -58,6 +51,37 @@ AC_PATH_PROG([GLIB_MKENUMS],[glib-mkenums]) 48 localedir=${datadir}/locale 49 AC_SUBST(localedir) 50 51+AC_MSG_CHECKING([for libsoup version to use]) 52+AC_ARG_WITH(soup, 53+ [AC_HELP_STRING([--soup=2|3], 54+ [version of libsoup library to use (default: 2)])], 55+ [case "$withval" in 56+ 2|3) ;; 57+ *) AC_MSG_ERROR([invalid argument "$withval" for --with-soup]) ;; 58+ esac], 59+ [with_soup=2]) 60+AC_MSG_RESULT([$with_soup]) 61+ 62+API_MAJOR=1 63+ 64+if test "$with_soup" = "2"; then 65+ PKG_CHECK_MODULES(SOUP, libsoup-2.4 >= 2.42) 66+ SOUP_API_VERSION=2.4 67+ API_MINOR=0 68+ AC_DEFINE([WITH_SOUP_2],[1],[Define if libsoup version used is 2]) 69+else 70+ PKG_CHECK_MODULES(SOUP, libsoup-3.0 >= 2.99.8) 71+ SOUP_API_VERSION=3.0 72+ API_MINOR=1 73+fi 74+ 75+AM_CONDITIONAL([WITH_SOUP_2],[test "$with_soup" = "2"]) 76+AC_SUBST(SOUP_API_VERSION) 77+ 78+AC_SUBST([API_VERSION],[$API_MAJOR.$API_MINOR]) 79+AC_SUBST([API_VERSION_AM],[$API_MAJOR\_$API_MINOR]) 80+AC_DEFINE_UNQUOTED(API_VERSION, [$API_VERSION], [API version]) 81+ 82 dnl === Coverage report ======================================================= 83 AC_PATH_PROG([GCOV], [lcov], [enable_gcov=no]) 84 85@@ -130,6 +154,7 @@ echo " LibRest $VERSION" 86 echo " ================" 87 echo "" 88 echo " prefix: ${prefix}" 89+echo " libsoup version: ${with_soup}" 90 echo "" 91 echo " Documentation: ${enable_gtk_doc}" 92 echo " Introspection data: ${enable_introspection}" 93diff --git a/rest-extras.pc.in b/rest-extras.pc.in 94index 39f21bf..3723d6d 100644 95--- a/rest-extras.pc.in 96+++ b/rest-extras.pc.in 97@@ -9,4 +9,4 @@ Description: RESTful web api query library 98 Version: @VERSION@ 99 Libs: -L${libdir} -lrest-extras-${apiversion} 100 Cflags: -I${includedir}/rest-${apiversion} 101-Requires: glib-2.0 libsoup-2.4 libxml-2.0 102+Requires: glib-2.0 libsoup-@SOUP_API_VERSION@ libxml-2.0 103diff --git a/rest-extras/youtube-proxy.c b/rest-extras/youtube-proxy.c 104index be0cf08..cd598f4 100644 105--- a/rest-extras/youtube-proxy.c 106+++ b/rest-extras/youtube-proxy.c 107@@ -246,6 +246,9 @@ typedef struct { 108 GObject *weak_object; 109 gpointer user_data; 110 gsize uploaded; 111+#ifndef WITH_SOUP_2 112+ GCancellable *cancellable; 113+#endif 114 } YoutubeProxyUploadClosure; 115 116 static void 117@@ -255,7 +258,11 @@ _upload_async_weak_notify_cb (gpointer *data, 118 YoutubeProxyUploadClosure *closure = 119 (YoutubeProxyUploadClosure *) data; 120 121+#ifdef WITH_SOUP_2 122 _rest_proxy_cancel_message (REST_PROXY (closure->proxy), closure->message); 123+#else 124+ g_cancellable_cancel (closure->cancellable); 125+#endif 126 } 127 128 static void 129@@ -267,6 +274,9 @@ _upload_async_closure_free (YoutubeProxyUploadClosure *closure) 130 closure); 131 132 g_object_unref (closure->proxy); 133+#ifndef WITH_SOUP_2 134+ g_object_unref (closure->cancellable); 135+#endif 136 137 g_slice_free (YoutubeProxyUploadClosure, closure); 138 } 139@@ -286,6 +296,9 @@ _upload_async_closure_new (YoutubeProxy *self, 140 closure->message = message; 141 closure->weak_object = weak_object; 142 closure->user_data = user_data; 143+#ifndef WITH_SOUP_2 144+ closure->cancellable = g_cancellable_new (); 145+#endif 146 147 if (weak_object != NULL) 148 g_object_weak_ref (weak_object, 149@@ -295,41 +308,67 @@ _upload_async_closure_new (YoutubeProxy *self, 150 } 151 152 static void 153-_upload_completed_cb (SoupSession *session, 154- SoupMessage *message, 155+_upload_completed_cb (SoupMessage *message, 156+ GBytes *payload, 157+ GError *error, 158 gpointer user_data) 159 { 160 YoutubeProxyUploadClosure *closure = 161 (YoutubeProxyUploadClosure *) user_data; 162- GError *error = NULL; 163+ gsize length; 164+ gconstpointer data; 165+ guint status_code; 166+ const char *reason_phrase; 167 168 if (closure->callback == NULL) 169 return; 170 171- if (message->status_code < 200 || message->status_code >= 300) 172- error = g_error_new_literal (REST_PROXY_ERROR, 173- message->status_code, 174- message->reason_phrase); 175- 176- closure->callback (closure->proxy, message->response_body->data, 177- message->request_body->length, 178- message->request_body->length, 179+#ifdef WITH_SOUP_2 180+ status_code = message->status_code; 181+ reason_phrase = message->reason_phrase; 182+#else 183+ status_code = soup_message_get_status (message); 184+ reason_phrase = soup_message_get_reason_phrase (message); 185+#endif 186+ 187+ if (status_code < 200 || status_code >= 300) 188+ { 189+ g_clear_error (&error); 190+ error = g_error_new_literal (REST_PROXY_ERROR, 191+ status_code, 192+ reason_phrase); 193+ } 194+ 195+ data = g_bytes_get_data (payload, &length); 196+ closure->callback (closure->proxy, data, length, length, 197 error, closure->weak_object, closure->user_data); 198+ g_bytes_unref (payload); 199 200 _upload_async_closure_free (closure); 201 } 202 203 static void 204 _message_wrote_data_cb (SoupMessage *msg, 205+#ifdef WITH_SOUP_2 206 SoupBuffer *chunk, 207+#else 208+ gsize chunk_size, 209+#endif 210 YoutubeProxyUploadClosure *closure) 211 { 212- closure->uploaded = closure->uploaded + chunk->length; 213+#ifdef WITH_SOUP_2 214+ gsize chunk_size = chunk->length; 215+ goffset content_length = msg->request_body->length; 216+#else 217+ goffset content_length = soup_message_headers_get_content_length (soup_message_get_request_headers (msg)); 218+#endif 219+ 220+ closure->uploaded = closure->uploaded + chunk_size; 221 222- if (closure->uploaded < msg->request_body->length) 223+ if (closure->uploaded < content_length) 224 closure->callback (closure->proxy, 225 NULL, 226- msg->request_body->length, 227+ content_length, 228 closure->uploaded, 229 NULL, 230 closure->weak_object, 231@@ -364,7 +403,12 @@ youtube_proxy_upload_async (YoutubeProxy *self, 232 SoupMultipart *mp; 233 SoupMessage *message; 234 SoupMessageHeaders *part_headers; 235+ SoupMessageHeaders *request_headers; 236+#ifdef WITH_SOUP_2 237 SoupBuffer *sb; 238+#else 239+ GBytes *sb; 240+#endif 241 gchar *content_type; 242 gchar *atom_xml; 243 GMappedFile *map; 244@@ -380,10 +424,17 @@ youtube_proxy_upload_async (YoutubeProxy *self, 245 246 atom_xml = _construct_upload_atom_xml (fields, incomplete); 247 248+#ifdef WITH_SOUP_2 249 sb = soup_buffer_new_with_owner (atom_xml, 250 strlen(atom_xml), 251 atom_xml, 252 (GDestroyNotify) g_free); 253+#else 254+ sb = g_bytes_new_with_free_func (atom_xml, 255+ strlen (atom_xml), 256+ (GDestroyNotify) g_free, 257+ atom_xml); 258+#endif 259 260 part_headers = soup_message_headers_new (SOUP_MESSAGE_HEADERS_MULTIPART); 261 262@@ -393,7 +444,11 @@ youtube_proxy_upload_async (YoutubeProxy *self, 263 264 soup_multipart_append_part (mp, part_headers, sb); 265 266+#ifdef WITH_SOUP_2 267 soup_buffer_free (sb); 268+#else 269+ g_bytes_unref (sb); 270+#endif 271 272 content_type = g_content_type_guess ( 273 filename, 274@@ -401,24 +456,37 @@ youtube_proxy_upload_async (YoutubeProxy *self, 275 g_mapped_file_get_length (map), 276 NULL); 277 278+#ifdef WITH_SOUP_2 279 sb = soup_buffer_new_with_owner (g_mapped_file_get_contents (map), 280 g_mapped_file_get_length (map), 281 map, 282 (GDestroyNotify) g_mapped_file_unref); 283+#else 284+ sb = g_bytes_new_with_free_func (g_mapped_file_get_contents (map), 285+ g_mapped_file_get_length (map), 286+ (GDestroyNotify) g_mapped_file_unref, 287+ map); 288+#endif 289 290 soup_message_headers_replace (part_headers, "Content-Type", content_type); 291 292 soup_multipart_append_part (mp, part_headers, sb); 293 294+#ifdef WITH_SOUP_2 295 soup_buffer_free (sb); 296- 297 soup_message_headers_free (part_headers); 298- 299 message = soup_form_request_new_from_multipart (UPLOAD_URL, mp); 300+ request_headers = message->request_headers; 301+#else 302+ g_bytes_unref (sb); 303+ soup_message_headers_unref (part_headers); 304+ message = soup_message_new_from_multipart (UPLOAD_URL, mp); 305+ request_headers = soup_message_get_request_headers (message); 306+#endif 307 308 soup_multipart_free (mp); 309 310- _set_upload_headers (self, message->request_headers, filename); 311+ _set_upload_headers (self, request_headers, filename); 312 313 closure = _upload_async_closure_new (self, callback, message, weak_object, 314 user_data); 315@@ -429,7 +497,13 @@ youtube_proxy_upload_async (YoutubeProxy *self, 316 closure); 317 318 319- _rest_proxy_queue_message (REST_PROXY (self), message, _upload_completed_cb, 320+ _rest_proxy_queue_message (REST_PROXY (self), message, 321+#ifdef WITH_SOUP_2 322+ NULL, 323+#else 324+ closure->cancellable, 325+#endif 326+ _upload_completed_cb, 327 closure); 328 329 return TRUE; 330diff --git a/rest.pc.in b/rest.pc.in 331index 94c384b..e6bae3e 100644 332--- a/rest.pc.in 333+++ b/rest.pc.in 334@@ -9,4 +9,4 @@ Description: RESTful web api query library 335 Version: @VERSION@ 336 Libs: -L${libdir} -lrest-${apiversion} 337 Cflags: -I${includedir}/rest-${apiversion} 338-Requires: glib-2.0 libsoup-2.4 libxml-2.0 339+Requires: glib-2.0 libsoup-@SOUP_API_VERSION@ libxml-2.0 340diff --git a/rest/rest-private.h b/rest/rest-private.h 341index 9e91fa0..6e71322 100644 342--- a/rest/rest-private.h 343+++ b/rest/rest-private.h 344@@ -31,6 +31,11 @@ 345 346 G_BEGIN_DECLS 347 348+typedef void (*RestMessageFinishedCallback) (SoupMessage *msg, 349+ GBytes *body, 350+ GError *error, 351+ gpointer user_data); 352+ 353 typedef enum 354 { 355 REST_DEBUG_XML_PARSER = 1 << 0, 356@@ -53,12 +58,23 @@ gboolean _rest_proxy_get_binding_required (RestProxy *proxy); 357 const gchar *_rest_proxy_get_bound_url (RestProxy *proxy); 358 void _rest_proxy_queue_message (RestProxy *proxy, 359 SoupMessage *message, 360- SoupSessionCallback callback, 361+ GCancellable *cancellable, 362+ RestMessageFinishedCallback callback, 363 gpointer user_data); 364 void _rest_proxy_cancel_message (RestProxy *proxy, 365 SoupMessage *message); 366-guint _rest_proxy_send_message (RestProxy *proxy, 367- SoupMessage *message); 368+GBytes *_rest_proxy_send_message (RestProxy *proxy, 369+ SoupMessage *message, 370+ GCancellable *cancellable, 371+ GError **error); 372+void _rest_proxy_send_message_async (RestProxy *proxy, 373+ SoupMessage *message, 374+ GCancellable *cancellable, 375+ GAsyncReadyCallback callback, 376+ gpointer user_data); 377+GInputStream *_rest_proxy_send_message_finish (RestProxy *proxy, 378+ GAsyncResult *result, 379+ GError **error); 380 381 RestXmlNode *_rest_xml_node_new (void); 382 void _rest_xml_node_reverse_children_siblings (RestXmlNode *node); 383diff --git a/rest/rest-proxy-auth.c b/rest/rest-proxy-auth.c 384index b96e443..0b2ec9f 100644 385--- a/rest/rest-proxy-auth.c 386+++ b/rest/rest-proxy-auth.c 387@@ -29,7 +29,9 @@ 388 struct _RestProxyAuthPrivate { 389 /* used to hold state during async authentication */ 390 RestProxy *proxy; 391+#ifdef WITH_SOUP_2 392 SoupSession *session; 393+#endif 394 SoupMessage *message; 395 SoupAuth *auth; 396 gboolean paused; 397@@ -43,7 +45,9 @@ rest_proxy_auth_dispose (GObject *object) 398 RestProxyAuthPrivate *priv = ((RestProxyAuth*)object)->priv; 399 400 g_clear_object (&priv->proxy); 401+#ifdef WITH_SOUP_2 402 g_clear_object (&priv->session); 403+#endif 404 g_clear_object (&priv->message); 405 g_clear_object (&priv->auth); 406 407@@ -73,13 +77,17 @@ rest_proxy_auth_new (RestProxy *proxy, 408 RestProxyAuth *rest_auth; 409 410 g_return_val_if_fail (REST_IS_PROXY (proxy), NULL); 411+#ifdef WITH_SOUP_2 412 g_return_val_if_fail (SOUP_IS_SESSION (session), NULL); 413+#endif 414 g_return_val_if_fail (SOUP_IS_MESSAGE (message), NULL); 415 g_return_val_if_fail (SOUP_IS_AUTH (soup_auth), NULL); 416 417 rest_auth = REST_PROXY_AUTH (g_object_new (REST_TYPE_PROXY_AUTH, NULL)); 418 rest_auth->priv->proxy = g_object_ref(proxy); 419+#ifdef WITH_SOUP_2 420 rest_auth->priv->session = g_object_ref(session); 421+#endif 422 rest_auth->priv->message = g_object_ref(message); 423 rest_auth->priv->auth = g_object_ref(soup_auth); 424 425@@ -104,7 +112,9 @@ rest_proxy_auth_pause (RestProxyAuth *auth) 426 return; 427 428 auth->priv->paused = TRUE; 429+#ifdef WITH_SOUP_2 430 soup_session_pause_message (auth->priv->session, auth->priv->message); 431+#endif 432 } 433 434 /** 435@@ -128,7 +138,9 @@ rest_proxy_auth_unpause (RestProxyAuth *auth) 436 soup_auth_authenticate (auth->priv->auth, username, password); 437 g_free (username); 438 g_free (password); 439+#ifdef WITH_SOUP_2 440 soup_session_unpause_message (auth->priv->session, auth->priv->message); 441+#endif 442 auth->priv->paused = FALSE; 443 } 444 445@@ -146,7 +158,11 @@ rest_proxy_auth_cancel (RestProxyAuth *auth) 446 { 447 g_return_if_fail (REST_IS_PROXY_AUTH (auth)); 448 449+#ifdef WITH_SOUP_2 450 soup_session_cancel_message (auth->priv->session, auth->priv->message, SOUP_STATUS_CANCELLED); 451+#else 452+ soup_auth_cancel (auth->priv->auth); 453+#endif 454 } 455 456 G_GNUC_INTERNAL gboolean rest_proxy_auth_is_paused (RestProxyAuth *auth) 457diff --git a/rest/rest-proxy-call.c b/rest/rest-proxy-call.c 458index 2ab722f..62b00da 100644 459--- a/rest/rest-proxy-call.c 460+++ b/rest/rest-proxy-call.c 461@@ -20,12 +20,14 @@ 462 * 463 */ 464 465+#include <config.h> 466 #include <rest/rest-proxy.h> 467 #include <rest/rest-proxy-call.h> 468 #include <rest/rest-params.h> 469 #include <libsoup/soup.h> 470 471 #include "rest-private.h" 472+#include "rest-proxy-auth-private.h" 473 #include "rest-proxy-call-private.h" 474 475 476@@ -38,12 +40,15 @@ struct _RestProxyCallAsyncClosure { 477 }; 478 typedef struct _RestProxyCallAsyncClosure RestProxyCallAsyncClosure; 479 480+#define READ_BUFFER_SIZE 8192 481+ 482 struct _RestProxyCallContinuousClosure { 483 RestProxyCall *call; 484 RestProxyCallContinuousCallback callback; 485 GObject *weak_object; 486 gpointer userdata; 487 SoupMessage *message; 488+ guchar buffer[READ_BUFFER_SIZE]; 489 }; 490 typedef struct _RestProxyCallContinuousClosure RestProxyCallContinuousClosure; 491 492@@ -70,8 +75,7 @@ struct _RestProxyCallPrivate { 493 gchar *url; 494 495 GHashTable *response_headers; 496- goffset length; 497- gchar *payload; 498+ GBytes *payload; 499 guint status_code; 500 gchar *status_message; 501 502@@ -160,7 +164,7 @@ rest_proxy_call_finalize (GObject *object) 503 g_free (priv->method); 504 g_free (priv->function); 505 506- g_free (priv->payload); 507+ g_clear_pointer (&priv->payload, g_bytes_unref); 508 g_free (priv->status_message); 509 510 g_free (priv->url); 511@@ -546,14 +550,23 @@ _populate_headers_hash_table (const gchar *name, 512 g_hash_table_insert (headers, g_strdup (name), g_strdup (value)); 513 } 514 515+#ifdef WITH_SOUP_2 516 /* I apologise for this macro, but it saves typing ;-) */ 517 #define error_helper(x) g_set_error_literal(error, REST_PROXY_ERROR, x, message->reason_phrase) 518+#endif 519 static gboolean 520 _handle_error_from_message (SoupMessage *message, GError **error) 521 { 522- if (message->status_code < 100) 523+ guint status_code; 524+ const char *reason_phrase; 525+ 526+#ifdef WITH_SOUP_2 527+ status_code = message->status_code; 528+ 529+ if (status_code < 100) 530 { 531- switch (message->status_code) 532+ g_clear_error (error); 533+ switch (status_code) 534 { 535 case SOUP_STATUS_CANCELLED: 536 error_helper (REST_PROXY_ERROR_CANCELLED); 537@@ -580,61 +593,84 @@ _handle_error_from_message (SoupMessage *message, GError **error) 538 } 539 return FALSE; 540 } 541+ reason_phrase = message->reason_phrase; 542+#else 543+ status_code = soup_message_get_status (message); 544+ reason_phrase = soup_message_get_reason_phrase (message); 545+#endif 546 547- if (message->status_code >= 200 && message->status_code < 300) 548+ if (status_code >= 200 && status_code < 300) 549 { 550 return TRUE; 551 } 552 553+ if (*error != NULL) 554+ return FALSE; 555+ 556 /* If we are here we must be in some kind of HTTP error, lets try */ 557 g_set_error_literal (error, 558 REST_PROXY_ERROR, 559- message->status_code, 560- message->reason_phrase); 561+ status_code, 562+ reason_phrase); 563 return FALSE; 564 } 565 566 static gboolean 567-finish_call (RestProxyCall *call, SoupMessage *message, GError **error) 568+finish_call (RestProxyCall *call, SoupMessage *message, GBytes *payload, GError **error) 569 { 570 RestProxyCallPrivate *priv = GET_PRIVATE (call); 571+ SoupMessageHeaders *response_headers; 572 573 g_assert (call); 574 g_assert (message); 575+ g_assert (payload); 576+ 577+#ifdef WITH_SOUP_2 578+ response_headers = message->response_headers; 579+#else 580+ response_headers = soup_message_get_response_headers (message); 581+#endif 582 583 /* Convert the soup headers in to hash */ 584 /* FIXME: Eeek..are you allowed duplicate headers? ... */ 585 g_hash_table_remove_all (priv->response_headers); 586- soup_message_headers_foreach (message->response_headers, 587+ soup_message_headers_foreach (response_headers, 588 (SoupMessageHeadersForeachFunc)_populate_headers_hash_table, 589 priv->response_headers); 590 591- priv->payload = g_memdup (message->response_body->data, 592- message->response_body->length + 1); 593- priv->length = message->response_body->length; 594+ priv->payload = payload; 595 596+#ifdef WITH_SOUP_2 597 priv->status_code = message->status_code; 598 priv->status_message = g_strdup (message->reason_phrase); 599+#else 600+ priv->status_code = soup_message_get_status (message); 601+ priv->status_message = g_strdup (soup_message_get_reason_phrase (message)); 602+#endif 603 604 return _handle_error_from_message (message, error); 605 } 606 607 static void 608-_continuous_call_message_completed_cb (SoupSession *session, 609- SoupMessage *message, 610- gpointer userdata) 611+_continuous_call_message_completed (SoupMessage *message, 612+ GError *error, 613+ gpointer userdata) 614 { 615 RestProxyCallContinuousClosure *closure; 616 RestProxyCall *call; 617 RestProxyCallPrivate *priv; 618- GError *error = NULL; 619 620 closure = (RestProxyCallContinuousClosure *)userdata; 621 call = closure->call; 622 priv = GET_PRIVATE (call); 623 624+#ifdef WITH_SOUP_2 625 priv->status_code = message->status_code; 626 priv->status_message = g_strdup (message->reason_phrase); 627+#else 628+ priv->status_code = soup_message_get_status (message); 629+ priv->status_message = g_strdup (soup_message_get_reason_phrase (message)); 630+#endif 631 632 _handle_error_from_message (message, &error); 633 634@@ -657,6 +693,7 @@ _continuous_call_message_completed_cb (SoupSession *session, 635 636 priv->cur_call_closure = NULL; 637 g_object_unref (closure->call); 638+ g_object_unref (message); 639 g_slice_free (RestProxyCallContinuousClosure, closure); 640 } 641 642@@ -715,6 +752,49 @@ set_url (RestProxyCall *call) 643 return TRUE; 644 } 645 646+#ifndef WITH_SOUP_2 647+static gboolean 648+authenticate (RestProxyCall *call, 649+ SoupAuth *soup_auth, 650+ gboolean retrying, 651+ SoupMessage *message) 652+{ 653+ RestProxyCallPrivate *priv = GET_PRIVATE (call); 654+ RestProxyAuth *rest_auth; 655+ gboolean try_auth; 656+ 657+ rest_auth = rest_proxy_auth_new (priv->proxy, NULL, message, soup_auth); 658+ g_signal_emit_by_name (priv->proxy, "authenticate", rest_auth, retrying, &try_auth); 659+ if (try_auth && !rest_proxy_auth_is_paused (rest_auth)) { 660+ char *username, *password; 661+ 662+ g_object_get (priv->proxy, "username", &username, "password", &password, NULL); 663+ soup_auth_authenticate (soup_auth, username, password); 664+ g_free (username); 665+ g_free (password); 666+ } 667+ g_object_unref (rest_auth); 668+ 669+ return try_auth; 670+} 671+ 672+static gboolean 673+accept_certificate (RestProxyCall *call, 674+ GTlsCertificate *tls_certificate, 675+ GTlsCertificateFlags *tls_errors, 676+ SoupMessage *message) 677+{ 678+ RestProxyCallPrivate *priv = GET_PRIVATE (call); 679+ gboolean ssl_strict; 680+ 681+ if (tls_errors == 0) 682+ return TRUE; 683+ 684+ g_object_get (priv->proxy, "ssl-strict", &ssl_strict, NULL); 685+ return !ssl_strict; 686+} 687+#endif 688+ 689 static SoupMessage * 690 prepare_message (RestProxyCall *call, GError **error_out) 691 { 692@@ -722,6 +802,7 @@ prepare_message (RestProxyCall *call, GError **error_out) 693 RestProxyCallClass *call_class; 694 const gchar *user_agent; 695 SoupMessage *message; 696+ SoupMessageHeaders *request_headers; 697 GError *error = NULL; 698 699 call_class = REST_PROXY_CALL_GET_CLASS (call); 700@@ -748,6 +829,9 @@ prepare_message (RestProxyCall *call, GError **error_out) 701 gchar *content; 702 gchar *content_type; 703 gsize content_len; 704+#ifndef WITH_SOUP_2 705+ GBytes *body; 706+#endif 707 708 if (!call_class->serialize_params (call, &content_type, 709 &content, &content_len, &error)) 710@@ -780,8 +864,14 @@ prepare_message (RestProxyCall *call, GError **error_out) 711 "Could not parse URI"); 712 return NULL; 713 } 714+#ifdef WITH_SOUP_2 715 soup_message_set_request (message, content_type, 716 SOUP_MEMORY_TAKE, content, content_len); 717+#else 718+ body = g_bytes_new_take (content, content_len); 719+ soup_message_set_request_body_from_bytes (message, content_type, body); 720+ g_bytes_unref (body); 721+#endif 722 723 g_free (content_type); 724 } else if (rest_params_are_strings (priv->params)) { 725@@ -798,9 +888,15 @@ prepare_message (RestProxyCall *call, GError **error_out) 726 727 hash = rest_params_as_string_hash_table (priv->params); 728 729+#ifdef WITH_SOUP_2 730 message = soup_form_request_new_from_hash (priv->method, 731 priv->url, 732 hash); 733+#else 734+ message = soup_message_new_from_encoded_form (priv->method, 735+ priv->url, 736+ soup_form_encode_hash (hash)); 737+#endif 738 739 g_hash_table_unref (hash); 740 741@@ -827,19 +923,28 @@ prepare_message (RestProxyCall *call, GError **error_out) 742 if (rest_param_is_string (param)) { 743 soup_multipart_append_form_string (mp, name, rest_param_get_content (param)); 744 } else { 745- SoupBuffer *sb; 746- 747- sb = soup_buffer_new_with_owner (rest_param_get_content (param), 748- rest_param_get_content_length (param), 749- rest_param_ref (param), 750- (GDestroyNotify)rest_param_unref); 751+#ifdef WITH_SOUP_2 752+ SoupBuffer *sb = soup_buffer_new_with_owner (rest_param_get_content (param), 753+ rest_param_get_content_length (param), 754+ rest_param_ref (param), 755+ (GDestroyNotify)rest_param_unref); 756+#else 757+ GBytes *sb = g_bytes_new_with_free_func (rest_param_get_content (param), 758+ rest_param_get_content_length (param), 759+ (GDestroyNotify)rest_param_unref, 760+ rest_param_ref (param)); 761+#endif 762 763 soup_multipart_append_form_file (mp, name, 764 rest_param_get_file_name (param), 765 rest_param_get_content_type (param), 766 sb); 767 768+#ifdef WITH_SOUP_2 769 soup_buffer_free (sb); 770+#else 771+ g_bytes_unref (sb); 772+#endif 773 } 774 } 775 776@@ -853,19 +958,36 @@ prepare_message (RestProxyCall *call, GError **error_out) 777 return NULL; 778 } 779 780+#ifdef WITH_SOUP_2 781 message = soup_form_request_new_from_multipart (priv->url, mp); 782+#else 783+ message = soup_message_new_from_multipart (priv->url, mp); 784+#endif 785 786 soup_multipart_free (mp); 787 } 788 789+#ifdef WITH_SOUP_2 790+ request_headers = message->request_headers; 791+#else 792+ request_headers = soup_message_get_request_headers (message); 793+ g_signal_connect_swapped (message, "authenticate", 794+ G_CALLBACK (authenticate), 795+ call); 796+ g_signal_connect_swapped (message, "accept-certificate", 797+ G_CALLBACK (accept_certificate), 798+ call); 799+#endif 800+ 801+ 802 /* Set the user agent, if one was set in the proxy */ 803 user_agent = rest_proxy_get_user_agent (priv->proxy); 804 if (user_agent) { 805- soup_message_headers_append (message->request_headers, "User-Agent", user_agent); 806+ soup_message_headers_append (request_headers, "User-Agent", user_agent); 807 } 808 809 /* Set the headers */ 810- g_hash_table_foreach (priv->headers, set_header, message->request_headers); 811+ g_hash_table_foreach (priv->headers, set_header, request_headers); 812 813 return message; 814 } 815@@ -878,17 +1000,17 @@ _call_message_call_cancelled_cb (GCancellable *cancellable, 816 } 817 818 static void 819-_call_message_call_completed_cb (SoupSession *session, 820- SoupMessage *message, 821+_call_message_call_completed_cb (SoupMessage *message, 822+ GBytes *payload, 823+ GError *error, 824 gpointer user_data) 825 { 826 GTask *task = user_data; 827 RestProxyCall *call; 828- GError *error = NULL; 829 830 call = REST_PROXY_CALL (g_task_get_source_object (task)); 831 832- finish_call (call, message, &error); 833+ finish_call (call, message, payload, &error); 834 835 if (error != NULL) 836 g_task_return_error (task, error); 837@@ -938,6 +1060,7 @@ rest_proxy_call_invoke_async (RestProxyCall *call, 838 839 _rest_proxy_queue_message (priv->proxy, 840 message, 841+ priv->cancellable, 842 _call_message_call_completed_cb, 843 task); 844 } 845@@ -962,16 +1085,55 @@ rest_proxy_call_invoke_finish (RestProxyCall *call, 846 } 847 848 static void 849-_continuous_call_message_got_chunk_cb (SoupMessage *msg, 850- SoupBuffer *chunk, 851- RestProxyCallContinuousClosure *closure) 852+_continuous_call_read_cb (GObject *source, 853+ GAsyncResult *result, 854+ gpointer user_data) 855 { 856+ GInputStream *stream = G_INPUT_STREAM (source); 857+ RestProxyCallContinuousClosure *closure = user_data; 858+ RestProxyCallPrivate *priv = GET_PRIVATE (closure->call); 859+ gssize bytes_read; 860+ GError *error = NULL; 861+ 862+ bytes_read = g_input_stream_read_finish (stream, result, &error); 863+ if (bytes_read <= 0) 864+ { 865+ _continuous_call_message_completed (closure->message, error, user_data); 866+ return; 867+ } 868+ 869 closure->callback (closure->call, 870- chunk->data, 871- chunk->length, 872+ (gconstpointer)closure->buffer, 873+ bytes_read, 874 NULL, 875 closure->weak_object, 876 closure->userdata); 877+ 878+ g_input_stream_read_async (stream, closure->buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 879+ priv->cancellable, _continuous_call_read_cb, closure); 880+} 881+ 882+static void 883+_continuous_call_message_sent_cb (GObject *source, 884+ GAsyncResult *result, 885+ gpointer user_data) 886+{ 887+ RestProxy *proxy = REST_PROXY (source); 888+ RestProxyCallContinuousClosure *closure = user_data; 889+ RestProxyCallPrivate *priv = GET_PRIVATE (closure->call); 890+ GInputStream *stream; 891+ GError *error = NULL; 892+ 893+ stream = _rest_proxy_send_message_finish (proxy, result, &error); 894+ if (!stream) 895+ { 896+ _continuous_call_message_completed (closure->message, error, user_data); 897+ return; 898+ } 899+ 900+ g_input_stream_read_async (stream, closure->buffer, READ_BUFFER_SIZE, G_PRIORITY_DEFAULT, 901+ priv->cancellable, _continuous_call_read_cb, closure); 902+ g_object_unref (stream); 903 } 904 905 906@@ -1021,9 +1183,6 @@ rest_proxy_call_continuous (RestProxyCall *call, 907 if (message == NULL) 908 return FALSE; 909 910- /* Must turn off accumulation */ 911- soup_message_body_set_accumulate (message->response_body, FALSE); 912- 913 closure = g_slice_new0 (RestProxyCallContinuousClosure); 914 closure->call = g_object_ref (call); 915 closure->callback = callback; 916@@ -1041,33 +1200,29 @@ rest_proxy_call_continuous (RestProxyCall *call, 917 closure); 918 } 919 920- g_signal_connect (message, 921- "got-chunk", 922- (GCallback)_continuous_call_message_got_chunk_cb, 923- closure); 924- 925- _rest_proxy_queue_message (priv->proxy, 926- message, 927- _continuous_call_message_completed_cb, 928- closure); 929+ _rest_proxy_send_message_async (priv->proxy, 930+ message, 931+ priv->cancellable, 932+ _continuous_call_message_sent_cb, 933+ closure); 934 return TRUE; 935 } 936 937 static void 938-_upload_call_message_completed_cb (SoupSession *session, 939- SoupMessage *message, 940+_upload_call_message_completed_cb (SoupMessage *message, 941+ GBytes *payload, 942+ GError *error, 943 gpointer user_data) 944 { 945 RestProxyCall *call; 946 RestProxyCallPrivate *priv; 947- GError *error = NULL; 948 RestProxyCallUploadClosure *closure; 949 950 closure = (RestProxyCallUploadClosure *) user_data; 951 call = closure->call; 952 priv = GET_PRIVATE (call); 953 954- finish_call (call, message, &error); 955+ finish_call (call, message, payload, &error); 956 957 closure->callback (closure->call, 958 closure->uploaded, 959@@ -1093,14 +1248,25 @@ _upload_call_message_completed_cb (SoupSession *session, 960 961 static void 962 _upload_call_message_wrote_data_cb (SoupMessage *msg, 963+#ifdef WITH_SOUP_2 964 SoupBuffer *chunk, 965+#else 966+ gsize chunk_size, 967+#endif 968 RestProxyCallUploadClosure *closure) 969 { 970- closure->uploaded = closure->uploaded + chunk->length; 971+#ifdef WITH_SOUP_2 972+ gsize chunk_size = chunk->length; 973+ goffset content_length = msg->request_body->length; 974+#else 975+ goffset content_length = soup_message_headers_get_content_length (soup_message_get_request_headers (msg)); 976+#endif 977 978- if (closure->uploaded < msg->request_body->length) 979+ closure->uploaded = closure->uploaded + chunk_size; 980+ 981+ if (closure->uploaded < content_length) 982 closure->callback (closure->call, 983- msg->request_body->length, 984+ content_length, 985 closure->uploaded, 986 NULL, 987 closure->weak_object, 988@@ -1178,6 +1344,7 @@ rest_proxy_call_upload (RestProxyCall *call, 989 990 _rest_proxy_queue_message (priv->proxy, 991 message, 992+ priv->cancellable, 993 _upload_call_message_completed_cb, 994 closure); 995 return TRUE; 996@@ -1206,6 +1373,10 @@ rest_proxy_call_cancel (RestProxyCall *call) 997 if (priv->cancellable) 998 { 999 g_signal_handler_disconnect (priv->cancellable, priv->cancel_sig); 1000+#ifndef WITH_SOUP_2 1001+ if (!g_cancellable_is_cancelled (priv->cancellable)) 1002+ g_cancellable_cancel (priv->cancellable); 1003+#endif 1004 g_clear_object (&priv->cancellable); 1005 } 1006 1007@@ -1240,6 +1411,7 @@ rest_proxy_call_sync (RestProxyCall *call, 1008 RestProxyCallPrivate *priv = GET_PRIVATE (call); 1009 SoupMessage *message; 1010 gboolean ret; 1011+ GBytes *payload; 1012 1013 g_return_val_if_fail (REST_IS_PROXY_CALL (call), FALSE); 1014 1015@@ -1247,9 +1419,9 @@ rest_proxy_call_sync (RestProxyCall *call, 1016 if (!message) 1017 return FALSE; 1018 1019- _rest_proxy_send_message (priv->proxy, message); 1020+ payload = _rest_proxy_send_message (priv->proxy, message, priv->cancellable, error_out); 1021 1022- ret = finish_call (call, message, error_out); 1023+ ret = finish_call (call, message, payload, error_out); 1024 1025 g_object_unref (message); 1026 1027@@ -1314,9 +1486,16 @@ rest_proxy_call_get_response_headers (RestProxyCall *call) 1028 goffset 1029 rest_proxy_call_get_payload_length (RestProxyCall *call) 1030 { 1031+ GBytes *payload; 1032+ 1033 g_return_val_if_fail (REST_IS_PROXY_CALL (call), 0); 1034 1035- return GET_PRIVATE (call)->length; 1036+ payload = GET_PRIVATE (call)->payload; 1037+#ifdef WITH_SOUP_2 1038+ return payload ? g_bytes_get_size (payload) - 1 : 0; 1039+#else 1040+ return payload ? g_bytes_get_size (payload) : 0; 1041+#endif 1042 } 1043 1044 /** 1045@@ -1331,9 +1510,12 @@ rest_proxy_call_get_payload_length (RestProxyCall *call) 1046 const gchar * 1047 rest_proxy_call_get_payload (RestProxyCall *call) 1048 { 1049+ GBytes *payload; 1050+ 1051 g_return_val_if_fail (REST_IS_PROXY_CALL (call), NULL); 1052 1053- return GET_PRIVATE (call)->payload; 1054+ payload = GET_PRIVATE (call)->payload; 1055+ return payload ? g_bytes_get_data (payload, NULL) : NULL; 1056 } 1057 1058 /** 1059diff --git a/rest/rest-proxy.c b/rest/rest-proxy.c 1060index 80972a3..171f6cb 100644 1061--- a/rest/rest-proxy.c 1062+++ b/rest/rest-proxy.c 1063@@ -45,6 +45,9 @@ struct _RestProxyPrivate { 1064 SoupSession *session; 1065 gboolean disable_cookies; 1066 char *ssl_ca_file; 1067+#ifndef WITH_SOUP_2 1068+ gboolean ssl_strict; 1069+#endif 1070 }; 1071 1072 1073@@ -116,11 +119,15 @@ rest_proxy_get_property (GObject *object, 1074 g_value_set_string (value, priv->password); 1075 break; 1076 case PROP_SSL_STRICT: { 1077+#ifdef WITH_SOUP_2 1078 gboolean ssl_strict; 1079 g_object_get (G_OBJECT(priv->session), 1080 "ssl-strict", &ssl_strict, 1081 NULL); 1082 g_value_set_boolean (value, ssl_strict); 1083+#else 1084+ g_value_set_boolean (value, priv->ssl_strict); 1085+#endif 1086 break; 1087 } 1088 case PROP_SSL_CA_FILE: 1089@@ -172,9 +179,13 @@ rest_proxy_set_property (GObject *object, 1090 priv->password = g_value_dup_string (value); 1091 break; 1092 case PROP_SSL_STRICT: 1093+#ifdef WITH_SOUP_2 1094 g_object_set (G_OBJECT(priv->session), 1095 "ssl-strict", g_value_get_boolean (value), 1096 NULL); 1097+#else 1098+ priv->ssl_strict = g_value_get_boolean (value); 1099+#endif 1100 break; 1101 case PROP_SSL_CA_FILE: 1102 g_free(priv->ssl_ca_file); 1103@@ -207,6 +218,7 @@ default_authenticate_cb (RestProxy *self, 1104 return !retrying; 1105 } 1106 1107+#ifdef WITH_SOUP_2 1108 static void 1109 authenticate (RestProxy *self, 1110 SoupMessage *msg, 1111@@ -224,6 +236,7 @@ authenticate (RestProxy *self, 1112 soup_auth_authenticate (soup_auth, priv->username, priv->password); 1113 g_object_unref (G_OBJECT (rest_auth)); 1114 } 1115+#endif 1116 1117 static void 1118 rest_proxy_constructed (GObject *object) 1119@@ -238,14 +251,20 @@ rest_proxy_constructed (GObject *object) 1120 } 1121 1122 if (REST_DEBUG_ENABLED(PROXY)) { 1123+#ifdef WITH_SOUP_2 1124 SoupSessionFeature *logger = (SoupSessionFeature*)soup_logger_new (SOUP_LOGGER_LOG_BODY, 0); 1125+#else 1126+ SoupSessionFeature *logger = (SoupSessionFeature*)soup_logger_new (SOUP_LOGGER_LOG_HEADERS); 1127+#endif 1128 soup_session_add_feature (priv->session, logger); 1129 g_object_unref (logger); 1130 } 1131 1132+#ifdef WITH_SOUP_2 1133 /* session lifetime is same as self, no need to keep signalid */ 1134 g_signal_connect_swapped (priv->session, "authenticate", 1135 G_CALLBACK(authenticate), object); 1136+#endif 1137 } 1138 1139 static void 1140@@ -391,23 +410,62 @@ rest_proxy_class_init (RestProxyClass *klass) 1141 proxy_class->authenticate = default_authenticate_cb; 1142 } 1143 1144+static gboolean 1145+transform_ssl_ca_file_to_tls_database (GBinding *binding, 1146+ const GValue *from_value, 1147+ GValue *to_value, 1148+ gpointer user_data) 1149+{ 1150+ g_value_take_object (to_value, 1151+ g_tls_file_database_new (g_value_get_string (from_value), NULL)); 1152+ return TRUE; 1153+} 1154+ 1155+static gboolean 1156+transform_tls_database_to_ssl_ca_file (GBinding *binding, 1157+ const GValue *from_value, 1158+ GValue *to_value, 1159+ gpointer user_data) 1160+{ 1161+ GTlsDatabase *tls_database; 1162+ char *path = NULL; 1163+ 1164+ tls_database = g_value_get_object (from_value); 1165+ if (tls_database) 1166+ g_object_get (tls_database, "anchors", &path, NULL); 1167+ g_value_take_string (to_value, path); 1168+ return TRUE; 1169+} 1170+ 1171 static void 1172 rest_proxy_init (RestProxy *self) 1173 { 1174 RestProxyPrivate *priv = GET_PRIVATE (self); 1175+ GTlsDatabase *tls_database; 1176+ 1177+#ifndef WITH_SOUP_2 1178+ priv->ssl_strict = TRUE; 1179+#endif 1180 1181 priv->session = soup_session_new (); 1182 1183 #ifdef REST_SYSTEM_CA_FILE 1184 /* with ssl-strict (defaults TRUE) setting ssl-ca-file forces all 1185 * certificates to be trusted */ 1186- g_object_set (priv->session, 1187- "ssl-ca-file", REST_SYSTEM_CA_FILE, 1188- NULL); 1189+ tls_database = g_tls_file_database_new (REST_SYSTEM_CA_FILE, NULL); 1190+ if (tls_database) { 1191+ g_object_set (priv->session, 1192+ "tls-database", tls_database, 1193+ NULL); 1194+ g_object_unref (tls_database); 1195+ } 1196 #endif 1197- g_object_bind_property (self, "ssl-ca-file", 1198- priv->session, "ssl-ca-file", 1199- G_BINDING_BIDIRECTIONAL); 1200+ g_object_bind_property_full (self, "ssl-ca-file", 1201+ priv->session, "tls-database", 1202+ G_BINDING_BIDIRECTIONAL, 1203+ transform_ssl_ca_file_to_tls_database, 1204+ transform_tls_database_to_ssl_ca_file, 1205+ NULL, NULL); 1206 } 1207 1208 /** 1209@@ -689,27 +747,127 @@ rest_proxy_simple_run (RestProxy *proxy, 1210 return ret; 1211 } 1212 1213+typedef struct { 1214+ RestMessageFinishedCallback callback; 1215+ gpointer user_data; 1216+} RestMessageQueueData; 1217+ 1218+#ifdef WITH_SOUP_2 1219+static void 1220+message_finished_cb (SoupSession *session, 1221+ SoupMessage *message, 1222+ gpointer user_data) 1223+{ 1224+ RestMessageQueueData *data = user_data; 1225+ GBytes *body; 1226+ GError *error = NULL; 1227+ 1228+ body = g_bytes_new (message->response_body->data, 1229+ message->response_body->length + 1); 1230+ data->callback (message, body, error, data->user_data); 1231+ g_free (data); 1232+} 1233+#else 1234+static void 1235+message_send_and_read_ready_cb (GObject *source, 1236+ GAsyncResult *result, 1237+ gpointer user_data) 1238+{ 1239+ SoupSession *session = SOUP_SESSION (source); 1240+ RestMessageQueueData *data = user_data; 1241+ GBytes *body; 1242+ GError *error = NULL; 1243+ 1244+ body = soup_session_send_and_read_finish (session, result, &error); 1245+ data->callback (soup_session_get_async_result_message (session, result), body, error, data->user_data); 1246+ g_free (data); 1247+} 1248+#endif 1249+ 1250 void 1251-_rest_proxy_queue_message (RestProxy *proxy, 1252- SoupMessage *message, 1253- SoupSessionCallback callback, 1254- gpointer user_data) 1255+_rest_proxy_queue_message (RestProxy *proxy, 1256+ SoupMessage *message, 1257+ GCancellable *cancellable, 1258+ RestMessageFinishedCallback callback, 1259+ gpointer user_data) 1260 { 1261 RestProxyPrivate *priv = GET_PRIVATE (proxy); 1262+ RestMessageQueueData *data; 1263 1264 g_return_if_fail (REST_IS_PROXY (proxy)); 1265 g_return_if_fail (SOUP_IS_MESSAGE (message)); 1266 1267+ data = g_new0 (RestMessageQueueData, 1); 1268+ data->callback = callback; 1269+ data->user_data = user_data; 1270+ 1271+#ifdef WITH_SOUP_2 1272 soup_session_queue_message (priv->session, 1273 message, 1274- callback, 1275- user_data); 1276+ message_finished_cb, 1277+ data); 1278+#else 1279+ soup_session_send_and_read_async (priv->session, 1280+ message, 1281+ G_PRIORITY_DEFAULT, 1282+ cancellable, 1283+ message_send_and_read_ready_cb, 1284+ data); 1285+#endif 1286+} 1287+ 1288+static void 1289+message_send_ready_cb (GObject *source, 1290+ GAsyncResult *result, 1291+ gpointer user_data) 1292+{ 1293+ SoupSession *session = SOUP_SESSION (source); 1294+ GTask *task = user_data; 1295+ GInputStream *stream; 1296+ GError *error = NULL; 1297+ 1298+ stream = soup_session_send_finish (session, result, &error); 1299+ if (stream) 1300+ g_task_return_pointer (task, stream, g_object_unref); 1301+ else 1302+ g_task_return_error (task, error); 1303+ g_object_unref (task); 1304+} 1305+ 1306+void 1307+_rest_proxy_send_message_async (RestProxy *proxy, 1308+ SoupMessage *message, 1309+ GCancellable *cancellable, 1310+ GAsyncReadyCallback callback, 1311+ gpointer user_data) 1312+{ 1313+ RestProxyPrivate *priv = GET_PRIVATE (proxy); 1314+ GTask *task; 1315+ 1316+ task = g_task_new (proxy, cancellable, callback, user_data); 1317+ soup_session_send_async (priv->session, 1318+ message, 1319+#ifndef WITH_SOUP_2 1320+ G_PRIORITY_DEFAULT, 1321+#endif 1322+ cancellable, 1323+ message_send_ready_cb, 1324+ task); 1325+} 1326+ 1327+GInputStream * 1328+_rest_proxy_send_message_finish (RestProxy *proxy, 1329+ GAsyncResult *result, 1330+ GError **error) 1331+{ 1332+ return g_task_propagate_pointer (G_TASK (result), error); 1333 } 1334 1335 void 1336 _rest_proxy_cancel_message (RestProxy *proxy, 1337 SoupMessage *message) 1338 { 1339+#ifdef WITH_SOUP_2 1340 RestProxyPrivate *priv = GET_PRIVATE (proxy); 1341 1342 g_return_if_fail (REST_IS_PROXY (proxy)); 1343@@ -718,16 +876,31 @@ _rest_proxy_cancel_message (RestProxy *proxy, 1344 soup_session_cancel_message (priv->session, 1345 message, 1346 SOUP_STATUS_CANCELLED); 1347+#endif 1348 } 1349 1350-guint 1351-_rest_proxy_send_message (RestProxy *proxy, 1352- SoupMessage *message) 1353+GBytes * 1354+_rest_proxy_send_message (RestProxy *proxy, 1355+ SoupMessage *message, 1356+ GCancellable *cancellable, 1357+ GError **error) 1358 { 1359 RestProxyPrivate *priv = GET_PRIVATE (proxy); 1360+ GBytes *body; 1361 1362- g_return_val_if_fail (REST_IS_PROXY (proxy), 0); 1363- g_return_val_if_fail (SOUP_IS_MESSAGE (message), 0); 1364+ g_return_val_if_fail (REST_IS_PROXY (proxy), NULL); 1365+ g_return_val_if_fail (SOUP_IS_MESSAGE (message), NULL); 1366+ 1367+#ifdef WITH_SOUP_2 1368+ soup_session_send_message (priv->session, message); 1369+ body = g_bytes_new (message->response_body->data, 1370+ message->response_body->length + 1); 1371+#else 1372+ body = soup_session_send_and_read (priv->session, 1373+ message, 1374+ cancellable, 1375+ error); 1376+#endif 1377 1378- return soup_session_send_message (priv->session, message); 1379+ return body; 1380 } 1381diff --git a/tests/custom-serialize.c b/tests/custom-serialize.c 1382index c3fde93..01b3a56 100644 1383--- a/tests/custom-serialize.c 1384+++ b/tests/custom-serialize.c 1385@@ -88,22 +88,40 @@ custom_proxy_call_init (CustomProxyCall *self) 1386 } 1387 1388 static void 1389+#ifdef WITH_SOUP_2 1390 server_callback (SoupServer *server, SoupMessage *msg, 1391 const char *path, GHashTable *query, 1392 SoupClientContext *client, gpointer user_data) 1393+#else 1394+server_callback (SoupServer *server, SoupServerMessage *msg, 1395+ const char *path, GHashTable *query, gpointer user_data) 1396+#endif 1397 { 1398 if (g_str_equal (path, "/ping")) { 1399 const char *content_type = NULL; 1400+#ifdef WITH_SOUP_2 1401 SoupMessageHeaders *headers = msg->request_headers; 1402 SoupMessageBody *body = msg->request_body; 1403+#else 1404+ SoupMessageHeaders *headers = soup_server_message_get_request_headers (msg); 1405+ SoupMessageBody *body = soup_server_message_get_request_body (msg); 1406+#endif 1407 content_type = soup_message_headers_get_content_type (headers, NULL); 1408 g_assert_cmpstr (content_type, ==, "application/json"); 1409 1410 g_assert_cmpstr (body->data, ==, "{}"); 1411 1412+#ifdef WITH_SOUP_2 1413 soup_message_set_status (msg, SOUP_STATUS_OK); 1414+#else 1415+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1416+#endif 1417 } else { 1418+#ifdef WITH_SOUP_2 1419 soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED); 1420+#else 1421+ soup_server_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED, NULL); 1422+#endif 1423 } 1424 } 1425 1426diff --git a/tests/proxy-continuous.c b/tests/proxy-continuous.c 1427index 8f4b7a8..7967bbd 100644 1428--- a/tests/proxy-continuous.c 1429+++ b/tests/proxy-continuous.c 1430@@ -39,9 +39,15 @@ static SoupServer *server; 1431 static gboolean 1432 send_chunks (gpointer user_data) 1433 { 1434- SoupMessage *msg = SOUP_MESSAGE (user_data); 1435 guint i; 1436 guint8 data[SIZE_CHUNK]; 1437+#ifdef WITH_SOUP_2 1438+ SoupMessage *msg = SOUP_MESSAGE (user_data); 1439+ SoupMessageBody *response_body = msg->response_body; 1440+#else 1441+ SoupServerMessage *msg = SOUP_SERVER_MESSAGE (user_data); 1442+ SoupMessageBody *response_body = soup_server_message_get_response_body (msg); 1443+#endif 1444 1445 for (i = 0; i < SIZE_CHUNK; i++) 1446 { 1447@@ -49,12 +55,12 @@ send_chunks (gpointer user_data) 1448 server_count++; 1449 } 1450 1451- soup_message_body_append (msg->response_body, SOUP_MEMORY_COPY, data, SIZE_CHUNK); 1452+ soup_message_body_append (response_body, SOUP_MEMORY_COPY, data, SIZE_CHUNK); 1453 soup_server_unpause_message (server, msg); 1454 1455 if (server_count == NUM_CHUNKS * SIZE_CHUNK) 1456 { 1457- soup_message_body_complete (msg->response_body); 1458+ soup_message_body_complete (response_body); 1459 return FALSE; 1460 } else { 1461 return TRUE; 1462@@ -62,13 +68,28 @@ send_chunks (gpointer user_data) 1463 } 1464 1465 static void 1466+#ifdef WITH_SOUP_2 1467 server_callback (SoupServer *server, SoupMessage *msg, 1468 const char *path, GHashTable *query, 1469 SoupClientContext *client, gpointer user_data) 1470+#else 1471+server_callback (SoupServer *server, SoupServerMessage *msg, 1472+ const char *path, GHashTable *query, gpointer user_data) 1473+#endif 1474 { 1475+#ifdef WITH_SOUP_2 1476+ SoupMessageHeaders *response_headers = msg->response_headers; 1477+#else 1478+ SoupMessageHeaders *response_headers = soup_server_message_get_response_headers (msg); 1479+#endif 1480+ 1481 g_assert_cmpstr (path, ==, "/stream"); 1482+#ifdef WITH_SOUP_2 1483 soup_message_set_status (msg, SOUP_STATUS_OK); 1484- soup_message_headers_set_encoding (msg->response_headers, 1485+#else 1486+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1487+#endif 1488+ soup_message_headers_set_encoding (response_headers, 1489 SOUP_ENCODING_CHUNKED); 1490 soup_server_pause_message (server, msg); 1491 1492@@ -142,13 +163,21 @@ continuous () 1493 uris = soup_server_get_uris (server); 1494 g_assert (g_slist_length (uris) > 0); 1495 1496+#ifdef WITH_SOUP_2 1497 url = soup_uri_to_string (uris->data, FALSE); 1498+#else 1499+ url = g_uri_to_string (uris->data); 1500+#endif 1501 1502 loop = g_main_loop_new (NULL, FALSE); 1503 1504 proxy = rest_proxy_new (url, FALSE); 1505 stream_test (proxy); 1506+#ifdef WITH_SOUP_2 1507 g_slist_free_full (uris, (GDestroyNotify)soup_uri_free); 1508+#else 1509+ g_slist_free_full (uris, (GDestroyNotify)g_uri_unref); 1510+#endif 1511 1512 g_main_loop_run (loop); 1513 g_free (url); 1514diff --git a/tests/proxy.c b/tests/proxy.c 1515index 89a9325..652c600 100644 1516--- a/tests/proxy.c 1517+++ b/tests/proxy.c 1518@@ -49,20 +49,35 @@ SoupServer *server; 1519 GMainLoop *server_loop; 1520 1521 static void 1522+#ifdef WITH_SOUP_2 1523 server_callback (SoupServer *server, SoupMessage *msg, 1524 const char *path, GHashTable *query, 1525 SoupClientContext *client, gpointer user_data) 1526+#else 1527+server_callback (SoupServer *server, SoupServerMessage *msg, 1528+ const char *path, GHashTable *query, gpointer user_data) 1529+#endif 1530 { 1531 if (g_str_equal (path, "/ping")) { 1532+#ifdef WITH_SOUP_2 1533 soup_message_set_status (msg, SOUP_STATUS_OK); 1534+#else 1535+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1536+#endif 1537 } 1538 else if (g_str_equal (path, "/echo")) { 1539 const char *value; 1540 1541 value = g_hash_table_lookup (query, "value"); 1542+#ifdef WITH_SOUP_2 1543 soup_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, 1544 value, strlen (value)); 1545 soup_message_set_status (msg, SOUP_STATUS_OK); 1546+#else 1547+ soup_server_message_set_response (msg, "text/plain", SOUP_MEMORY_COPY, 1548+ value, strlen (value)); 1549+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1550+#endif 1551 } 1552 else if (g_str_equal (path, "/reverse")) { 1553 char *value; 1554@@ -70,9 +85,15 @@ server_callback (SoupServer *server, SoupMessage *msg, 1555 value = g_strdup (g_hash_table_lookup (query, "value")); 1556 g_strreverse (value); 1557 1558+#ifdef WITH_SOUP_2 1559 soup_message_set_response (msg, "text/plain", SOUP_MEMORY_TAKE, 1560 value, strlen (value)); 1561 soup_message_set_status (msg, SOUP_STATUS_OK); 1562+#else 1563+ soup_server_message_set_response (msg, "text/plain", SOUP_MEMORY_TAKE, 1564+ value, strlen (value)); 1565+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1566+#endif 1567 } 1568 else if (g_str_equal (path, "/status")) { 1569 const char *value; 1570@@ -81,25 +102,61 @@ server_callback (SoupServer *server, SoupMessage *msg, 1571 value = g_hash_table_lookup (query, "status"); 1572 if (value) { 1573 status = atoi (value); 1574+#ifdef WITH_SOUP_2 1575 soup_message_set_status (msg, status ?: SOUP_STATUS_INTERNAL_SERVER_ERROR); 1576+#else 1577+ soup_server_message_set_status (msg, status ?: SOUP_STATUS_INTERNAL_SERVER_ERROR, NULL); 1578+#endif 1579 } else { 1580+#ifdef WITH_SOUP_2 1581 soup_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR); 1582+#else 1583+ soup_server_message_set_status (msg, SOUP_STATUS_INTERNAL_SERVER_ERROR, NULL); 1584+#endif 1585 } 1586 } 1587 else if (g_str_equal (path, "/useragent/none")) { 1588- if (soup_message_headers_get (msg->request_headers, "User-Agent") == NULL) { 1589+#ifdef WITH_SOUP_2 1590+ SoupMessageHeaders *request_headers = msg->request_headers; 1591+#else 1592+ SoupMessageHeaders *request_headers = soup_server_message_get_request_headers (msg); 1593+#endif 1594+ 1595+ if (soup_message_headers_get (request_headers, "User-Agent") == NULL) { 1596+#ifdef WITH_SOUP_2 1597 soup_message_set_status (msg, SOUP_STATUS_OK); 1598+#else 1599+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1600+#endif 1601 } else { 1602+#ifdef WITH_SOUP_2 1603 soup_message_set_status (msg, SOUP_STATUS_EXPECTATION_FAILED); 1604+#else 1605+ soup_server_message_set_status (msg, SOUP_STATUS_EXPECTATION_FAILED, NULL); 1606+#endif 1607 } 1608 } 1609 else if (g_str_equal (path, "/useragent/testsuite")) { 1610+#ifdef WITH_SOUP_2 1611+ SoupMessageHeaders *request_headers = msg->request_headers; 1612+#else 1613+ SoupMessageHeaders *request_headers = soup_server_message_get_request_headers (msg); 1614+#endif 1615 const char *value; 1616- value = soup_message_headers_get (msg->request_headers, "User-Agent"); 1617+ value = soup_message_headers_get (request_headers, "User-Agent"); 1618 if (g_strcmp0 (value, "TestSuite-1.0") == 0) { 1619+#ifdef WITH_SOUP_2 1620 soup_message_set_status (msg, SOUP_STATUS_OK); 1621+#else 1622+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1623+#endif 1624 } else { 1625+#ifdef WITH_SOUP_2 1626 soup_message_set_status (msg, SOUP_STATUS_EXPECTATION_FAILED); 1627+#else 1628+ soup_server_message_set_status (msg, SOUP_STATUS_EXPECTATION_FAILED, NULL); 1629+#endif 1630+ 1631 } 1632 } 1633 } 1634@@ -325,7 +382,7 @@ main (int argc, char **argv) 1635 char *url; 1636 RestProxy *proxy; 1637 1638- server = soup_server_new ("", NULL); 1639+ server = soup_server_new (NULL); 1640 g_thread_new ("Server Thread", server_thread_func, NULL); 1641 1642 url = g_strdup_printf ("http://127.0.0.1:%d/", PORT); 1643diff --git a/tests/threaded.c b/tests/threaded.c 1644index a251900..411361c 100644 1645--- a/tests/threaded.c 1646+++ b/tests/threaded.c 1647@@ -36,13 +36,22 @@ GMainLoop *main_loop; 1648 SoupServer *server; 1649 1650 static void 1651+#ifdef WITH_SOUP_2 1652 server_callback (SoupServer *server, SoupMessage *msg, 1653 const char *path, GHashTable *query, 1654 SoupClientContext *client, gpointer user_data) 1655+#else 1656+server_callback (SoupServer *server, SoupServerMessage *msg, 1657+ const char *path, GHashTable *query, gpointer user_data) 1658+#endif 1659 { 1660 g_assert_cmpstr (path, ==, "/ping"); 1661 1662+#ifdef WITH_SOUP_2 1663 soup_message_set_status (msg, SOUP_STATUS_OK); 1664+#else 1665+ soup_server_message_set_status (msg, SOUP_STATUS_OK, NULL); 1666+#endif 1667 g_atomic_int_add (&threads_done, 1); 1668 1669 if (threads_done == N_THREADS) { 1670@@ -96,7 +105,11 @@ static void ping () 1671 uris = soup_server_get_uris (server); 1672 g_assert (g_slist_length (uris) > 0); 1673 1674+#ifdef WITH_SOUP_2 1675 url = soup_uri_to_string (uris->data, FALSE); 1676+#else 1677+ url = g_uri_to_string (uris->data); 1678+#endif 1679 1680 main_loop = g_main_loop_new (NULL, TRUE); 1681 1682@@ -109,7 +122,11 @@ static void ping () 1683 g_main_loop_run (main_loop); 1684 1685 g_free (url); 1686+#ifdef WITH_SOUP_2 1687 g_slist_free_full (uris, (GDestroyNotify)soup_uri_free); 1688+#else 1689+ g_slist_free_full (uris, (GDestroyNotify)g_uri_unref); 1690+#endif 1691 g_object_unref (server); 1692 g_main_loop_unref (main_loop); 1693 } 1694-- 16952.33.1 1696 1697