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 }