1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5 * Copyright (C) 2008 Red Hat, Inc.
15 #include "soup-cookie.h"
16 #include "soup-cookie-jar.h"
17 #include "soup-date.h"
18 #include "soup-enum-types.h"
19 #include "soup-marshal.h"
20 #include "soup-message.h"
21 #include "soup-session-feature.h"
26 * SECTION:soup-cookie-jar
27 * @short_description: Automatic cookie handling for #SoupSession
29 * A #SoupCookieJar stores #SoupCookie<!-- -->s and arrange for them
30 * to be sent with the appropriate #SoupMessage<!-- -->s.
31 * #SoupCookieJar implements #SoupSessionFeature, so you can add a
32 * cookie jar to a session with soup_session_add_feature() or
33 * soup_session_add_feature_by_type().
35 * Note that the base #SoupCookieJar class does not support any form
36 * of long-term cookie persistence.
39 static void soup_cookie_jar_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data);
40 static void request_queued (SoupSessionFeature *feature, SoupSession *session,
42 static void request_started (SoupSessionFeature *feature, SoupSession *session,
43 SoupMessage *msg, SoupSocket *socket);
44 static void request_unqueued (SoupSessionFeature *feature, SoupSession *session,
46 static gboolean is_persistent (SoupCookieJar *jar);
48 G_DEFINE_TYPE_WITH_CODE (SoupCookieJar, soup_cookie_jar, G_TYPE_OBJECT,
49 G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE,
50 soup_cookie_jar_session_feature_init))
57 static guint signals[LAST_SIGNAL] = { 0 };
69 gboolean constructed, read_only;
70 GHashTable *domains, *serials;
72 SoupCookieJarAcceptPolicy accept_policy;
73 } SoupCookieJarPrivate;
74 #define SOUP_COOKIE_JAR_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), SOUP_TYPE_COOKIE_JAR, SoupCookieJarPrivate))
76 static void set_property (GObject *object, guint prop_id,
77 const GValue *value, GParamSpec *pspec);
78 static void get_property (GObject *object, guint prop_id,
79 GValue *value, GParamSpec *pspec);
82 soup_cookie_jar_init (SoupCookieJar *jar)
84 SoupCookieJarPrivate *priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
86 priv->domains = g_hash_table_new_full (soup_str_case_hash,
89 priv->serials = g_hash_table_new (NULL, NULL);
90 priv->accept_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
94 constructed (GObject *object)
96 SoupCookieJarPrivate *priv = SOUP_COOKIE_JAR_GET_PRIVATE (object);
98 priv->constructed = TRUE;
102 finalize (GObject *object)
104 SoupCookieJarPrivate *priv = SOUP_COOKIE_JAR_GET_PRIVATE (object);
108 g_hash_table_iter_init (&iter, priv->domains);
109 while (g_hash_table_iter_next (&iter, &key, &value))
110 soup_cookies_free (value);
111 g_hash_table_destroy (priv->domains);
112 g_hash_table_destroy (priv->serials);
114 G_OBJECT_CLASS (soup_cookie_jar_parent_class)->finalize (object);
118 soup_cookie_jar_class_init (SoupCookieJarClass *jar_class)
120 GObjectClass *object_class = G_OBJECT_CLASS (jar_class);
122 g_type_class_add_private (jar_class, sizeof (SoupCookieJarPrivate));
124 object_class->constructed = constructed;
125 object_class->finalize = finalize;
126 object_class->set_property = set_property;
127 object_class->get_property = get_property;
129 jar_class->is_persistent = is_persistent;
132 * SoupCookieJar::changed:
133 * @jar: the #SoupCookieJar
134 * @old_cookie: the old #SoupCookie value
135 * @new_cookie: the new #SoupCookie value
137 * Emitted when @jar changes. If a cookie has been added,
138 * @new_cookie will contain the newly-added cookie and
139 * @old_cookie will be %NULL. If a cookie has been deleted,
140 * @old_cookie will contain the to-be-deleted cookie and
141 * @new_cookie will be %NULL. If a cookie has been changed,
142 * @old_cookie will contain its old value, and @new_cookie its
146 g_signal_new ("changed",
147 G_OBJECT_CLASS_TYPE (object_class),
149 G_STRUCT_OFFSET (SoupCookieJarClass, changed),
151 _soup_marshal_NONE__BOXED_BOXED,
153 SOUP_TYPE_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE,
154 SOUP_TYPE_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE);
157 * SOUP_COOKIE_JAR_READ_ONLY:
159 * Alias for the #SoupCookieJar:read-only property. (Whether
160 * or not the cookie jar is read-only.)
162 g_object_class_install_property (
163 object_class, PROP_READ_ONLY,
164 g_param_spec_boolean (SOUP_COOKIE_JAR_READ_ONLY,
166 "Whether or not the cookie jar is read-only",
168 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
171 * SOUP_COOKIE_JAR_ACCEPT_POLICY:
173 * Alias for the #SoupCookieJar:accept-policy property.
178 * SoupCookieJar:accept-policy:
180 * The policy the jar should follow to accept or reject cookies
184 g_object_class_install_property (
185 object_class, PROP_ACCEPT_POLICY,
186 g_param_spec_enum (SOUP_COOKIE_JAR_ACCEPT_POLICY,
188 "The policy the jar should follow to accept or reject cookies",
189 SOUP_TYPE_COOKIE_JAR_ACCEPT_POLICY,
190 SOUP_COOKIE_JAR_ACCEPT_ALWAYS,
195 soup_cookie_jar_session_feature_init (SoupSessionFeatureInterface *feature_interface,
196 gpointer interface_data)
198 feature_interface->request_queued = request_queued;
199 feature_interface->request_started = request_started;
200 feature_interface->request_unqueued = request_unqueued;
204 set_property (GObject *object, guint prop_id,
205 const GValue *value, GParamSpec *pspec)
207 SoupCookieJarPrivate *priv =
208 SOUP_COOKIE_JAR_GET_PRIVATE (object);
212 priv->read_only = g_value_get_boolean (value);
214 case PROP_ACCEPT_POLICY:
215 priv->accept_policy = g_value_get_enum (value);
218 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
224 get_property (GObject *object, guint prop_id,
225 GValue *value, GParamSpec *pspec)
227 SoupCookieJarPrivate *priv =
228 SOUP_COOKIE_JAR_GET_PRIVATE (object);
232 g_value_set_boolean (value, priv->read_only);
234 case PROP_ACCEPT_POLICY:
235 g_value_set_enum (value, priv->accept_policy);
238 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
244 * soup_cookie_jar_new:
246 * Creates a new #SoupCookieJar. The base #SoupCookieJar class does
247 * not support persistent storage of cookies; use a subclass for that.
249 * Returns: a new #SoupCookieJar
254 soup_cookie_jar_new (void)
256 return g_object_new (SOUP_TYPE_COOKIE_JAR, NULL);
260 * soup_cookie_jar_save:
261 * @jar: a #SoupCookieJar
263 * This function exists for backward compatibility, but does not do
264 * anything any more; cookie jars are saved automatically when they
268 soup_cookie_jar_save (SoupCookieJar *jar)
270 /* Does nothing, obsolete */
274 is_persistent (SoupCookieJar *jar)
280 soup_cookie_jar_changed (SoupCookieJar *jar,
281 SoupCookie *old, SoupCookie *new)
283 SoupCookieJarPrivate *priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
285 if (old && old != new)
286 g_hash_table_remove (priv->serials, old);
289 g_hash_table_insert (priv->serials, new, GUINT_TO_POINTER (priv->serial));
292 if (priv->read_only || !priv->constructed)
295 g_signal_emit (jar, signals[CHANGED], 0, old, new);
299 compare_cookies (gconstpointer a, gconstpointer b, gpointer jar)
301 SoupCookie *ca = (SoupCookie *)a;
302 SoupCookie *cb = (SoupCookie *)b;
303 SoupCookieJarPrivate *priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
305 guint aserial, bserial;
307 /* "Cookies with longer path fields are listed before cookies
308 * with shorter path field."
310 alen = ca->path ? strlen (ca->path) : 0;
311 blen = cb->path ? strlen (cb->path) : 0;
315 /* "Among cookies that have equal length path fields, cookies
316 * with earlier creation dates are listed before cookies with
317 * later creation dates."
319 aserial = GPOINTER_TO_UINT (g_hash_table_lookup (priv->serials, ca));
320 bserial = GPOINTER_TO_UINT (g_hash_table_lookup (priv->serials, cb));
321 return aserial - bserial;
325 get_cookies (SoupCookieJar *jar, SoupURI *uri, gboolean for_http, gboolean copy_cookies)
327 SoupCookieJarPrivate *priv;
328 GSList *cookies, *domain_cookies;
329 char *domain, *cur, *next_domain;
330 GSList *new_head, *cookies_to_remove = NULL, *p;
332 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
337 /* The logic here is a little weird, but the plan is that if
338 * uri->host is "www.foo.com", we will end up looking up
339 * cookies for ".www.foo.com", "www.foo.com", ".foo.com", and
340 * ".com", in that order. (Logic stolen from Mozilla.)
343 domain = cur = g_strdup_printf (".%s", uri->host);
344 next_domain = domain + 1;
346 new_head = domain_cookies = g_hash_table_lookup (priv->domains, cur);
347 while (domain_cookies) {
348 GSList *next = domain_cookies->next;
349 SoupCookie *cookie = domain_cookies->data;
351 if (cookie->expires && soup_date_is_past (cookie->expires)) {
352 cookies_to_remove = g_slist_append (cookies_to_remove,
354 new_head = g_slist_delete_link (new_head, domain_cookies);
355 g_hash_table_insert (priv->domains,
358 } else if (soup_cookie_applies_to_uri (cookie, uri) &&
359 (for_http || !cookie->http_only))
360 cookies = g_slist_append (cookies, copy_cookies ? soup_cookie_copy (cookie) : cookie);
362 domain_cookies = next;
366 next_domain = strchr (cur + 1, '.');
370 for (p = cookies_to_remove; p; p = p->next) {
371 SoupCookie *cookie = p->data;
373 soup_cookie_jar_changed (jar, cookie, NULL);
374 soup_cookie_free (cookie);
376 g_slist_free (cookies_to_remove);
378 return g_slist_sort_with_data (cookies, compare_cookies, jar);
382 * soup_cookie_jar_get_cookies:
383 * @jar: a #SoupCookieJar
385 * @for_http: whether or not the return value is being passed directly
386 * to an HTTP operation
388 * Retrieves (in Cookie-header form) the list of cookies that would
389 * be sent with a request to @uri.
391 * If @for_http is %TRUE, the return value will include cookies marked
392 * "HttpOnly" (that is, cookies that the server wishes to keep hidden
393 * from client-side scripting operations such as the JavaScript
394 * document.cookies property). Since #SoupCookieJar sets the Cookie
395 * header itself when making the actual HTTP request, you should
396 * almost certainly be setting @for_http to %FALSE if you are calling
399 * Return value: the cookies, in string form, or %NULL if there are no
405 soup_cookie_jar_get_cookies (SoupCookieJar *jar, SoupURI *uri,
410 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), NULL);
411 g_return_val_if_fail (uri != NULL, NULL);
413 cookies = get_cookies (jar, uri, for_http, FALSE);
416 char *result = soup_cookies_to_cookie_header (cookies);
417 g_slist_free (cookies);
429 * soup_cookie_jar_get_cookie_list:
430 * @jar: a #SoupCookieJar
432 * @for_http: whether or not the return value is being passed directly
433 * to an HTTP operation
435 * Retrieves the list of cookies that would be sent with a request to @uri
436 * as a #GSList of #SoupCookie objects.
438 * If @for_http is %TRUE, the return value will include cookies marked
439 * "HttpOnly" (that is, cookies that the server wishes to keep hidden
440 * from client-side scripting operations such as the JavaScript
441 * document.cookies property). Since #SoupCookieJar sets the Cookie
442 * header itself when making the actual HTTP request, you should
443 * almost certainly be setting @for_http to %FALSE if you are calling
446 * Return value: (transfer full) (element-type Soup.Cookie): a #GSList
447 * with the cookies in the @jar that would be sent with a request to @uri.
452 soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, SoupURI *uri, gboolean for_http)
454 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), NULL);
455 g_return_val_if_fail (uri != NULL, NULL);
457 return get_cookies (jar, uri, for_http, TRUE);
461 * soup_cookie_jar_add_cookie:
462 * @jar: a #SoupCookieJar
463 * @cookie: a #SoupCookie
465 * Adds @cookie to @jar, emitting the 'changed' signal if we are modifying
466 * an existing cookie or adding a valid new cookie ('valid' means
467 * that the cookie's expire date is not in the past).
469 * @cookie will be 'stolen' by the jar, so don't free it afterwards.
474 soup_cookie_jar_add_cookie (SoupCookieJar *jar, SoupCookie *cookie)
476 SoupCookieJarPrivate *priv;
477 GSList *old_cookies, *oc, *last = NULL;
478 SoupCookie *old_cookie;
480 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
481 g_return_if_fail (cookie != NULL);
483 /* Never accept cookies for public domains. */
484 if (!g_hostname_is_ip_address (cookie->domain) &&
485 soup_tld_domain_is_public_suffix (cookie->domain)) {
486 soup_cookie_free (cookie);
490 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
491 old_cookies = g_hash_table_lookup (priv->domains, cookie->domain);
492 for (oc = old_cookies; oc; oc = oc->next) {
493 old_cookie = oc->data;
494 if (!strcmp (cookie->name, old_cookie->name) &&
495 !g_strcmp0 (cookie->path, old_cookie->path)) {
496 if (cookie->expires && soup_date_is_past (cookie->expires)) {
497 /* The new cookie has an expired date,
498 * this is the way the the server has
499 * of telling us that we have to
502 old_cookies = g_slist_delete_link (old_cookies, oc);
503 g_hash_table_insert (priv->domains,
504 g_strdup (cookie->domain),
506 soup_cookie_jar_changed (jar, old_cookie, NULL);
507 soup_cookie_free (old_cookie);
508 soup_cookie_free (cookie);
511 soup_cookie_jar_changed (jar, old_cookie, cookie);
512 soup_cookie_free (old_cookie);
520 /* The new cookie is... a new cookie */
521 if (cookie->expires && soup_date_is_past (cookie->expires)) {
522 soup_cookie_free (cookie);
527 last->next = g_slist_append (NULL, cookie);
529 old_cookies = g_slist_append (NULL, cookie);
530 g_hash_table_insert (priv->domains, g_strdup (cookie->domain),
534 soup_cookie_jar_changed (jar, NULL, cookie);
538 * soup_cookie_jar_add_cookie_with_first_party:
539 * @jar: a #SoupCookieJar
540 * @first_party: the URI for the main document
541 * @cookie: a #SoupCookie
543 * Adds @cookie to @jar, emitting the 'changed' signal if we are modifying
544 * an existing cookie or adding a valid new cookie ('valid' means
545 * that the cookie's expire date is not in the past).
547 * @first_party will be used to reject cookies coming from third party
548 * resources in case such a security policy is set in the @jar.
550 * @cookie will be 'stolen' by the jar, so don't free it afterwards.
555 soup_cookie_jar_add_cookie_with_first_party (SoupCookieJar *jar, SoupURI *first_party, SoupCookie *cookie)
557 SoupCookieJarPrivate *priv;
559 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
560 g_return_if_fail (first_party != NULL);
561 g_return_if_fail (cookie != NULL);
563 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
564 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER) {
565 soup_cookie_free (cookie);
569 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS ||
570 soup_cookie_domain_matches (cookie, first_party->host)) {
571 /* will steal or free soup_cookie */
572 soup_cookie_jar_add_cookie (jar, cookie);
574 soup_cookie_free (cookie);
579 * soup_cookie_jar_set_cookie:
580 * @jar: a #SoupCookieJar
581 * @uri: the URI setting the cookie
582 * @cookie: the stringified cookie to set
584 * Adds @cookie to @jar, exactly as though it had appeared in a
585 * Set-Cookie header returned from a request to @uri.
587 * Keep in mind that if the #SoupCookieJarAcceptPolicy
588 * %SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY is set you'll need to use
589 * soup_cookie_jar_set_cookie_with_first_party(), otherwise the jar
590 * will have no way of knowing if the cookie is being set by a third
596 soup_cookie_jar_set_cookie (SoupCookieJar *jar, SoupURI *uri,
599 SoupCookie *soup_cookie;
600 SoupCookieJarPrivate *priv;
602 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
603 g_return_if_fail (uri != NULL);
604 g_return_if_fail (cookie != NULL);
609 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
610 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
613 g_return_if_fail (priv->accept_policy != SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY);
615 soup_cookie = soup_cookie_parse (cookie, uri);
617 /* will steal or free soup_cookie */
618 soup_cookie_jar_add_cookie (jar, soup_cookie);
623 * soup_cookie_jar_set_cookie_with_first_party:
624 * @jar: a #SoupCookieJar
625 * @uri: the URI setting the cookie
626 * @first_party: the URI for the main document
627 * @cookie: the stringified cookie to set
629 * Adds @cookie to @jar, exactly as though it had appeared in a
630 * Set-Cookie header returned from a request to @uri. @first_party
631 * will be used to reject cookies coming from third party resources in
632 * case such a security policy is set in the @jar.
637 soup_cookie_jar_set_cookie_with_first_party (SoupCookieJar *jar,
639 SoupURI *first_party,
642 SoupCookie *soup_cookie;
644 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
645 g_return_if_fail (uri != NULL);
646 g_return_if_fail (first_party != NULL);
647 g_return_if_fail (cookie != NULL);
652 soup_cookie = soup_cookie_parse (cookie, uri);
654 soup_cookie_jar_add_cookie_with_first_party (jar, first_party, soup_cookie);
658 process_set_cookie_header (SoupMessage *msg, gpointer user_data)
660 SoupCookieJar *jar = user_data;
661 SoupCookieJarPrivate *priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
662 GSList *new_cookies, *nc;
664 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
667 new_cookies = soup_cookies_from_response (msg);
668 for (nc = new_cookies; nc; nc = nc->next) {
669 SoupURI *first_party = soup_message_get_first_party (msg);
671 if ((priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY &&
672 first_party != NULL && first_party->host &&
673 soup_cookie_domain_matches (nc->data, first_party->host)) ||
674 priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS)
675 soup_cookie_jar_add_cookie (jar, nc->data);
677 soup_cookie_free (nc->data);
679 g_slist_free (new_cookies);
683 request_queued (SoupSessionFeature *feature, SoupSession *session,
686 soup_message_add_header_handler (msg, "got-headers",
688 G_CALLBACK (process_set_cookie_header),
693 request_started (SoupSessionFeature *feature, SoupSession *session,
694 SoupMessage *msg, SoupSocket *socket)
696 SoupCookieJar *jar = SOUP_COOKIE_JAR (feature);
699 cookies = soup_cookie_jar_get_cookies (jar, soup_message_get_uri (msg), TRUE);
701 soup_message_headers_replace (msg->request_headers,
705 soup_message_headers_remove (msg->request_headers, "Cookie");
709 request_unqueued (SoupSessionFeature *feature, SoupSession *session,
712 g_signal_handlers_disconnect_by_func (msg, process_set_cookie_header, feature);
716 * soup_cookie_jar_all_cookies:
717 * @jar: a #SoupCookieJar
719 * Constructs a #GSList with every cookie inside the @jar.
720 * The cookies in the list are a copy of the original, so
721 * you have to free them when you are done with them.
723 * Return value: (transfer full) (element-type Soup.Cookie): a #GSList
724 * with all the cookies in the @jar.
729 soup_cookie_jar_all_cookies (SoupCookieJar *jar)
731 SoupCookieJarPrivate *priv;
736 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), NULL);
738 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
740 g_hash_table_iter_init (&iter, priv->domains);
742 while (g_hash_table_iter_next (&iter, &key, &value)) {
743 GSList *p, *cookies = value;
744 for (p = cookies; p; p = p->next)
745 l = g_slist_prepend (l, soup_cookie_copy (p->data));
752 * soup_cookie_jar_delete_cookie:
753 * @jar: a #SoupCookieJar
754 * @cookie: a #SoupCookie
756 * Deletes @cookie from @jar, emitting the 'changed' signal.
761 soup_cookie_jar_delete_cookie (SoupCookieJar *jar,
764 SoupCookieJarPrivate *priv;
768 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
769 g_return_if_fail (cookie != NULL);
771 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
773 domain = g_strdup (cookie->domain);
775 cookies = g_hash_table_lookup (priv->domains, domain);
779 for (p = cookies; p; p = p->next ) {
780 SoupCookie *c = (SoupCookie*)p->data;
781 if (soup_cookie_equal (cookie, c)) {
782 cookies = g_slist_delete_link (cookies, p);
783 g_hash_table_insert (priv->domains,
786 soup_cookie_jar_changed (jar, c, NULL);
787 soup_cookie_free (c);
794 * SoupCookieJarAcceptPolicy:
795 * @SOUP_COOKIE_JAR_ACCEPT_ALWAYS: accept all cookies unconditionally.
796 * @SOUP_COOKIE_JAR_ACCEPT_NEVER: reject all cookies unconditionally.
797 * @SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY: accept all cookies set by
798 * the main document loaded in the application using libsoup. An
799 * example of the most common case, web browsers, would be: If
800 * http://www.example.com is the page loaded, accept all cookies set
801 * by example.com, but if a resource from http://www.third-party.com
802 * is loaded from that page reject any cookie that it could try to
803 * set. For libsoup to be able to tell apart first party cookies from
804 * the rest, the application must call soup_message_set_first_party()
805 * on each outgoing #SoupMessage, setting the #SoupURI of the main
806 * document. If no first party is set in a message when this policy is
807 * in effect, cookies will be assumed to be third party by default.
813 * soup_cookie_jar_get_accept_policy:
814 * @jar: a #SoupCookieJar
816 * Gets @jar's #SoupCookieJarAcceptPolicy
818 * Returns: the #SoupCookieJarAcceptPolicy set in the @jar
822 SoupCookieJarAcceptPolicy
823 soup_cookie_jar_get_accept_policy (SoupCookieJar *jar)
825 SoupCookieJarPrivate *priv;
827 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), SOUP_COOKIE_JAR_ACCEPT_ALWAYS);
829 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
830 return priv->accept_policy;
834 * soup_cookie_jar_set_accept_policy:
835 * @jar: a #SoupCookieJar
836 * @policy: a #SoupCookieJarAcceptPolicy
838 * Sets @policy as the cookie acceptance policy for @jar.
843 soup_cookie_jar_set_accept_policy (SoupCookieJar *jar,
844 SoupCookieJarAcceptPolicy policy)
846 SoupCookieJarPrivate *priv;
848 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
850 priv = SOUP_COOKIE_JAR_GET_PRIVATE (jar);
852 if (priv->accept_policy != policy) {
853 priv->accept_policy = policy;
854 g_object_notify (G_OBJECT (jar), SOUP_COOKIE_JAR_ACCEPT_POLICY);
859 * soup_cookie_jar_is_persistent:
860 * @jar: a #SoupCookieJar
862 * Gets whether @jar stores cookies persistenly.
864 * Returns: %TRUE if @jar storage is persistent or %FALSE otherwise.
869 soup_cookie_jar_is_persistent (SoupCookieJar *jar)
871 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), FALSE);
873 return SOUP_COOKIE_JAR_GET_CLASS (jar)->is_persistent (jar);