1 module soup.URI;
2 
3 private import glib.ConstructionException;
4 private import glib.HashTable;
5 private import glib.MemorySlice;
6 private import glib.Str;
7 private import gobject.ObjectG;
8 private import soup.c.functions;
9 public  import soup.c.types;
10 
11 
12 /**
13  * A #SoupURI represents a (parsed) URI.
14  * 
15  * Many applications will not need to use #SoupURI directly at all; on
16  * the client side, soup_message_new() takes a stringified URI, and on
17  * the server side, the path and query components are provided for you
18  * in the server callback.
19  */
20 public final class URI
21 {
22 	/** the main Gtk struct */
23 	protected SoupURI* soupURI;
24 	protected bool ownedRef;
25 
26 	/** Get the main Gtk struct */
27 	public SoupURI* getURIStruct(bool transferOwnership = false)
28 	{
29 		if (transferOwnership)
30 			ownedRef = false;
31 		return soupURI;
32 	}
33 
34 	/** the main Gtk struct as a void* */
35 	protected void* getStruct()
36 	{
37 		return cast(void*)soupURI;
38 	}
39 
40 	/**
41 	 * Sets our main struct and passes it to the parent class.
42 	 */
43 	public this (SoupURI* soupURI, bool ownedRef = false)
44 	{
45 		this.soupURI = soupURI;
46 		this.ownedRef = ownedRef;
47 	}
48 
49 	~this ()
50 	{
51 		if ( ownedRef )
52 			soup_uri_free(soupURI);
53 	}
54 
55 
56 	/**
57 	 * the URI scheme (eg, "http")
58 	 */
59 	public @property string scheme()
60 	{
61 		return Str.toString(soupURI.scheme);
62 	}
63 
64 	/** Ditto */
65 	public @property void scheme(string value)
66 	{
67 		soupURI.scheme = Str.toStringz(value);
68 	}
69 
70 	/**
71 	 * a username, or %NULL
72 	 */
73 	public @property string user()
74 	{
75 		return Str.toString(soupURI.user);
76 	}
77 
78 	/** Ditto */
79 	public @property void user(string value)
80 	{
81 		soupURI.user = Str.toStringz(value);
82 	}
83 
84 	/**
85 	 * a password, or %NULL
86 	 */
87 	public @property string password()
88 	{
89 		return Str.toString(soupURI.password);
90 	}
91 
92 	/** Ditto */
93 	public @property void password(string value)
94 	{
95 		soupURI.password = Str.toStringz(value);
96 	}
97 
98 	/**
99 	 * the hostname or IP address, or %NULL
100 	 */
101 	public @property string host()
102 	{
103 		return Str.toString(soupURI.host);
104 	}
105 
106 	/** Ditto */
107 	public @property void host(string value)
108 	{
109 		soupURI.host = Str.toStringz(value);
110 	}
111 
112 	/**
113 	 * the port number on @host
114 	 */
115 	public @property uint port()
116 	{
117 		return soupURI.port;
118 	}
119 
120 	/** Ditto */
121 	public @property void port(uint value)
122 	{
123 		soupURI.port = value;
124 	}
125 
126 	/**
127 	 * the path on @host
128 	 */
129 	public @property string path()
130 	{
131 		return Str.toString(soupURI.path);
132 	}
133 
134 	/** Ditto */
135 	public @property void path(string value)
136 	{
137 		soupURI.path = Str.toStringz(value);
138 	}
139 
140 	/**
141 	 * a query for @path, or %NULL
142 	 */
143 	public @property string query()
144 	{
145 		return Str.toString(soupURI.query);
146 	}
147 
148 	/** Ditto */
149 	public @property void query(string value)
150 	{
151 		soupURI.query = Str.toStringz(value);
152 	}
153 
154 	/**
155 	 * a fragment identifier within @path, or %NULL
156 	 */
157 	public @property string fragment()
158 	{
159 		return Str.toString(soupURI.fragment);
160 	}
161 
162 	/** Ditto */
163 	public @property void fragment(string value)
164 	{
165 		soupURI.fragment = Str.toStringz(value);
166 	}
167 
168 	/** */
169 	public static GType getType()
170 	{
171 		return soup_uri_get_type();
172 	}
173 
174 	/**
175 	 * Parses an absolute URI.
176 	 *
177 	 * You can also pass %NULL for @uri_string if you want to get back an
178 	 * "empty" #SoupURI that you can fill in by hand. (You will need to
179 	 * call at least soup_uri_set_scheme() and soup_uri_set_path(), since
180 	 * those fields are required.)
181 	 *
182 	 * Params:
183 	 *     uriString = a URI
184 	 *
185 	 * Returns: a #SoupURI, or %NULL if the given string
186 	 *     was found to be invalid.
187 	 *
188 	 * Throws: ConstructionException GTK+ fails to create the object.
189 	 */
190 	public this(string uriString)
191 	{
192 		auto __p = soup_uri_new(Str.toStringz(uriString));
193 
194 		if(__p is null)
195 		{
196 			throw new ConstructionException("null returned by new");
197 		}
198 
199 		this(cast(SoupURI*) __p);
200 	}
201 
202 	/**
203 	 * Parses @uri_string relative to @base.
204 	 *
205 	 * Params:
206 	 *     base = a base URI
207 	 *     uriString = the URI
208 	 *
209 	 * Returns: a parsed #SoupURI.
210 	 *
211 	 * Throws: ConstructionException GTK+ fails to create the object.
212 	 */
213 	public this(URI base, string uriString)
214 	{
215 		auto __p = soup_uri_new_with_base((base is null) ? null : base.getURIStruct(), Str.toStringz(uriString));
216 
217 		if(__p is null)
218 		{
219 			throw new ConstructionException("null returned by new_with_base");
220 		}
221 
222 		this(cast(SoupURI*) __p);
223 	}
224 
225 	/**
226 	 * Copies @uri
227 	 *
228 	 * Returns: a copy of @uri, which must be freed with soup_uri_free()
229 	 */
230 	public URI copy()
231 	{
232 		auto __p = soup_uri_copy(soupURI);
233 
234 		if(__p is null)
235 		{
236 			return null;
237 		}
238 
239 		return ObjectG.getDObject!(URI)(cast(SoupURI*) __p, true);
240 	}
241 
242 	/**
243 	 * Makes a copy of @uri, considering only the protocol, host, and port
244 	 *
245 	 * Returns: the new #SoupURI
246 	 *
247 	 * Since: 2.28
248 	 */
249 	public URI copyHost()
250 	{
251 		auto __p = soup_uri_copy_host(soupURI);
252 
253 		if(__p is null)
254 		{
255 			return null;
256 		}
257 
258 		return ObjectG.getDObject!(URI)(cast(SoupURI*) __p, true);
259 	}
260 
261 	/**
262 	 * Tests whether or not @uri1 and @uri2 are equal in all parts
263 	 *
264 	 * Params:
265 	 *     uri2 = another #SoupURI
266 	 *
267 	 * Returns: %TRUE or %FALSE
268 	 */
269 	public bool equal(URI uri2)
270 	{
271 		return soup_uri_equal(soupURI, (uri2 is null) ? null : uri2.getURIStruct()) != 0;
272 	}
273 
274 	/**
275 	 * Frees @uri.
276 	 */
277 	public void free()
278 	{
279 		soup_uri_free(soupURI);
280 		ownedRef = false;
281 	}
282 
283 	/**
284 	 * Gets @uri's fragment.
285 	 *
286 	 * Returns: @uri's fragment.
287 	 *
288 	 * Since: 2.32
289 	 */
290 	public string getFragment()
291 	{
292 		return Str.toString(soup_uri_get_fragment(soupURI));
293 	}
294 
295 	/**
296 	 * Gets @uri's host.
297 	 *
298 	 * Returns: @uri's host.
299 	 *
300 	 * Since: 2.32
301 	 */
302 	public string getHost()
303 	{
304 		return Str.toString(soup_uri_get_host(soupURI));
305 	}
306 
307 	/**
308 	 * Gets @uri's password.
309 	 *
310 	 * Returns: @uri's password.
311 	 *
312 	 * Since: 2.32
313 	 */
314 	public string getPassword()
315 	{
316 		return Str.toString(soup_uri_get_password(soupURI));
317 	}
318 
319 	/**
320 	 * Gets @uri's path.
321 	 *
322 	 * Returns: @uri's path.
323 	 *
324 	 * Since: 2.32
325 	 */
326 	public string getPath()
327 	{
328 		return Str.toString(soup_uri_get_path(soupURI));
329 	}
330 
331 	/**
332 	 * Gets @uri's port.
333 	 *
334 	 * Returns: @uri's port.
335 	 *
336 	 * Since: 2.32
337 	 */
338 	public uint getPort()
339 	{
340 		return soup_uri_get_port(soupURI);
341 	}
342 
343 	/**
344 	 * Gets @uri's query.
345 	 *
346 	 * Returns: @uri's query.
347 	 *
348 	 * Since: 2.32
349 	 */
350 	public string getQuery()
351 	{
352 		return Str.toString(soup_uri_get_query(soupURI));
353 	}
354 
355 	/**
356 	 * Gets @uri's scheme.
357 	 *
358 	 * Returns: @uri's scheme.
359 	 *
360 	 * Since: 2.32
361 	 */
362 	public string getScheme()
363 	{
364 		return Str.toString(soup_uri_get_scheme(soupURI));
365 	}
366 
367 	/**
368 	 * Gets @uri's user.
369 	 *
370 	 * Returns: @uri's user.
371 	 *
372 	 * Since: 2.32
373 	 */
374 	public string getUser()
375 	{
376 		return Str.toString(soup_uri_get_user(soupURI));
377 	}
378 
379 	/**
380 	 * Compares @v1 and @v2, considering only the scheme, host, and port.
381 	 *
382 	 * Params:
383 	 *     v2 = a #SoupURI with a non-%NULL @host member
384 	 *
385 	 * Returns: whether or not the URIs are equal in scheme, host,
386 	 *     and port.
387 	 *
388 	 * Since: 2.28
389 	 */
390 	public bool hostEqual(URI v2)
391 	{
392 		return soup_uri_host_equal(soupURI, (v2 is null) ? null : v2.getURIStruct()) != 0;
393 	}
394 
395 	/**
396 	 * Hashes @key, considering only the scheme, host, and port.
397 	 *
398 	 * Returns: a hash
399 	 *
400 	 * Since: 2.28
401 	 */
402 	public uint hostHash()
403 	{
404 		return soup_uri_host_hash(soupURI);
405 	}
406 
407 	/**
408 	 * Sets @uri's fragment to @fragment.
409 	 *
410 	 * Params:
411 	 *     fragment = the fragment
412 	 */
413 	public void setFragment(string fragment)
414 	{
415 		soup_uri_set_fragment(soupURI, Str.toStringz(fragment));
416 	}
417 
418 	/**
419 	 * Sets @uri's host to @host.
420 	 *
421 	 * If @host is an IPv6 IP address, it should not include the brackets
422 	 * required by the URI syntax; they will be added automatically when
423 	 * converting @uri to a string.
424 	 *
425 	 * http and https URIs should not have a %NULL @host.
426 	 *
427 	 * Params:
428 	 *     host = the hostname or IP address, or %NULL
429 	 */
430 	public void setHost(string host)
431 	{
432 		soup_uri_set_host(soupURI, Str.toStringz(host));
433 	}
434 
435 	/**
436 	 * Sets @uri's password to @password.
437 	 *
438 	 * Params:
439 	 *     password = the password, or %NULL
440 	 */
441 	public void setPassword(string password)
442 	{
443 		soup_uri_set_password(soupURI, Str.toStringz(password));
444 	}
445 
446 	/**
447 	 * Sets @uri's path to @path.
448 	 *
449 	 * Params:
450 	 *     path = the non-%NULL path
451 	 */
452 	public void setPath(string path)
453 	{
454 		soup_uri_set_path(soupURI, Str.toStringz(path));
455 	}
456 
457 	/**
458 	 * Sets @uri's port to @port. If @port is 0, @uri will not have an
459 	 * explicitly-specified port.
460 	 *
461 	 * Params:
462 	 *     port = the port, or 0
463 	 */
464 	public void setPort(uint port)
465 	{
466 		soup_uri_set_port(soupURI, port);
467 	}
468 
469 	/**
470 	 * Sets @uri's query to @query.
471 	 *
472 	 * Params:
473 	 *     query = the query
474 	 */
475 	public void setQuery(string query)
476 	{
477 		soup_uri_set_query(soupURI, Str.toStringz(query));
478 	}
479 
480 	/**
481 	 * Sets @uri's query to the result of encoding @form according to the
482 	 * HTML form rules. See soup_form_encode_hash() for more information.
483 	 *
484 	 * Params:
485 	 *     form = a #GHashTable containing HTML form
486 	 *         information
487 	 */
488 	public void setQueryFromForm(HashTable form)
489 	{
490 		soup_uri_set_query_from_form(soupURI, (form is null) ? null : form.getHashTableStruct());
491 	}
492 
493 	/**
494 	 * Sets @uri's scheme to @scheme. This will also set @uri's port to
495 	 * the default port for @scheme, if known.
496 	 *
497 	 * Params:
498 	 *     scheme = the URI scheme
499 	 */
500 	public void setScheme(string scheme)
501 	{
502 		soup_uri_set_scheme(soupURI, Str.toStringz(scheme));
503 	}
504 
505 	/**
506 	 * Sets @uri's user to @user.
507 	 *
508 	 * Params:
509 	 *     user = the username, or %NULL
510 	 */
511 	public void setUser(string user)
512 	{
513 		soup_uri_set_user(soupURI, Str.toStringz(user));
514 	}
515 
516 	/**
517 	 * Returns a string representing @uri.
518 	 *
519 	 * If @just_path_and_query is %TRUE, this concatenates the path and query
520 	 * together. That is, it constructs the string that would be needed in
521 	 * the Request-Line of an HTTP request for @uri.
522 	 *
523 	 * Note that the output will never contain a password, even if @uri
524 	 * does.
525 	 *
526 	 * Params:
527 	 *     justPathAndQuery = if %TRUE, output just the path and query portions
528 	 *
529 	 * Returns: a string representing @uri, which the caller must free.
530 	 */
531 	public string toString(bool justPathAndQuery)
532 	{
533 		auto retStr = soup_uri_to_string(soupURI, justPathAndQuery);
534 
535 		scope(exit) Str.freeString(retStr);
536 		return Str.toString(retStr);
537 	}
538 
539 	/**
540 	 * Tests if @uri uses the default port for its scheme. (Eg, 80 for
541 	 * http.) (This only works for http, https and ftp; libsoup does not know
542 	 * the default ports of other protocols.)
543 	 *
544 	 * Returns: %TRUE or %FALSE
545 	 */
546 	public bool usesDefaultPort()
547 	{
548 		return soup_uri_uses_default_port(soupURI) != 0;
549 	}
550 
551 	/**
552 	 * Fully %<!-- -->-decodes @part.
553 	 *
554 	 * In the past, this would return %NULL if @part contained invalid
555 	 * percent-encoding, but now it just ignores the problem (as
556 	 * soup_uri_new() already did).
557 	 *
558 	 * Params:
559 	 *     part = a URI part
560 	 *
561 	 * Returns: the decoded URI part.
562 	 */
563 	public static string decode(string part)
564 	{
565 		auto retStr = soup_uri_decode(Str.toStringz(part));
566 
567 		scope(exit) Str.freeString(retStr);
568 		return Str.toString(retStr);
569 	}
570 
571 	/**
572 	 * This %<!-- -->-encodes the given URI part and returns the escaped
573 	 * version in allocated memory, which the caller must free when it is
574 	 * done.
575 	 *
576 	 * Params:
577 	 *     part = a URI part
578 	 *     escapeExtra = additional reserved characters to
579 	 *         escape (or %NULL)
580 	 *
581 	 * Returns: the encoded URI part
582 	 */
583 	public static string encode(string part, string escapeExtra)
584 	{
585 		auto retStr = soup_uri_encode(Str.toStringz(part), Str.toStringz(escapeExtra));
586 
587 		scope(exit) Str.freeString(retStr);
588 		return Str.toString(retStr);
589 	}
590 
591 	/**
592 	 * %<!-- -->-decodes any "unreserved" characters (or characters in
593 	 * @unescape_extra) in @part, and %<!-- -->-encodes any non-ASCII
594 	 * characters, spaces, and non-printing characters in @part.
595 	 *
596 	 * "Unreserved" characters are those that are not allowed to be used
597 	 * for punctuation according to the URI spec. For example, letters are
598 	 * unreserved, so soup_uri_normalize() will turn
599 	 * <literal>http://example.com/foo/b%<!-- -->61r</literal> into
600 	 * <literal>http://example.com/foo/bar</literal>, which is guaranteed
601 	 * to mean the same thing. However, "/" is "reserved", so
602 	 * <literal>http://example.com/foo%<!-- -->2Fbar</literal> would not
603 	 * be changed, because it might mean something different to the
604 	 * server.
605 	 *
606 	 * In the past, this would return %NULL if @part contained invalid
607 	 * percent-encoding, but now it just ignores the problem (as
608 	 * soup_uri_new() already did).
609 	 *
610 	 * Params:
611 	 *     part = a URI part
612 	 *     unescapeExtra = reserved characters to unescape (or %NULL)
613 	 *
614 	 * Returns: the normalized URI part
615 	 */
616 	public static string normalize(string part, string unescapeExtra)
617 	{
618 		auto retStr = soup_uri_normalize(Str.toStringz(part), Str.toStringz(unescapeExtra));
619 
620 		scope(exit) Str.freeString(retStr);
621 		return Str.toString(retStr);
622 	}
623 }