1 /*
2     GSK - a library to write servers
3     Copyright (C) 1999-2000 Dave Benson
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 Public
16     License along with this library; if not, write to the Free Software
17     Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
18 
19     Contact:
20         daveb@ffem.org <Dave Benson>
21 */
22 
23 
24 #ifndef __GSK_URL_H_
25 #define __GSK_URL_H_
26 
27 #include "../gskstream.h"
28 
29 G_BEGIN_DECLS
30 
31 typedef struct _GskUrl GskUrl;
32 typedef struct _GskUrlClass GskUrlClass;
33 
34 /* --- type macros --- */
35 GType gsk_url_get_type(void) G_GNUC_CONST;
36 #define GSK_TYPE_URL			(gsk_url_get_type ())
37 #define GSK_URL(obj)              (G_TYPE_CHECK_INSTANCE_CAST ((obj), GSK_TYPE_URL, GskUrl))
38 #define GSK_URL_CLASS(klass)      (G_TYPE_CHECK_CLASS_CAST ((klass), GSK_TYPE_URL, GskUrlClass))
39 #define GSK_URL_GET_CLASS(obj)    (G_TYPE_INSTANCE_GET_CLASS ((obj), GSK_TYPE_URL, GskUrlClass))
40 #define GSK_IS_URL(obj)           (G_TYPE_CHECK_INSTANCE_TYPE ((obj), GSK_TYPE_URL))
41 #define GSK_IS_URL_CLASS(klass)   (G_TYPE_CHECK_CLASS_TYPE ((klass), GSK_TYPE_URL))
42 
43 /* --- enums --- */
44 typedef enum
45 {
46   GSK_URL_SCHEME_FILE,
47   GSK_URL_SCHEME_HTTP,
48   GSK_URL_SCHEME_HTTPS,
49   GSK_URL_SCHEME_FTP,
50   GSK_URL_SCHEME_OTHER = 0x10000,
51 } GskUrlScheme;
52 
53 /* --- structures --- */
54 struct _GskUrlClass
55 {
56   GObjectClass                  parent_class;
57 };
58 
59 struct _GskUrl
60 {
61   GObject                       parent_instance;
62 
63   GskUrlScheme			scheme;
64   char                         *scheme_name;
65 
66   /* The place where the resource can be obtained.
67    * (The RFC refers to this as an `authority', which is more general, sect 3.2)
68    */
69   char                         *host;
70 
71   /* XXX: refer to RFC again for if this is general... */
72   char                         *password;
73 
74   /* For server-based urls, the port where the resource may be obtained,
75    * or 0, indicating that none was specified. (Section 3.2.2)
76    */
77   int				port;
78 
79   /* The username or NULL if none was given. */
80   char			       *user_name;
81 
82   /* The scheme-specific data (we separate the section and query pieces though)
83    * This string usually begins with a slash (/).
84    * RFC 2396, Section 3.3.
85    */
86   char                         *path;
87 
88   /* The query portion of the URL. */
89   char                         *query;
90 
91   /* The portion after a `#' character. (Section 4.1) */
92   char			       *fragment;
93 };
94 
95 /* --- character sets --- */
96 /* Characters having specific meaning within a url;
97  * these should be escaped to be passed on to the underlying scheme.
98  * From RFC 2396, section 2.2.
99  */
100 #define GSK_URL_RESERVED_CHARSET			\
101 	";/?:@&=+$,"
102 
103 /* Characters which do not normally need escaping within a URL.
104  * From RFC 2396, section 2.3.
105  */
106 #define GSK_URL_UNRESERVED_CHARSET			\
107 	"abcdefghijklmnopqrstuvwxyz"			\
108 	"ABCDEFGHIJKLMNOPQRSTUVWXYZ"			\
109 	"0123456789"					\
110 	"-_.!~*'()"
111 
112 /* --- public methods --- */
113 GskUrl         *gsk_url_new                 (const char      *spec,
114 					     GError         **error);
115 GskUrl         *gsk_url_new_in_context      (const char      *spec,
116                                              GskUrlScheme     context,
117 					     GError         **error);
118 GskUrl         *gsk_url_new_from_parts      (GskUrlScheme     scheme,
119 					     const char      *host,
120 					     int              port,
121 					     const char      *user_name,
122 					     const char      *password,
123 					     const char      *path,
124 					     const char      *query,
125 					     const char      *fragment);
126 GskUrl         *gsk_url_new_relative        (GskUrl          *base_url,
127 					     const char      *location,
128 					     GError         **error);
129 
130 char           *gsk_url_get_relative_path   (GskUrl          *url);
131 
132 guint           gsk_url_get_port            (const GskUrl    *url);
133 
134 /* Url-encoding helper functions. */
135 char           *gsk_url_decode              (const char      *encoded);
136 char           *gsk_url_encode              (const char      *decoded);
137 
138 
139 char           *gsk_url_to_string           (const GskUrl    *url);
140 
141 guint           gsk_url_hash                (const GskUrl    *url);
142 gboolean        gsk_url_equal               (const GskUrl    *a,
143                                              const GskUrl    *b);
144 
145 /* These do what is typically thought of
146  * as "url encoding" in http-land... namely SPACE maps to '+'
147  * and funny characters are encoded
148  * as %xx where 'x' denotes a single hex-digit.
149  *
150  * This is the encoding applied to field names and values in HTML
151  * forms when using the default "application/x-www-form-urlencoded"
152  * encoding. See RFC 1866, section 8.2.1.
153  */
154 char           *gsk_url_decode_http         (const char      *encoded);
155 char           *gsk_url_encode_http         (const char      *decoded);
156 char           *gsk_url_encode_http_binary  (const guint8    *decoded,
157                                              guint            length);
158 
159 /* Split an "application/x-www-form-urlencoded" format query string into
160  * a null-terminated array of strings: key, value, ...
161  * Caller must free result with g_strfreev.
162  *
163  * XXX: this is a duplicate of gsk_http_parse_cgi_query_string()
164  */
165 char **         gsk_url_split_form_urlencoded (const char *encoded_query);
166 
167 
168 gboolean gsk_url_is_valid_hostname          (const char *str,
169                                              char *bad_char_out);
170 #define gsk_url_is_valid_path(str, bad_char_out)     \
171 	gsk_url_is_valid_generic_component(str, bad_char_out)
172 #define gsk_url_is_valid_query(str, bad_char_out)    \
173 	gsk_url_is_valid_generic_component(str, bad_char_out)
174 #define gsk_url_is_valid_fragment(str, bad_char_out) \
175 	gsk_url_is_valid_generic_component(str, bad_char_out)
176 
177 /* Downloading URLs */
178 typedef void (*GskUrlSuccess) (GskStream        *stream,
179 			       gpointer          user_data);
180 typedef void (*GskUrlFailure) (GError           *error,
181 			       gpointer          user_data);
182 void           gsk_url_download             (GskUrl          *url,
183 					     GskUrlSuccess    success_func,
184 					     GskUrlFailure    failure_func,
185 					     gpointer         user_data);
186 
187 /* --- protected methods --- */
188 /* Allocating new url schemes. */
189 typedef GskUrl *(*GskUrlParser) (GskUrlScheme     scheme,
190 				 const char      *url,
191 				 gpointer         data);
192 typedef char   *(*GskUrlToString) (GskUrl        *url,
193 				   gpointer       data);
194 GskUrlScheme    gsk_url_scheme_get_unique   (const char      *url_scheme,
195 					     guint            default_port,
196 					     GskUrlParser     parse_func,
197 					     GskUrlToString   print_func,
198 					     gpointer         data);
199 
200 /* registering new download methods */
201 typedef struct _GskUrlDownload GskUrlDownload;
202 typedef void  (*GskUrlDownloadMethod)       (GskUrlDownload  *download,
203 					     gpointer         download_data);
204 void            gsk_url_scheme_add_dl_method(GskUrlScheme     scheme,
205 					     GskUrlDownloadMethod download_method,
206 					     gpointer         download_data);
207 
208 /* protected: (called (eventually) by DownloadMethod) */
209 void            gsk_url_download_success    (GskUrlDownload  *download,
210 			                     GskStream       *stream);
211 void            gsk_url_download_fail       (GskUrlDownload  *download,
212 			                     GError          *error);
213 GskUrl         *gsk_url_download_peek_url   (GskUrlDownload  *download);
214 void            gsk_url_download_redirect   (GskUrlDownload  *download,
215 					     GskUrl          *new_url);
216 
217 /*< private >*/
218 gboolean gsk_url_is_valid_generic_component (const char *str,
219                                              char *bad_char_out);
220 G_END_DECLS
221 
222 #endif
223