1 /*
2  * librest - RESTful web services access
3  * Copyright (c) 2009 Intel Corporation.
4  *
5  * Authors: Rob Bradford <rob@linux.intel.com>
6  *          Ross Burton <ross@linux.intel.com>
7  *
8  * This program is free software; you can redistribute it and/or modify it
9  * under the terms and conditions of the GNU Lesser General Public License,
10  * version 2.1, as published by the Free Software Foundation.
11  *
12  * This program is distributed in the hope it will be useful, but WITHOUT ANY
13  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
14  * FOR A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public License
18  * along with this program; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  */
22 
23 #include <config.h>
24 
25 #include <string.h>
26 #include <stdlib.h>
27 #include <libsoup/soup.h>
28 #include <rest/rest-proxy.h>
29 
30 static volatile int errors = 0;
31 static const gboolean verbose = FALSE;
32 
33 #define REST_TYPE_CUSTOM_PROXY_CALL custom_proxy_call_get_type()
34 
35 #define REST_CUSTOM_PROXY_CALL(obj) \
36   (G_TYPE_CHECK_INSTANCE_CAST ((obj), REST_TYPE_CUSTOM_PROXY_CALL, CustomProxyCall))
37 
38 #define REST_CUSTOM_PROXY_CALL_CLASS(klass) \
39   (G_TYPE_CHECK_CLASS_CAST ((klass), REST_TYPE_CUSTOM_PROXY_CALL, CustomProxyCallClass))
40 
41 #define REST_IS_CUSTOM_PROXY_CALL(obj) \
42   (G_TYPE_CHECK_INSTANCE_TYPE ((obj), REST_TYPE_CUSTOM_PROXY_CALL))
43 
44 #define REST_IS_CUSTOM_PROXY_CALL_CLASS(klass) \
45   (G_TYPE_CHECK_CLASS_TYPE ((klass), REST_TYPE_CUSTOM_PROXY_CALL))
46 
47 #define REST_CUSTOM_PROXY_CALL_GET_CLASS(obj) \
48   (G_TYPE_INSTANCE_GET_CLASS ((obj), REST_TYPE_CUSTOM_PROXY_CALL, CustomProxyCallClass))
49 
50 typedef struct {
51   RestProxyCall parent;
52 } CustomProxyCall;
53 
54 typedef struct {
55   RestProxyCallClass parent_class;
56 } CustomProxyCallClass;
57 
58 GType custom_proxy_call_get_type (void);
59 
G_DEFINE_TYPE(CustomProxyCall,custom_proxy_call,REST_TYPE_PROXY_CALL)60 G_DEFINE_TYPE (CustomProxyCall, custom_proxy_call, REST_TYPE_PROXY_CALL)
61 
62 static gboolean
63 custom_proxy_call_serialize (RestProxyCall *self,
64                              gchar **content_type,
65                              gchar **content, gsize *content_len,
66                              GError **error)
67 {
68   g_return_val_if_fail (REST_IS_CUSTOM_PROXY_CALL (self), FALSE);
69 
70   *content_type = g_strdup ("application/json");
71   *content = g_strdup ("{}");
72   *content_len = strlen (*content);
73   rest_proxy_call_set_function (self, "ping");
74 
75   return TRUE;
76 }
77 
78 static void
custom_proxy_call_class_init(CustomProxyCallClass * klass)79 custom_proxy_call_class_init (CustomProxyCallClass *klass)
80 {
81   RestProxyCallClass *parent_klass = (RestProxyCallClass*) klass;
82 
83   parent_klass->serialize_params = custom_proxy_call_serialize;
84 }
85 
86 static void
custom_proxy_call_init(CustomProxyCall * self)87 custom_proxy_call_init (CustomProxyCall *self)
88 {
89 }
90 
91 static void
server_callback(SoupServer * server,SoupMessage * msg,const char * path,GHashTable * query,SoupClientContext * client,gpointer user_data)92 server_callback (SoupServer *server, SoupMessage *msg,
93                  const char *path, GHashTable *query,
94                  SoupClientContext *client, gpointer user_data)
95 {
96   if (g_str_equal (path, "/ping")) {
97     const char *content_type = NULL;
98     SoupMessageHeaders *headers = msg->request_headers;
99     SoupMessageBody *body = msg->request_body;
100     content_type = soup_message_headers_get_content_type (headers, NULL);
101     g_assert_cmpstr (content_type, ==, "application/json");
102 
103     g_assert_cmpstr (body->data, ==, "{}");
104 
105     soup_message_set_status (msg, SOUP_STATUS_OK);
106   } else {
107     soup_message_set_status (msg, SOUP_STATUS_NOT_IMPLEMENTED);
108   }
109 }
110 
111 int
main(int argc,char ** argv)112 main (int argc, char **argv)
113 {
114   SoupServer *server;
115   RestProxy *proxy;
116   RestProxyCall *call;
117   char *url;
118   GError *error = NULL;
119 
120 #if !GLIB_CHECK_VERSION (2, 36, 0)
121   g_type_init ();
122 #endif
123 
124   server = soup_server_new (NULL);
125   soup_server_add_handler (server, NULL, server_callback, NULL, NULL);
126   url = g_strdup_printf ("http://127.0.0.1:%d/", soup_server_get_port (server));
127 
128   g_thread_create ((GThreadFunc)soup_server_run, server, FALSE, NULL);
129 
130   proxy = rest_proxy_new (url, FALSE);
131   call = g_object_new (REST_TYPE_CUSTOM_PROXY_CALL, "proxy", proxy, NULL);
132 
133   rest_proxy_call_set_function (call, "wrong-function");
134 
135   if (!rest_proxy_call_sync (call, &error)) {
136     g_printerr ("Call failed: %s\n", error->message);
137     g_error_free (error);
138     g_atomic_int_add (&errors, 1);
139     goto done;
140   }
141 
142   if (rest_proxy_call_get_status_code (call) != SOUP_STATUS_OK) {
143     g_printerr ("Wrong response code, got %d\n", rest_proxy_call_get_status_code (call));
144     g_atomic_int_add (&errors, 1);
145     goto done;
146   }
147 
148   done:
149 
150   g_object_unref (call);
151   g_object_unref (proxy);
152   soup_server_quit (server);
153   g_free (url);
154 
155   return errors != 0;
156 }
157