Git init
[profile/ivi/libsoup2.4.git] / libsoup / soup-proxy-resolver.c
1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
2 /*
3  * soup-proxy-resolver.c: HTTP proxy resolver interface
4  *
5  * Copyright (C) 2008 Red Hat, Inc.
6  */
7
8 #ifdef HAVE_CONFIG_H
9 #include <config.h>
10 #endif
11
12 #include "soup-proxy-resolver.h"
13 #include "soup-proxy-uri-resolver.h"
14 #include "soup-address.h"
15 #include "soup-message.h"
16 #include "soup-session-feature.h"
17 #include "soup-uri.h"
18
19 static void soup_proxy_resolver_interface_init (GTypeInterface *iface);
20 static void soup_proxy_resolver_uri_resolver_interface_init (SoupProxyURIResolverInterface *uri_resolver_interface);
21
22 GType
23 soup_proxy_resolver_get_type (void)
24 {
25   static volatile gsize g_define_type_id__volatile = 0;
26   if (g_once_init_enter (&g_define_type_id__volatile))
27     {
28       GType g_define_type_id =
29         g_type_register_static_simple (G_TYPE_INTERFACE,
30                                        g_intern_static_string ("SoupProxyResolver"),
31                                        sizeof (SoupProxyResolverInterface),
32                                        (GClassInitFunc)soup_proxy_resolver_interface_init,
33                                        0,
34                                        (GInstanceInitFunc)NULL,
35                                        (GTypeFlags) 0);
36       g_type_interface_add_prerequisite (g_define_type_id, G_TYPE_OBJECT);
37       g_type_interface_add_prerequisite (g_define_type_id, SOUP_TYPE_SESSION_FEATURE);
38       g_once_init_leave (&g_define_type_id__volatile, g_define_type_id);
39     }
40   return g_define_type_id__volatile;
41 }
42
43 static void
44 proxy_resolver_interface_check (gpointer func_data, gpointer g_iface)
45 {
46         GTypeInterface *iface = g_iface;
47
48         if (iface->g_type != SOUP_TYPE_PROXY_RESOLVER)
49                 return;
50
51         /* If the class hasn't already declared that it implements
52          * SoupProxyURIResolver, add our own compat implementation.
53          */
54         if (!g_type_is_a (iface->g_instance_type, SOUP_TYPE_PROXY_URI_RESOLVER)) {
55                 const GInterfaceInfo uri_resolver_interface_info = {
56                         (GInterfaceInitFunc) soup_proxy_resolver_uri_resolver_interface_init, NULL, NULL
57                 };
58                 g_type_add_interface_static (iface->g_instance_type,
59                                              SOUP_TYPE_PROXY_URI_RESOLVER,
60                                              &uri_resolver_interface_info);
61         }
62 }
63
64
65 static void
66 soup_proxy_resolver_interface_init (GTypeInterface *iface)
67 {
68         /* Add an interface_check where we can kludgily add the
69          * SoupProxyURIResolver interface to all SoupProxyResolvers.
70          * (SoupProxyResolver can't just implement
71          * SoupProxyURIResolver itself because interface types can't
72          * implement other interfaces.) This is an ugly hack, but it
73          * only gets used if someone actually creates a
74          * SoupProxyResolver...
75          */
76         g_type_add_interface_check (NULL, proxy_resolver_interface_check);
77 }
78
79 void
80 soup_proxy_resolver_get_proxy_async (SoupProxyResolver  *proxy_resolver,
81                                      SoupMessage        *msg,
82                                      GMainContext       *async_context,
83                                      GCancellable       *cancellable,
84                                      SoupProxyResolverCallback callback,
85                                      gpointer            user_data)
86 {
87         SOUP_PROXY_RESOLVER_GET_CLASS (proxy_resolver)->
88                 get_proxy_async (proxy_resolver, msg,
89                                  async_context, cancellable,
90                                  callback, user_data);
91 }
92
93 guint
94 soup_proxy_resolver_get_proxy_sync (SoupProxyResolver  *proxy_resolver,
95                                     SoupMessage        *msg,
96                                     GCancellable       *cancellable,
97                                     SoupAddress       **addr)
98 {
99         return SOUP_PROXY_RESOLVER_GET_CLASS (proxy_resolver)->
100                 get_proxy_sync (proxy_resolver, msg, cancellable, addr);
101 }
102
103 /* SoupProxyURIResolver implementation */
104
105 static SoupURI *
106 uri_from_address (SoupAddress *addr)
107 {
108         SoupURI *proxy_uri;
109
110         proxy_uri = soup_uri_new (NULL);
111         soup_uri_set_scheme (proxy_uri, SOUP_URI_SCHEME_HTTP);
112         soup_uri_set_host (proxy_uri, soup_address_get_name (addr));
113         soup_uri_set_port (proxy_uri, soup_address_get_port (addr));
114         return proxy_uri;
115 }
116
117 typedef struct {
118         SoupProxyURIResolverCallback callback;
119         gpointer user_data;
120 } ProxyURIResolverAsyncData;
121
122 static void
123 compat_got_proxy (SoupProxyResolver *proxy_resolver,
124                   SoupMessage *msg, guint status, SoupAddress *proxy_addr,
125                   gpointer user_data)
126 {
127         ProxyURIResolverAsyncData *purad = user_data;
128         SoupURI *proxy_uri;
129
130         proxy_uri = proxy_addr ? uri_from_address (proxy_addr) : NULL;
131         purad->callback (SOUP_PROXY_URI_RESOLVER (proxy_resolver),
132                          status, proxy_uri, purad->user_data);
133         g_object_unref (msg);
134         if (proxy_uri)
135                 soup_uri_free (proxy_uri);
136         g_slice_free (ProxyURIResolverAsyncData, purad);
137 }
138
139 static void
140 compat_get_proxy_uri_async (SoupProxyURIResolver *proxy_uri_resolver,
141                             SoupURI *uri, GMainContext *async_context,
142                             GCancellable *cancellable,
143                             SoupProxyURIResolverCallback callback,
144                             gpointer user_data)
145 {
146         SoupMessage *dummy_msg;
147         ProxyURIResolverAsyncData *purad;
148
149         dummy_msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
150
151         purad = g_slice_new (ProxyURIResolverAsyncData);
152         purad->callback = callback;
153         purad->user_data = user_data;
154
155         soup_proxy_resolver_get_proxy_async (
156                 SOUP_PROXY_RESOLVER (proxy_uri_resolver), dummy_msg,
157                 async_context, cancellable,
158                 compat_got_proxy, purad);
159 }
160
161 static guint
162 compat_get_proxy_uri_sync (SoupProxyURIResolver *proxy_uri_resolver,
163                            SoupURI *uri, GCancellable *cancellable,
164                            SoupURI **proxy_uri)
165 {
166         SoupMessage *dummy_msg;
167         SoupAddress *proxy_addr = NULL;
168         guint status;
169
170         dummy_msg = soup_message_new_from_uri (SOUP_METHOD_GET, uri);
171         status = soup_proxy_resolver_get_proxy_sync (
172                 SOUP_PROXY_RESOLVER (proxy_uri_resolver), dummy_msg,
173                 cancellable, &proxy_addr);
174         g_object_unref (dummy_msg);
175         if (!proxy_addr)
176                 return status;
177
178         *proxy_uri = uri_from_address (proxy_addr);
179         g_object_unref (proxy_addr);
180         return status;
181 }
182
183 static void
184 soup_proxy_resolver_uri_resolver_interface_init (SoupProxyURIResolverInterface *uri_resolver_interface)
185 {
186         uri_resolver_interface->get_proxy_uri_async = compat_get_proxy_uri_async;
187         uri_resolver_interface->get_proxy_uri_sync = compat_get_proxy_uri_sync;
188 }