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 }