1 /* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
5 * Copyright (C) 2008 Red Hat, Inc.
14 #include "soup-cookie-jar.h"
15 #include "soup-misc-private.h"
19 * SECTION:soup-cookie-jar
20 * @short_description: Automatic cookie handling for SoupSession
22 * A #SoupCookieJar stores #SoupCookie<!-- -->s and arrange for them
23 * to be sent with the appropriate #SoupMessage<!-- -->s.
24 * #SoupCookieJar implements #SoupSessionFeature, so you can add a
25 * cookie jar to a session with soup_session_add_feature() or
26 * soup_session_add_feature_by_type().
28 * Note that the base #SoupCookieJar class does not support any form
29 * of long-term cookie persistence.
37 static guint signals[LAST_SIGNAL] = { 0 };
49 gboolean constructed, read_only;
50 GHashTable *domains, *serials;
52 SoupCookieJarAcceptPolicy accept_policy;
53 } SoupCookieJarPrivate;
55 static void soup_cookie_jar_session_feature_init (SoupSessionFeatureInterface *feature_interface, gpointer interface_data);
57 G_DEFINE_TYPE_WITH_CODE (SoupCookieJar, soup_cookie_jar, G_TYPE_OBJECT,
58 G_ADD_PRIVATE (SoupCookieJar)
59 G_IMPLEMENT_INTERFACE (SOUP_TYPE_SESSION_FEATURE,
60 soup_cookie_jar_session_feature_init))
63 soup_cookie_jar_init (SoupCookieJar *jar)
65 SoupCookieJarPrivate *priv = soup_cookie_jar_get_instance_private (jar);
67 priv->domains = g_hash_table_new_full (soup_str_case_hash,
70 priv->serials = g_hash_table_new (NULL, NULL);
71 priv->accept_policy = SOUP_COOKIE_JAR_ACCEPT_ALWAYS;
75 soup_cookie_jar_constructed (GObject *object)
77 SoupCookieJarPrivate *priv =
78 soup_cookie_jar_get_instance_private (SOUP_COOKIE_JAR (object));
80 priv->constructed = TRUE;
84 soup_cookie_jar_finalize (GObject *object)
86 SoupCookieJarPrivate *priv =
87 soup_cookie_jar_get_instance_private (SOUP_COOKIE_JAR (object));
91 g_hash_table_iter_init (&iter, priv->domains);
92 while (g_hash_table_iter_next (&iter, &key, &value))
93 soup_cookies_free (value);
94 g_hash_table_destroy (priv->domains);
95 g_hash_table_destroy (priv->serials);
97 G_OBJECT_CLASS (soup_cookie_jar_parent_class)->finalize (object);
101 soup_cookie_jar_set_property (GObject *object, guint prop_id,
102 const GValue *value, GParamSpec *pspec)
104 SoupCookieJarPrivate *priv =
105 soup_cookie_jar_get_instance_private (SOUP_COOKIE_JAR (object));
109 priv->read_only = g_value_get_boolean (value);
111 case PROP_ACCEPT_POLICY:
112 priv->accept_policy = g_value_get_enum (value);
115 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
121 soup_cookie_jar_get_property (GObject *object, guint prop_id,
122 GValue *value, GParamSpec *pspec)
124 SoupCookieJarPrivate *priv =
125 soup_cookie_jar_get_instance_private (SOUP_COOKIE_JAR (object));
129 g_value_set_boolean (value, priv->read_only);
131 case PROP_ACCEPT_POLICY:
132 g_value_set_enum (value, priv->accept_policy);
135 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
141 soup_cookie_jar_real_is_persistent (SoupCookieJar *jar)
147 soup_cookie_jar_class_init (SoupCookieJarClass *jar_class)
149 GObjectClass *object_class = G_OBJECT_CLASS (jar_class);
151 object_class->constructed = soup_cookie_jar_constructed;
152 object_class->finalize = soup_cookie_jar_finalize;
153 object_class->set_property = soup_cookie_jar_set_property;
154 object_class->get_property = soup_cookie_jar_get_property;
156 jar_class->is_persistent = soup_cookie_jar_real_is_persistent;
159 * SoupCookieJar::changed:
160 * @jar: the #SoupCookieJar
161 * @old_cookie: the old #SoupCookie value
162 * @new_cookie: the new #SoupCookie value
164 * Emitted when @jar changes. If a cookie has been added,
165 * @new_cookie will contain the newly-added cookie and
166 * @old_cookie will be %NULL. If a cookie has been deleted,
167 * @old_cookie will contain the to-be-deleted cookie and
168 * @new_cookie will be %NULL. If a cookie has been changed,
169 * @old_cookie will contain its old value, and @new_cookie its
173 g_signal_new ("changed",
174 G_OBJECT_CLASS_TYPE (object_class),
176 G_STRUCT_OFFSET (SoupCookieJarClass, changed),
180 SOUP_TYPE_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE,
181 SOUP_TYPE_COOKIE | G_SIGNAL_TYPE_STATIC_SCOPE);
184 * SOUP_COOKIE_JAR_READ_ONLY:
186 * Alias for the #SoupCookieJar:read-only property. (Whether
187 * or not the cookie jar is read-only.)
189 g_object_class_install_property (
190 object_class, PROP_READ_ONLY,
191 g_param_spec_boolean (SOUP_COOKIE_JAR_READ_ONLY,
193 "Whether or not the cookie jar is read-only",
195 G_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
198 * SOUP_COOKIE_JAR_ACCEPT_POLICY:
200 * Alias for the #SoupCookieJar:accept-policy property.
205 * SoupCookieJar:accept-policy:
207 * The policy the jar should follow to accept or reject cookies
211 g_object_class_install_property (
212 object_class, PROP_ACCEPT_POLICY,
213 g_param_spec_enum (SOUP_COOKIE_JAR_ACCEPT_POLICY,
215 "The policy the jar should follow to accept or reject cookies",
216 SOUP_TYPE_COOKIE_JAR_ACCEPT_POLICY,
217 SOUP_COOKIE_JAR_ACCEPT_ALWAYS,
222 * soup_cookie_jar_new:
224 * Creates a new #SoupCookieJar. The base #SoupCookieJar class does
225 * not support persistent storage of cookies; use a subclass for that.
227 * Returns: a new #SoupCookieJar
232 soup_cookie_jar_new (void)
234 return g_object_new (SOUP_TYPE_COOKIE_JAR, NULL);
238 * soup_cookie_jar_save:
239 * @jar: a #SoupCookieJar
241 * This function exists for backward compatibility, but does not do
242 * anything any more; cookie jars are saved automatically when they
247 * Deprecated: This is a no-op.
250 soup_cookie_jar_save (SoupCookieJar *jar)
252 /* Does nothing, obsolete */
256 soup_cookie_jar_changed (SoupCookieJar *jar,
257 SoupCookie *old, SoupCookie *new)
259 SoupCookieJarPrivate *priv = soup_cookie_jar_get_instance_private (jar);
261 if (old && old != new)
262 g_hash_table_remove (priv->serials, old);
265 g_hash_table_insert (priv->serials, new, GUINT_TO_POINTER (priv->serial));
268 if (priv->read_only || !priv->constructed)
271 g_signal_emit (jar, signals[CHANGED], 0, old, new);
275 compare_cookies (gconstpointer a, gconstpointer b, gpointer jar)
277 SoupCookie *ca = (SoupCookie *)a;
278 SoupCookie *cb = (SoupCookie *)b;
279 SoupCookieJarPrivate *priv = soup_cookie_jar_get_instance_private (jar);
281 guint aserial, bserial;
283 /* "Cookies with longer path fields are listed before cookies
284 * with shorter path field."
286 alen = ca->path ? strlen (ca->path) : 0;
287 blen = cb->path ? strlen (cb->path) : 0;
291 /* "Among cookies that have equal length path fields, cookies
292 * with earlier creation dates are listed before cookies with
293 * later creation dates."
295 aserial = GPOINTER_TO_UINT (g_hash_table_lookup (priv->serials, ca));
296 bserial = GPOINTER_TO_UINT (g_hash_table_lookup (priv->serials, cb));
297 return aserial - bserial;
301 get_cookies (SoupCookieJar *jar, SoupURI *uri, gboolean for_http, gboolean copy_cookies)
303 SoupCookieJarPrivate *priv;
304 GSList *cookies, *domain_cookies;
305 char *domain, *cur, *next_domain;
306 GSList *new_head, *cookies_to_remove = NULL, *p;
308 priv = soup_cookie_jar_get_instance_private (jar);
313 /* The logic here is a little weird, but the plan is that if
314 * uri->host is "www.foo.com", we will end up looking up
315 * cookies for ".www.foo.com", "www.foo.com", ".foo.com", and
316 * ".com", in that order. (Logic stolen from Mozilla.)
319 domain = cur = g_strdup_printf (".%s", uri->host);
320 next_domain = domain + 1;
322 new_head = domain_cookies = g_hash_table_lookup (priv->domains, cur);
323 while (domain_cookies) {
324 GSList *next = domain_cookies->next;
325 SoupCookie *cookie = domain_cookies->data;
327 if (cookie->expires && soup_date_is_past (cookie->expires)) {
328 cookies_to_remove = g_slist_append (cookies_to_remove,
330 new_head = g_slist_delete_link (new_head, domain_cookies);
331 g_hash_table_insert (priv->domains,
334 } else if (soup_cookie_applies_to_uri (cookie, uri) &&
335 (for_http || !cookie->http_only))
336 cookies = g_slist_append (cookies, copy_cookies ? soup_cookie_copy (cookie) : cookie);
338 domain_cookies = next;
342 next_domain = strchr (cur + 1, '.');
346 for (p = cookies_to_remove; p; p = p->next) {
347 SoupCookie *cookie = p->data;
349 soup_cookie_jar_changed (jar, cookie, NULL);
350 soup_cookie_free (cookie);
352 g_slist_free (cookies_to_remove);
354 return g_slist_sort_with_data (cookies, compare_cookies, jar);
358 * soup_cookie_jar_get_cookies:
359 * @jar: a #SoupCookieJar
361 * @for_http: whether or not the return value is being passed directly
362 * to an HTTP operation
364 * Retrieves (in Cookie-header form) the list of cookies that would
365 * be sent with a request to @uri.
367 * If @for_http is %TRUE, the return value will include cookies marked
368 * "HttpOnly" (that is, cookies that the server wishes to keep hidden
369 * from client-side scripting operations such as the JavaScript
370 * document.cookies property). Since #SoupCookieJar sets the Cookie
371 * header itself when making the actual HTTP request, you should
372 * almost certainly be setting @for_http to %FALSE if you are calling
375 * Return value: (nullable): the cookies, in string form, or %NULL if
376 * there are no cookies for @uri.
381 soup_cookie_jar_get_cookies (SoupCookieJar *jar, SoupURI *uri,
386 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), NULL);
387 g_return_val_if_fail (uri != NULL, NULL);
389 cookies = get_cookies (jar, uri, for_http, FALSE);
392 char *result = soup_cookies_to_cookie_header (cookies);
393 g_slist_free (cookies);
405 * soup_cookie_jar_get_cookie_list:
406 * @jar: a #SoupCookieJar
408 * @for_http: whether or not the return value is being passed directly
409 * to an HTTP operation
411 * Retrieves the list of cookies that would be sent with a request to @uri
412 * as a #GSList of #SoupCookie objects.
414 * If @for_http is %TRUE, the return value will include cookies marked
415 * "HttpOnly" (that is, cookies that the server wishes to keep hidden
416 * from client-side scripting operations such as the JavaScript
417 * document.cookies property). Since #SoupCookieJar sets the Cookie
418 * header itself when making the actual HTTP request, you should
419 * almost certainly be setting @for_http to %FALSE if you are calling
422 * Return value: (transfer full) (element-type Soup.Cookie): a #GSList
423 * with the cookies in the @jar that would be sent with a request to @uri.
428 soup_cookie_jar_get_cookie_list (SoupCookieJar *jar, SoupURI *uri, gboolean for_http)
430 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), NULL);
431 g_return_val_if_fail (uri != NULL, NULL);
433 return get_cookies (jar, uri, for_http, TRUE);
437 * soup_cookie_jar_add_cookie:
438 * @jar: a #SoupCookieJar
439 * @cookie: (transfer full): a #SoupCookie
441 * Adds @cookie to @jar, emitting the 'changed' signal if we are modifying
442 * an existing cookie or adding a valid new cookie ('valid' means
443 * that the cookie's expire date is not in the past).
445 * @cookie will be 'stolen' by the jar, so don't free it afterwards.
450 soup_cookie_jar_add_cookie (SoupCookieJar *jar, SoupCookie *cookie)
452 SoupCookieJarPrivate *priv;
453 GSList *old_cookies, *oc, *last = NULL;
454 SoupCookie *old_cookie;
456 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
457 g_return_if_fail (cookie != NULL);
459 /* Never accept cookies for public domains. */
460 if (!g_hostname_is_ip_address (cookie->domain) &&
461 soup_tld_domain_is_public_suffix (cookie->domain)) {
462 soup_cookie_free (cookie);
466 priv = soup_cookie_jar_get_instance_private (jar);
467 old_cookies = g_hash_table_lookup (priv->domains, cookie->domain);
468 for (oc = old_cookies; oc; oc = oc->next) {
469 old_cookie = oc->data;
470 if (!strcmp (cookie->name, old_cookie->name) &&
471 !g_strcmp0 (cookie->path, old_cookie->path)) {
472 if (cookie->expires && soup_date_is_past (cookie->expires)) {
473 /* The new cookie has an expired date,
474 * this is the way the the server has
475 * of telling us that we have to
478 old_cookies = g_slist_delete_link (old_cookies, oc);
479 g_hash_table_insert (priv->domains,
480 g_strdup (cookie->domain),
482 soup_cookie_jar_changed (jar, old_cookie, NULL);
483 soup_cookie_free (old_cookie);
484 soup_cookie_free (cookie);
487 soup_cookie_jar_changed (jar, old_cookie, cookie);
488 soup_cookie_free (old_cookie);
496 /* The new cookie is... a new cookie */
497 if (cookie->expires && soup_date_is_past (cookie->expires)) {
498 soup_cookie_free (cookie);
503 last->next = g_slist_append (NULL, cookie);
505 old_cookies = g_slist_append (NULL, cookie);
506 g_hash_table_insert (priv->domains, g_strdup (cookie->domain),
510 soup_cookie_jar_changed (jar, NULL, cookie);
514 normalize_cookie_domain (const char *domain)
516 /* Trim any leading dot if present to transform the cookie
517 * domain into a valid hostname.
519 if (domain != NULL && domain[0] == '.')
525 incoming_cookie_is_third_party (SoupCookie *cookie, SoupURI *first_party)
527 const char *normalized_cookie_domain;
528 const char *cookie_base_domain;
529 const char *first_party_base_domain;
531 if (first_party == NULL || first_party->host == NULL)
534 normalized_cookie_domain = normalize_cookie_domain (cookie->domain);
535 cookie_base_domain = soup_tld_get_base_domain (normalized_cookie_domain, NULL);
536 if (cookie_base_domain == NULL)
537 cookie_base_domain = cookie->domain;
539 first_party_base_domain = soup_tld_get_base_domain (first_party->host, NULL);
540 if (first_party_base_domain == NULL)
541 first_party_base_domain = first_party->host;
542 return !soup_host_matches_host (cookie_base_domain, first_party_base_domain);
546 * soup_cookie_jar_add_cookie_with_first_party:
547 * @jar: a #SoupCookieJar
548 * @first_party: the URI for the main document
549 * @cookie: (transfer full): a #SoupCookie
551 * Adds @cookie to @jar, emitting the 'changed' signal if we are modifying
552 * an existing cookie or adding a valid new cookie ('valid' means
553 * that the cookie's expire date is not in the past).
555 * @first_party will be used to reject cookies coming from third party
556 * resources in case such a security policy is set in the @jar.
558 * @cookie will be 'stolen' by the jar, so don't free it afterwards.
563 soup_cookie_jar_add_cookie_with_first_party (SoupCookieJar *jar, SoupURI *first_party, SoupCookie *cookie)
565 SoupCookieJarPrivate *priv;
567 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
568 g_return_if_fail (first_party != NULL);
569 g_return_if_fail (cookie != NULL);
571 priv = soup_cookie_jar_get_instance_private (jar);
572 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER) {
573 soup_cookie_free (cookie);
577 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS ||
578 !incoming_cookie_is_third_party (cookie, first_party)) {
579 /* will steal or free soup_cookie */
580 soup_cookie_jar_add_cookie (jar, cookie);
582 soup_cookie_free (cookie);
587 * soup_cookie_jar_set_cookie:
588 * @jar: a #SoupCookieJar
589 * @uri: the URI setting the cookie
590 * @cookie: the stringified cookie to set
592 * Adds @cookie to @jar, exactly as though it had appeared in a
593 * Set-Cookie header returned from a request to @uri.
595 * Keep in mind that if the #SoupCookieJarAcceptPolicy
596 * %SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY is set you'll need to use
597 * soup_cookie_jar_set_cookie_with_first_party(), otherwise the jar
598 * will have no way of knowing if the cookie is being set by a third
604 soup_cookie_jar_set_cookie (SoupCookieJar *jar, SoupURI *uri,
607 SoupCookie *soup_cookie;
608 SoupCookieJarPrivate *priv;
610 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
611 g_return_if_fail (uri != NULL);
612 g_return_if_fail (cookie != NULL);
617 priv = soup_cookie_jar_get_instance_private (jar);
618 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
621 g_return_if_fail (priv->accept_policy != SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY);
623 soup_cookie = soup_cookie_parse (cookie, uri);
625 /* will steal or free soup_cookie */
626 soup_cookie_jar_add_cookie (jar, soup_cookie);
631 * soup_cookie_jar_set_cookie_with_first_party:
632 * @jar: a #SoupCookieJar
633 * @uri: the URI setting the cookie
634 * @first_party: the URI for the main document
635 * @cookie: the stringified cookie to set
637 * Adds @cookie to @jar, exactly as though it had appeared in a
638 * Set-Cookie header returned from a request to @uri. @first_party
639 * will be used to reject cookies coming from third party resources in
640 * case such a security policy is set in the @jar.
645 soup_cookie_jar_set_cookie_with_first_party (SoupCookieJar *jar,
647 SoupURI *first_party,
650 SoupCookie *soup_cookie;
652 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
653 g_return_if_fail (uri != NULL);
654 g_return_if_fail (first_party != NULL);
655 g_return_if_fail (cookie != NULL);
660 soup_cookie = soup_cookie_parse (cookie, uri);
662 soup_cookie_jar_add_cookie_with_first_party (jar, first_party, soup_cookie);
666 process_set_cookie_header (SoupMessage *msg, gpointer user_data)
668 SoupCookieJar *jar = user_data;
669 SoupCookieJarPrivate *priv = soup_cookie_jar_get_instance_private (jar);
670 GSList *new_cookies, *nc;
672 if (priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NEVER)
675 new_cookies = soup_cookies_from_response (msg);
676 for (nc = new_cookies; nc; nc = nc->next) {
677 SoupURI *first_party = soup_message_get_first_party (msg);
679 if ((priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY &&
680 !incoming_cookie_is_third_party (nc->data, first_party)) ||
681 priv->accept_policy == SOUP_COOKIE_JAR_ACCEPT_ALWAYS)
682 soup_cookie_jar_add_cookie (jar, nc->data);
684 soup_cookie_free (nc->data);
686 g_slist_free (new_cookies);
690 msg_starting_cb (SoupMessage *msg, gpointer feature)
692 SoupCookieJar *jar = SOUP_COOKIE_JAR (feature);
695 cookies = soup_cookie_jar_get_cookies (jar, soup_message_get_uri (msg), TRUE);
697 soup_message_headers_replace (msg->request_headers,
701 soup_message_headers_remove (msg->request_headers, "Cookie");
705 soup_cookie_jar_request_queued (SoupSessionFeature *feature,
706 SoupSession *session,
709 g_signal_connect (msg, "starting",
710 G_CALLBACK (msg_starting_cb),
713 soup_message_add_header_handler (msg, "got-headers",
715 G_CALLBACK (process_set_cookie_header),
720 soup_cookie_jar_request_unqueued (SoupSessionFeature *feature,
721 SoupSession *session,
724 g_signal_handlers_disconnect_by_func (msg, process_set_cookie_header, feature);
728 soup_cookie_jar_session_feature_init (SoupSessionFeatureInterface *feature_interface,
729 gpointer interface_data)
731 feature_interface->request_queued = soup_cookie_jar_request_queued;
732 feature_interface->request_unqueued = soup_cookie_jar_request_unqueued;
736 * soup_cookie_jar_all_cookies:
737 * @jar: a #SoupCookieJar
739 * Constructs a #GSList with every cookie inside the @jar.
740 * The cookies in the list are a copy of the original, so
741 * you have to free them when you are done with them.
743 * Return value: (transfer full) (element-type Soup.Cookie): a #GSList
744 * with all the cookies in the @jar.
749 soup_cookie_jar_all_cookies (SoupCookieJar *jar)
751 SoupCookieJarPrivate *priv;
756 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), NULL);
758 priv = soup_cookie_jar_get_instance_private (jar);
760 g_hash_table_iter_init (&iter, priv->domains);
762 while (g_hash_table_iter_next (&iter, &key, &value)) {
763 GSList *p, *cookies = value;
764 for (p = cookies; p; p = p->next)
765 l = g_slist_prepend (l, soup_cookie_copy (p->data));
772 * soup_cookie_jar_delete_cookie:
773 * @jar: a #SoupCookieJar
774 * @cookie: a #SoupCookie
776 * Deletes @cookie from @jar, emitting the 'changed' signal.
781 soup_cookie_jar_delete_cookie (SoupCookieJar *jar,
784 SoupCookieJarPrivate *priv;
787 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
788 g_return_if_fail (cookie != NULL);
790 priv = soup_cookie_jar_get_instance_private (jar);
792 cookies = g_hash_table_lookup (priv->domains, cookie->domain);
796 for (p = cookies; p; p = p->next ) {
797 SoupCookie *c = (SoupCookie*)p->data;
798 if (soup_cookie_equal (cookie, c)) {
799 cookies = g_slist_delete_link (cookies, p);
800 g_hash_table_insert (priv->domains,
801 g_strdup (cookie->domain),
803 soup_cookie_jar_changed (jar, c, NULL);
804 soup_cookie_free (c);
811 * SoupCookieJarAcceptPolicy:
812 * @SOUP_COOKIE_JAR_ACCEPT_ALWAYS: accept all cookies unconditionally.
813 * @SOUP_COOKIE_JAR_ACCEPT_NEVER: reject all cookies unconditionally.
814 * @SOUP_COOKIE_JAR_ACCEPT_NO_THIRD_PARTY: accept all cookies set by
815 * the main document loaded in the application using libsoup. An
816 * example of the most common case, web browsers, would be: If
817 * http://www.example.com is the page loaded, accept all cookies set
818 * by example.com, but if a resource from http://www.third-party.com
819 * is loaded from that page reject any cookie that it could try to
820 * set. For libsoup to be able to tell apart first party cookies from
821 * the rest, the application must call soup_message_set_first_party()
822 * on each outgoing #SoupMessage, setting the #SoupURI of the main
823 * document. If no first party is set in a message when this policy is
824 * in effect, cookies will be assumed to be third party by default.
826 * The policy for accepting or rejecting cookies returned in
833 * soup_cookie_jar_get_accept_policy:
834 * @jar: a #SoupCookieJar
836 * Gets @jar's #SoupCookieJarAcceptPolicy
838 * Returns: the #SoupCookieJarAcceptPolicy set in the @jar
842 SoupCookieJarAcceptPolicy
843 soup_cookie_jar_get_accept_policy (SoupCookieJar *jar)
845 SoupCookieJarPrivate *priv;
847 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), SOUP_COOKIE_JAR_ACCEPT_ALWAYS);
849 priv = soup_cookie_jar_get_instance_private (jar);
850 return priv->accept_policy;
854 * soup_cookie_jar_set_accept_policy:
855 * @jar: a #SoupCookieJar
856 * @policy: a #SoupCookieJarAcceptPolicy
858 * Sets @policy as the cookie acceptance policy for @jar.
863 soup_cookie_jar_set_accept_policy (SoupCookieJar *jar,
864 SoupCookieJarAcceptPolicy policy)
866 SoupCookieJarPrivate *priv;
868 g_return_if_fail (SOUP_IS_COOKIE_JAR (jar));
870 priv = soup_cookie_jar_get_instance_private (jar);
872 if (priv->accept_policy != policy) {
873 priv->accept_policy = policy;
874 g_object_notify (G_OBJECT (jar), SOUP_COOKIE_JAR_ACCEPT_POLICY);
879 * soup_cookie_jar_is_persistent:
880 * @jar: a #SoupCookieJar
882 * Gets whether @jar stores cookies persistenly.
884 * Returns: %TRUE if @jar storage is persistent or %FALSE otherwise.
889 soup_cookie_jar_is_persistent (SoupCookieJar *jar)
891 g_return_val_if_fail (SOUP_IS_COOKIE_JAR (jar), FALSE);
893 return SOUP_COOKIE_JAR_GET_CLASS (jar)->is_persistent (jar);