Skip to content
cookie.c 30.1 KiB
Newer Older
/***************************************************************************
 *                                  _   _ ____  _
 *  Project                     ___| | | |  _ \| |
 *                             / __| | | | |_) | |
 *                            | (__| |_| |  _ <| |___
Daniel Stenberg's avatar
Daniel Stenberg committed
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2008, Daniel Stenberg, <daniel@haxx.se>, et al.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
 * are also available at http://curl.haxx.se/docs/copyright.html.
Daniel Stenberg's avatar
Daniel Stenberg committed
 * You may opt to use, copy, modify, merge, publish, distribute and/or sell
 * copies of the Software, and permit persons to whom the Software is
 * furnished to do so, under the terms of the COPYING file.
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
 * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
 * KIND, either express or implied.
 *
 * $Id$
 ***************************************************************************/
Daniel Stenberg's avatar
Daniel Stenberg committed

/***


RECEIVING COOKIE INFORMATION
============================

struct CookieInfo *cookie_init(char *file);
        Inits a cookie struct to store data in a local file. This is always
        called before any cookies are set.
Daniel Stenberg's avatar
Daniel Stenberg committed

int cookies_set(struct CookieInfo *cookie, char *cookie_line);

        The 'cookie_line' parameter is a full "Set-cookie:" line as
        received from a server.
Daniel Stenberg's avatar
Daniel Stenberg committed

        The function need to replace previously stored lines that this new
        line superceeds.
Daniel Stenberg's avatar
Daniel Stenberg committed

        It may remove lines that are expired.
Daniel Stenberg's avatar
Daniel Stenberg committed

        It should return an indication of success/error.
Daniel Stenberg's avatar
Daniel Stenberg committed


SENDING COOKIE INFORMATION
==========================

struct Cookies *cookie_getlist(struct CookieInfo *cookie,
                               char *host, char *path, bool secure);

        For a given host and path, return a linked list of cookies that
        the client should send to the server if used now. The secure
        boolean informs the cookie if a secure connection is achieved or
        not.
Daniel Stenberg's avatar
Daniel Stenberg committed

        It shall only return cookies that haven't expired.
Daniel Stenberg's avatar
Daniel Stenberg committed

Daniel Stenberg's avatar
Daniel Stenberg committed
Example set of cookies:
Daniel Stenberg's avatar
Daniel Stenberg committed
    Set-cookie: PRODUCTINFO=webxpress; domain=.fidelity.com; path=/; secure
    Set-cookie: PERSONALIZE=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
    domain=.fidelity.com; path=/ftgw; secure
    Set-cookie: FidHist=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
    domain=.fidelity.com; path=/; secure
    Set-cookie: FidOrder=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
    domain=.fidelity.com; path=/; secure
    Set-cookie: DisPend=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
    domain=.fidelity.com; path=/; secure
    Set-cookie: FidDis=none;expires=Monday, 13-Jun-1988 03:04:55 GMT;
    domain=.fidelity.com; path=/; secure
    Set-cookie:
    Session_Key@6791a9e0-901a-11d0-a1c8-9b012c88aa77=none;expires=Monday,
    13-Jun-1988 03:04:55 GMT; domain=.fidelity.com; path=/; secure
****/

#if !defined(CURL_DISABLE_HTTP) && !defined(CURL_DISABLE_COOKIES)
Daniel Stenberg's avatar
Daniel Stenberg committed
#include <stdlib.h>
#include <string.h>

#define _MPRINTF_REPLACE /* without this on windows OS we get undefined reference to snprintf */
#include <curl/mprintf.h>

Daniel Stenberg's avatar
Daniel Stenberg committed
#include "cookie.h"
#include "strequal.h"
#include "strtok.h"
Daniel Stenberg's avatar
Daniel Stenberg committed

/* The last #include file should be: */
#ifdef CURLDEBUG
#include "memdebug.h"
#endif

static void freecookie(struct Cookie *co)
  if(co->domain)
    free(co->domain);
  if(co->path)
    free(co->path);
  if(co->name)
    free(co->name);
  if(co->value)
    free(co->value);
Daniel Stenberg's avatar
Daniel Stenberg committed
static bool tailmatch(const char *little, const char *bigone)
{
  size_t littlelen = strlen(little);
  size_t biglen = strlen(bigone);
Daniel Stenberg's avatar
Daniel Stenberg committed

  if(littlelen > biglen)
    return FALSE;

  return (bool)strequal(little, bigone+biglen-littlelen);
/*
 * Load cookies from all given cookie files (CURLOPT_COOKIEFILE).
 */
void Curl_cookie_loadfiles(struct SessionHandle *data)
{
  struct curl_slist *list = data->change.cookielist;
  if(list) {
    Curl_share_lock(data, CURL_LOCK_DATA_COOKIE, CURL_LOCK_ACCESS_SINGLE);
    while(list) {
      data->cookies = Curl_cookie_init(data,
                                       list->data,
                                       data->cookies,
                                       data->set.cookiesession);
      list = list->next;
    }
    Curl_share_unlock(data, CURL_LOCK_DATA_COOKIE);
    curl_slist_free_all(data->change.cookielist); /* clean up list */
    data->change.cookielist = NULL; /* don't do this again! */
  }
}

Daniel Stenberg's avatar
Daniel Stenberg committed
/****************************************************************************
 *
Daniel Stenberg's avatar
Daniel Stenberg committed
 *
 * Add a single cookie line to the cookie keeping object.
 *
 ***************************************************************************/

Curl_cookie_add(struct SessionHandle *data,
                /* The 'data' pointer here may be NULL at times, and thus
                   must only be used very carefully for things that can deal
                   with data being NULL. Such as infof() and similar */
                bool httpheader, /* TRUE if HTTP header-style line */
                char *lineptr,   /* first character of the line */
Dan Fandrich's avatar
Dan Fandrich committed
                const char *domain, /* default domain */
                const char *path)   /* full path used when this cookie is set,
Daniel Stenberg's avatar
Daniel Stenberg committed
                                    used to get default path for the cookie
                                    unless set */
Daniel Stenberg's avatar
Daniel Stenberg committed
{
  struct Cookie *clist;
  char name[MAX_NAME];
  struct Cookie *co;
Daniel Stenberg's avatar
Daniel Stenberg committed
  time_t now = time(NULL);
  bool replace_old = FALSE;
Daniel Stenberg's avatar
Daniel Stenberg committed
  bool badcookie = FALSE; /* cookies are good by default. mmmmm yummy */
Daniel Stenberg's avatar
Daniel Stenberg committed

Yang Tse's avatar
Yang Tse committed
#ifdef CURL_DISABLE_VERBOSE_STRINGS
  (void)data;
#endif

Daniel Stenberg's avatar
Daniel Stenberg committed
  /* First, alloc and init a new struct for it */
  co = calloc(sizeof(struct Cookie), 1);
Daniel Stenberg's avatar
Daniel Stenberg committed
  if(!co)
    return NULL; /* bail out if we're this low on memory */

  if(httpheader) {
    /* This line was read off a HTTP-header */
Dan Fandrich's avatar
Dan Fandrich committed
    const char *ptr;
    const char *sep;
Loading
Loading full blame…