1 /* GIO - GLib Input, Output and Streaming Library
2 *
3 * Copyright (C) 2008 Red Hat, Inc.
4 *
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
9 *
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
14 *
15 * You should have received a copy of the GNU Lesser General
16 * Public License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
18 * Boston, MA 02110-1301, USA.
19 *
20 * Author: Christian Kellner <gicmo@gnome.org>
21 */
22
23 #include <config.h>
24 #include <string.h>
25
26 #include <stdlib.h> /* atoi */
27
28 #include <gio/gio.h>
29 #include <gvfsurimapper.h>
30 #include <gvfsuriutils.h>
31
32 typedef struct _GVfsUriMapperHttp GVfsUriMapperHttp;
33 typedef struct _GVfsUriMapperHttpClass GVfsUriMapperHttpClass;
34
35 struct _GVfsUriMapperHttp
36 {
37 GVfsUriMapper parent;
38 };
39
40 struct _GVfsUriMapperHttpClass
41 {
42 GVfsUriMapperClass parent_class;
43 };
44
45 GType g_vfs_uri_mapper_http_get_type (void);
46 void g_vfs_uri_mapper_http_register (GIOModule *module);
47
G_DEFINE_DYNAMIC_TYPE(GVfsUriMapperHttp,g_vfs_uri_mapper_http,G_VFS_TYPE_URI_MAPPER)48 G_DEFINE_DYNAMIC_TYPE (GVfsUriMapperHttp, g_vfs_uri_mapper_http, G_VFS_TYPE_URI_MAPPER)
49
50 static void
51 g_vfs_uri_mapper_http_init (GVfsUriMapperHttp *vfs)
52 {
53 }
54
55 static const char * const *
http_get_handled_schemes(GVfsUriMapper * mapper)56 http_get_handled_schemes (GVfsUriMapper *mapper)
57 {
58 static const char *schemes[] = {
59 "http",
60 "https",
61 "dav",
62 "davs",
63 NULL
64 };
65 return schemes;
66 }
67
68 static inline gboolean
port_is_default_port(int port,gboolean ssl)69 port_is_default_port (int port, gboolean ssl)
70 {
71 if (ssl)
72 return port == 443;
73 else
74 return port == 80;
75 }
76
77 static GMountSpec *
http_from_uri(GVfsUriMapper * mapper,const char * uri_str,char ** path)78 http_from_uri (GVfsUriMapper *mapper,
79 const char *uri_str,
80 char **path)
81 {
82 GMountSpec *spec;
83 gboolean ssl;
84 GDecodedUri *uri;
85
86 uri = g_vfs_decode_uri (uri_str);
87
88 if (uri == NULL)
89 return NULL;
90
91 if (!g_ascii_strncasecmp (uri->scheme, "http", 4))
92 {
93 spec = g_mount_spec_new ("http");
94 g_mount_spec_set (spec, "uri", uri_str);
95 }
96 else
97 {
98 spec = g_mount_spec_new ("dav");
99 ssl = !g_ascii_strcasecmp (uri->scheme, "davs");
100 g_mount_spec_set (spec, "ssl", ssl ? "true" : "false");
101
102 if (uri->host && *uri->host)
103 g_mount_spec_set (spec, "host", uri->host);
104
105 if (uri->userinfo && *uri->userinfo)
106 g_mount_spec_set (spec, "user", uri->userinfo);
107
108 /* only set the port if it isn't the default port */
109 if (uri->port != -1 && ! port_is_default_port (uri->port, ssl))
110 {
111 char *port = g_strdup_printf ("%d", uri->port);
112 g_mount_spec_set (spec, "port", port);
113 g_free (port);
114 }
115 }
116
117 *path = uri->path;
118 uri->path = NULL;
119 g_vfs_decoded_uri_free (uri);
120
121 return spec;
122 }
123
124 static GMountSpec *
http_get_mount_spec_for_path(GVfsUriMapper * mapper,GMountSpec * spec,const char * old_path,const char * new_path)125 http_get_mount_spec_for_path (GVfsUriMapper *mapper,
126 GMountSpec *spec,
127 const char *old_path,
128 const char *new_path)
129 {
130 const char *type;
131
132 type = g_mount_spec_get (spec, "type");
133
134 if (strcmp (type, "http") == 0)
135 {
136 const char *uri_str;
137 char *new_uri;
138 GDecodedUri *uri;
139 GMountSpec *new_spec;
140
141 uri_str = g_mount_spec_get (spec, "uri");
142
143 uri = g_vfs_decode_uri (uri_str);
144
145 if (uri == NULL)
146 return NULL;
147
148 if (strcmp (uri->path, new_path) == 0)
149 {
150 g_vfs_decoded_uri_free (uri);
151 return NULL;
152 }
153
154 g_free (uri->path);
155 uri->path = g_strdup (new_path);
156
157 g_free (uri->query);
158 uri->query = NULL;
159
160 g_free (uri->fragment);
161 uri->fragment = NULL;
162
163 new_spec = g_mount_spec_new ("http");
164
165 new_uri = g_vfs_encode_uri (uri, TRUE);
166 g_mount_spec_set (new_spec, "uri", new_uri);
167 g_free (new_uri);
168
169 g_vfs_decoded_uri_free (uri);
170
171 return new_spec;
172 }
173 else
174 return NULL;
175 }
176
177 static const char * const *
http_get_handled_mount_types(GVfsUriMapper * mapper)178 http_get_handled_mount_types (GVfsUriMapper *mapper)
179 {
180 static const char *types[] = {
181 "http",
182 "dav",
183 NULL
184 };
185 return types;
186 }
187
188 static char *
http_to_uri(GVfsUriMapper * mapper,GMountSpec * spec,const char * path,gboolean allow_utf8)189 http_to_uri (GVfsUriMapper *mapper,
190 GMountSpec *spec,
191 const char *path,
192 gboolean allow_utf8)
193 {
194 char *res;
195 const char *type;
196 const char *host;
197 const char *user;
198 const char *port;
199 const char *ssl;
200
201 type = g_mount_spec_get (spec, "type");
202
203 if (strcmp (type, "http") == 0)
204 {
205 res = g_strdup (g_mount_spec_get (spec, "uri"));
206 }
207 else
208 {
209 GDecodedUri *decoded_uri;
210 int port_num;
211
212 decoded_uri = g_new0 (GDecodedUri, 1);
213
214 ssl = g_mount_spec_get (spec, "ssl");
215 host = g_mount_spec_get (spec, "host");
216 user = g_mount_spec_get (spec, "user");
217 port = g_mount_spec_get (spec, "port");
218
219 if (ssl && strcmp (ssl, "true") == 0)
220 decoded_uri->scheme = g_strdup ("davs");
221 else
222 decoded_uri->scheme = g_strdup ("dav");
223
224 decoded_uri->host = g_strdup (host);
225 decoded_uri->userinfo = g_strdup (user);
226
227 if (port && (port_num = atoi (port)))
228 decoded_uri->port = port_num;
229 else
230 decoded_uri->port = -1;
231
232 decoded_uri->path = g_strdup (path);
233
234 res = g_vfs_encode_uri (decoded_uri, allow_utf8);
235 g_vfs_decoded_uri_free (decoded_uri);
236 }
237
238 return res;
239 }
240
241 static const char *
http_to_uri_scheme(GVfsUriMapper * mapper,GMountSpec * spec)242 http_to_uri_scheme (GVfsUriMapper *mapper,
243 GMountSpec *spec)
244 {
245 const gchar *ssl;
246 const gchar *type;
247 gboolean is_dav;
248 gboolean is_ssl;
249
250 ssl = g_mount_spec_get (spec, "ssl");
251 type = g_mount_spec_get (spec, "type");
252
253 if (strcmp (type, "dav") == 0)
254 is_dav = TRUE;
255 else if (strcmp (type, "http") == 0)
256 is_dav = FALSE;
257 else
258 return NULL;
259
260 is_ssl =
261 ssl != NULL &&
262 strcmp (ssl, "true") == 0;
263
264 if (is_dav && is_ssl)
265 return "davs";
266 else if (is_dav && !is_ssl)
267 return "dav";
268 else if (!is_dav && is_ssl)
269 return "https";
270 else
271 return "http";
272 }
273
274 static void
g_vfs_uri_mapper_http_class_finalize(GVfsUriMapperHttpClass * klass)275 g_vfs_uri_mapper_http_class_finalize (GVfsUriMapperHttpClass *klass)
276 {
277 }
278
279 static void
g_vfs_uri_mapper_http_class_init(GVfsUriMapperHttpClass * class)280 g_vfs_uri_mapper_http_class_init (GVfsUriMapperHttpClass *class)
281 {
282 GVfsUriMapperClass *mapper_class;
283
284 mapper_class = G_VFS_URI_MAPPER_CLASS (class);
285 mapper_class->get_handled_schemes = http_get_handled_schemes;
286 mapper_class->from_uri = http_from_uri;
287 mapper_class->get_mount_spec_for_path = http_get_mount_spec_for_path;
288 mapper_class->get_handled_mount_types = http_get_handled_mount_types;
289 mapper_class->to_uri = http_to_uri;
290 mapper_class->to_uri_scheme = http_to_uri_scheme;
291 }
292
293 void
g_vfs_uri_mapper_http_register(GIOModule * module)294 g_vfs_uri_mapper_http_register (GIOModule *module)
295 {
296 g_vfs_uri_mapper_http_register_type (G_TYPE_MODULE (module));
297 }
298