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