Back to index

avfs  1.0.1
http_cookies.c
Go to the documentation of this file.
00001 /* 
00002    Basic cookie support for neon
00003    Copyright (C) 1999-2001, Joe Orton <joe@light.plus.com>
00004 
00005    This library is free software; you can redistribute it and/or
00006    modify it under the terms of the GNU Library General Public
00007    License as published by the Free Software Foundation; either
00008    version 2 of the License, or (at your option) any later version.
00009    
00010    This library is distributed in the hope that it will be useful,
00011    but WITHOUT ANY WARRANTY; without even the implied warranty of
00012    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00013    Library General Public License for more details.
00014 
00015    You should have received a copy of the GNU Library General Public
00016    License along with this library; if not, write to the Free
00017    Software Foundation, Inc., 59 Temple Place - Suite 330, Boston,
00018    MA 02111-1307, USA
00019 
00020 */
00021 
00022 /* A nice demo of hooks, since it doesn't need any external
00023  * interface to muck with the stored states.
00024  */
00025 
00026 #include "config.h"
00027 
00028 #ifdef HAVE_STDLIB_H
00029 #include <stdlib.h>
00030 #endif
00031 
00032 #ifdef HAVE_STRING_H
00033 #include <string.h>
00034 #endif
00035 
00036 #include <time.h>
00037 
00038 #include "http_request.h"
00039 #include "string_utils.h"
00040 #include "http_cookies.h"
00041 #include "ne_alloc.h"
00042 
00043 static void set_cookie_hdl(void *userdata, const char *value)
00044 {
00045     char **pairs = pair_string(value, ';', '=', HTTP_QUOTES, HTTP_WHITESPACE);
00046     http_cookie *cook;
00047     http_cookie_cache *cache = userdata;
00048     int n;
00049 
00050     /* Check sanity */
00051     if (pairs[0] == NULL || pairs[1] == NULL) {
00052        /* yagaboo */
00053        return;
00054     }
00055 
00056     DEBUG(DEBUG_HTTP, "Got cookie name=%s\n", pairs[0]);
00057 
00058     /* Search for a cookie of this name */
00059     DEBUG(DEBUG_HTTP, "Searching for existing cookie...\n");
00060     for (cook = cache->cookies; cook != NULL; cook = cook->next) {
00061        if (strcasecmp(cook->name, pairs[0]) == 0) {
00062            break;
00063        }
00064     }
00065     
00066     if (cook == NULL) {
00067        DEBUG(DEBUG_HTTP, "New cookie.\n");
00068        cook = ne_malloc(sizeof(http_cookie));
00069        memset(cook, 0, sizeof(http_cookie));
00070        cook->name = pairs[0];
00071        cook->next = cache->cookies;
00072        cache->cookies = cook;
00073     } else {
00074        /* Free the old value */
00075        free(cook->value);
00076     }
00077 
00078     cook->value = pairs[1];
00079 
00080     for (n = 2; pairs[n] != NULL; n+=2) {
00081        DEBUG(DEBUG_HTTP, "Cookie parm %s=%s\n", pairs[n], pairs[n+1]);
00082        if (strcasecmp(pairs[n], "path") == 0) {
00083            cook->path = pairs[n+1];
00084            pairs[n+1] = NULL;
00085        } else if (strcasecmp(pairs[n], "max-age") == 0) {
00086            int t = atoi(pairs[n+1]);
00087            cook->expiry = time(NULL) + (time_t)t;
00088        } else if (strcasecmp(pairs[n], "domain") == 0) {
00089            cook->domain = pairs[n+1];
00090            pairs[n+1] = NULL;
00091        }
00092     }
00093 
00094     DEBUG(DEBUG_HTTP, "End of parms.\n");
00095 
00096     pair_string_free(pairs);
00097 }
00098 
00099 static void *create(void *session, http_req *req, const char *method, const char *uri)
00100 {
00101     http_cookie_cache *cache = session;
00102     http_add_response_header_handler(req, "Set-Cookie", set_cookie_hdl, cache);
00103     return cache;
00104 }
00105 
00106 /* Just before sending the request: let them add headers if they want */
00107 static void pre_send(void *private, sbuffer request)
00108 {
00109     http_cookie_cache *cache = private;
00110     http_cookie *cook;
00111     
00112     if (cache->cookies == NULL) {
00113        return;
00114     }
00115     
00116     sbuffer_zappend(request, "Cookie: ");
00117 
00118     for (cook = cache->cookies; cook != NULL; cook=cook->next) {
00119        sbuffer_concat(request, cook->name, "=", cook->value, NULL);
00120        if (cook->next != NULL) {
00121            sbuffer_zappend(request, "; ");
00122        }
00123     }
00124     
00125     sbuffer_zappend(request, EOL);
00126     
00127 }
00128 
00129 static void destroy(void *private)
00130 {
00131     /* FIXME */
00132     return;
00133 }
00134 
00135 http_request_hooks http_cookie_hooks = {
00136     "http://www.webdav.org/neon/hooks/cookies",
00137     create,
00138     NULL,
00139     pre_send,
00140     NULL,
00141     destroy
00142 };