1 module soup.Address; 2 3 private import gio.Cancellable; 4 private import gio.SocketAddress; 5 private import gio.SocketConnectableIF; 6 private import gio.SocketConnectableT; 7 private import glib.ConstructionException; 8 private import glib.MainContext; 9 private import glib.Str; 10 private import gobject.ObjectG; 11 private import soup.c.functions; 12 public import soup.c.types; 13 14 15 /** 16 * #SoupAddress represents the address of a TCP connection endpoint: 17 * both the IP address and the port. (It is somewhat like an 18 * object-oriented version of struct sockaddr.) 19 * 20 * Although #SoupAddress is still used in some libsoup API's, it 21 * should not be used in new code; use GLib's #GNetworkAddress or 22 * #GSocketAddress instead. 23 */ 24 public class Address : ObjectG, SocketConnectableIF 25 { 26 /** the main Gtk struct */ 27 protected SoupAddress* soupAddress; 28 29 /** Get the main Gtk struct */ 30 public SoupAddress* getAddressStruct(bool transferOwnership = false) 31 { 32 if (transferOwnership) 33 ownedRef = false; 34 return soupAddress; 35 } 36 37 /** the main Gtk struct as a void* */ 38 protected override void* getStruct() 39 { 40 return cast(void*)soupAddress; 41 } 42 43 /** 44 * Sets our main struct and passes it to the parent class. 45 */ 46 public this (SoupAddress* soupAddress, bool ownedRef = false) 47 { 48 this.soupAddress = soupAddress; 49 super(cast(GObject*)soupAddress, ownedRef); 50 } 51 52 // add the SocketConnectable capabilities 53 mixin SocketConnectableT!(SoupAddress); 54 55 56 /** */ 57 public static GType getType() 58 { 59 return soup_address_get_type(); 60 } 61 62 /** 63 * Creates a #SoupAddress from @name and @port. The #SoupAddress's IP 64 * address may not be available right away; the caller can call 65 * soup_address_resolve_async() or soup_address_resolve_sync() to 66 * force a DNS resolution. 67 * 68 * Params: 69 * name = a hostname or physical address 70 * port = a port number 71 * 72 * Returns: a #SoupAddress 73 * 74 * Throws: ConstructionException GTK+ fails to create the object. 75 */ 76 public this(string name, uint port) 77 { 78 auto __p = soup_address_new(Str.toStringz(name), port); 79 80 if(__p is null) 81 { 82 throw new ConstructionException("null returned by new"); 83 } 84 85 this(cast(SoupAddress*) __p, true); 86 } 87 88 /** 89 * Returns a #SoupAddress corresponding to the "any" address 90 * for @family (or %NULL if @family isn't supported), suitable for 91 * using as a listening #SoupSocket. 92 * 93 * Params: 94 * family = the address family 95 * port = the port number (usually %SOUP_ADDRESS_ANY_PORT) 96 * 97 * Returns: the new #SoupAddress 98 * 99 * Throws: ConstructionException GTK+ fails to create the object. 100 */ 101 public this(SoupAddressFamily family, uint port) 102 { 103 auto __p = soup_address_new_any(family, port); 104 105 if(__p is null) 106 { 107 throw new ConstructionException("null returned by new_any"); 108 } 109 110 this(cast(SoupAddress*) __p, true); 111 } 112 113 /** 114 * Returns a #SoupAddress equivalent to @sa (or %NULL if @sa's 115 * address family isn't supported) 116 * 117 * Params: 118 * sa = a pointer to a sockaddr 119 * len = size of @sa 120 * 121 * Returns: the new #SoupAddress 122 * 123 * Throws: ConstructionException GTK+ fails to create the object. 124 */ 125 public this(sockaddr* sa, int len) 126 { 127 auto __p = soup_address_new_from_sockaddr(sa, len); 128 129 if(__p is null) 130 { 131 throw new ConstructionException("null returned by new_from_sockaddr"); 132 } 133 134 this(cast(SoupAddress*) __p, true); 135 } 136 137 /** 138 * Tests if @addr1 and @addr2 have the same IP address. This method 139 * can be used with soup_address_hash_by_ip() to create a 140 * #GHashTable that hashes on IP address. 141 * 142 * This would be used to distinguish hosts in situations where 143 * different virtual hosts on the same IP address should be considered 144 * the same. Eg, if "www.example.com" and "www.example.net" have the 145 * same IP address, then a single connection can be used to talk 146 * to either of them. 147 * 148 * See also soup_address_equal_by_name(), which compares by name 149 * rather than by IP address. 150 * 151 * Params: 152 * addr2 = another #SoupAddress with a resolved 153 * IP address 154 * 155 * Returns: whether or not @addr1 and @addr2 have the same IP 156 * address. 157 * 158 * Since: 2.26 159 */ 160 public bool equalByIp(Address addr2) 161 { 162 return soup_address_equal_by_ip(soupAddress, (addr2 is null) ? null : addr2.getAddressStruct()) != 0; 163 } 164 165 /** 166 * Tests if @addr1 and @addr2 have the same "name". This method can be 167 * used with soup_address_hash_by_name() to create a #GHashTable that 168 * hashes on address "names". 169 * 170 * Comparing by name normally means comparing the addresses by their 171 * hostnames. But if the address was originally created using an IP 172 * address literal, then it will be compared by that instead. 173 * 174 * In particular, if "www.example.com" has the IP address 10.0.0.1, 175 * and @addr1 was created with the name "www.example.com" and @addr2 176 * was created with the name "10.0.0.1", then they will compare as 177 * unequal for purposes of soup_address_equal_by_name(). 178 * 179 * This would be used to distinguish hosts in situations where 180 * different virtual hosts on the same IP address should be considered 181 * different. Eg, for purposes of HTTP authentication or cookies, two 182 * hosts with the same IP address but different names are considered 183 * to be different hosts. 184 * 185 * See also soup_address_equal_by_ip(), which compares by IP address 186 * rather than by name. 187 * 188 * Params: 189 * addr2 = another #SoupAddress with a resolved 190 * name 191 * 192 * Returns: whether or not @addr1 and @addr2 have the same name 193 * 194 * Since: 2.26 195 */ 196 public bool equalByName(Address addr2) 197 { 198 return soup_address_equal_by_name(soupAddress, (addr2 is null) ? null : addr2.getAddressStruct()) != 0; 199 } 200 201 /** 202 * Creates a new #GSocketAddress corresponding to @addr (which is assumed 203 * to only have one socket address associated with it). 204 * 205 * Returns: a new #GSocketAddress 206 * 207 * Since: 2.32 208 */ 209 public SocketAddress getGsockaddr() 210 { 211 auto __p = soup_address_get_gsockaddr(soupAddress); 212 213 if(__p is null) 214 { 215 return null; 216 } 217 218 return ObjectG.getDObject!(SocketAddress)(cast(GSocketAddress*) __p, true); 219 } 220 221 /** 222 * Returns the hostname associated with @addr. 223 * 224 * This method is not thread-safe; if you call it while @addr is being 225 * resolved in another thread, it may return garbage. You can use 226 * soup_address_is_resolved() to safely test whether or not an address 227 * is resolved before fetching its name or address. 228 * 229 * Returns: the hostname, or %NULL if it is not known. 230 */ 231 public string getName() 232 { 233 return Str.toString(soup_address_get_name(soupAddress)); 234 } 235 236 /** 237 * Returns the physical address associated with @addr as a string. 238 * (Eg, "127.0.0.1"). If the address is not yet known, returns %NULL. 239 * 240 * This method is not thread-safe; if you call it while @addr is being 241 * resolved in another thread, it may return garbage. You can use 242 * soup_address_is_resolved() to safely test whether or not an address 243 * is resolved before fetching its name or address. 244 * 245 * Returns: the physical address, or %NULL 246 */ 247 public string getPhysical() 248 { 249 return Str.toString(soup_address_get_physical(soupAddress)); 250 } 251 252 /** 253 * Returns the port associated with @addr. 254 * 255 * Returns: the port 256 */ 257 public uint getPort() 258 { 259 return soup_address_get_port(soupAddress); 260 } 261 262 /** 263 * Returns the sockaddr associated with @addr, with its length in 264 * *@len. If the sockaddr is not yet known, returns %NULL. 265 * 266 * This method is not thread-safe; if you call it while @addr is being 267 * resolved in another thread, it may return garbage. You can use 268 * soup_address_is_resolved() to safely test whether or not an address 269 * is resolved before fetching its name or address. 270 * 271 * Params: 272 * len = return location for sockaddr length 273 * 274 * Returns: the sockaddr, or %NULL 275 */ 276 public sockaddr* getSockaddr(int* len) 277 { 278 return soup_address_get_sockaddr(soupAddress, len); 279 } 280 281 /** 282 * A hash function (for #GHashTable) that corresponds to 283 * soup_address_equal_by_ip(), qv 284 * 285 * Returns: the IP-based hash value for @addr. 286 * 287 * Since: 2.26 288 */ 289 public uint hashByIp() 290 { 291 return soup_address_hash_by_ip(soupAddress); 292 } 293 294 /** 295 * A hash function (for #GHashTable) that corresponds to 296 * soup_address_equal_by_name(), qv 297 * 298 * Returns: the named-based hash value for @addr. 299 * 300 * Since: 2.26 301 */ 302 public uint hashByName() 303 { 304 return soup_address_hash_by_name(soupAddress); 305 } 306 307 /** 308 * Tests if @addr has already been resolved. Unlike the other 309 * #SoupAddress "get" methods, this is safe to call when @addr might 310 * be being resolved in another thread. 311 * 312 * Returns: %TRUE if @addr has been resolved. 313 */ 314 public bool isResolved() 315 { 316 return soup_address_is_resolved(soupAddress) != 0; 317 } 318 319 /** 320 * Asynchronously resolves the missing half of @addr (its IP address 321 * if it was created with soup_address_new(), or its hostname if it 322 * was created with soup_address_new_from_sockaddr() or 323 * soup_address_new_any().) 324 * 325 * If @cancellable is non-%NULL, it can be used to cancel the 326 * resolution. @callback will still be invoked in this case, with a 327 * status of %SOUP_STATUS_CANCELLED. 328 * 329 * It is safe to call this more than once on a given address, from the 330 * same thread, with the same @async_context (and doing so will not 331 * result in redundant DNS queries being made). But it is not safe to 332 * call from multiple threads, or with different @async_contexts, or 333 * mixed with calls to soup_address_resolve_sync(). 334 * 335 * Params: 336 * asyncContext = the #GMainContext to call @callback from 337 * cancellable = a #GCancellable object, or %NULL 338 * callback = callback to call with the result 339 * userData = data for @callback 340 */ 341 public void resolveAsync(MainContext asyncContext, Cancellable cancellable, SoupAddressCallback callback, void* userData) 342 { 343 soup_address_resolve_async(soupAddress, (asyncContext is null) ? null : asyncContext.getMainContextStruct(), (cancellable is null) ? null : cancellable.getCancellableStruct(), callback, userData); 344 } 345 346 /** 347 * Synchronously resolves the missing half of @addr, as with 348 * soup_address_resolve_async(). 349 * 350 * If @cancellable is non-%NULL, it can be used to cancel the 351 * resolution. soup_address_resolve_sync() will then return a status 352 * of %SOUP_STATUS_CANCELLED. 353 * 354 * It is safe to call this more than once, even from different 355 * threads, but it is not safe to mix calls to 356 * soup_address_resolve_sync() with calls to 357 * soup_address_resolve_async() on the same address. 358 * 359 * Params: 360 * cancellable = a #GCancellable object, or %NULL 361 * 362 * Returns: %SOUP_STATUS_OK, %SOUP_STATUS_CANT_RESOLVE, or 363 * %SOUP_STATUS_CANCELLED. 364 */ 365 public uint resolveSync(Cancellable cancellable) 366 { 367 return soup_address_resolve_sync(soupAddress, (cancellable is null) ? null : cancellable.getCancellableStruct()); 368 } 369 }