ReactOS Fundraising Campaign 2012
 
€ 4,410 / € 30,000

Information | Donate

Home | Info | Community | Development | myReactOS | Contact Us

  1. Home
  2. Community
  3. Development
  4. myReactOS
  5. Fundraiser 2012

  1. Main Page
  2. Alphabetical List
  3. Data Structures
  4. Directories
  5. File List
  6. Data Fields
  7. Globals
  8. Related Pages

ReactOS Development > Doxygen

cookie.c
Go to the documentation of this file.
00001 /*
00002  * Copyright 2008 Hans Leidekker for CodeWeavers
00003  *
00004  * This library is free software; you can redistribute it and/or
00005  * modify it under the terms of the GNU Lesser General Public
00006  * License as published by the Free Software Foundation; either
00007  * version 2.1 of the License, or (at your option) any later version.
00008  *
00009  * This library is distributed in the hope that it will be useful,
00010  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00011  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00012  * Lesser General Public License for more details.
00013  *
00014  * You should have received a copy of the GNU Lesser General Public
00015  * License along with this library; if not, write to the Free Software
00016  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
00017  */
00018 
00019 #include "config.h"
00020 #include <stdarg.h>
00021 
00022 #include "wine/debug.h"
00023 #include "wine/list.h"
00024 
00025 #include "windef.h"
00026 #include "winbase.h"
00027 #include "winhttp.h"
00028 
00029 #include "winhttp_private.h"
00030 
00031 WINE_DEFAULT_DEBUG_CHANNEL(winhttp);
00032 
00033 static domain_t *add_domain( session_t *session, WCHAR *name )
00034 {
00035     domain_t *domain;
00036 
00037     if (!(domain = heap_alloc_zero( sizeof(domain_t) ))) return NULL;
00038 
00039     list_init( &domain->entry );
00040     list_init( &domain->cookies );
00041 
00042     domain->name = strdupW( name );
00043     list_add_tail( &session->cookie_cache, &domain->entry );
00044 
00045     TRACE("%s\n", debugstr_w(domain->name));
00046     return domain;
00047 }
00048 
00049 static cookie_t *find_cookie( domain_t *domain, const WCHAR *path, const WCHAR *name )
00050 {
00051     struct list *item;
00052     cookie_t *cookie;
00053 
00054     LIST_FOR_EACH( item, &domain->cookies )
00055     {
00056         cookie = LIST_ENTRY( item, cookie_t, entry );
00057         if (!strcmpW( cookie->path, path ) && !strcmpiW( cookie->name, name ))
00058         {
00059             TRACE("found %s=%s\n", debugstr_w(cookie->name), debugstr_w(cookie->value));
00060             return cookie;
00061          }
00062     }
00063     return NULL;
00064 }
00065 
00066 static BOOL domain_match( const WCHAR *name, domain_t *domain, BOOL partial )
00067 {
00068     TRACE("comparing %s with %s\n", debugstr_w(name), debugstr_w(domain->name));
00069 
00070     if (partial && !strstrW( name, domain->name )) return FALSE;
00071     else if (!partial && strcmpW( name, domain->name )) return FALSE;
00072     return TRUE;
00073 }
00074 
00075 static void free_cookie( cookie_t *cookie )
00076 {
00077     heap_free( cookie->name );
00078     heap_free( cookie->value );
00079     heap_free( cookie->path );
00080     heap_free( cookie );
00081 }
00082 
00083 static void delete_cookie( cookie_t *cookie )
00084 {
00085     list_remove( &cookie->entry );
00086     free_cookie( cookie );
00087 }
00088 
00089 void delete_domain( domain_t *domain )
00090 {
00091     cookie_t *cookie;
00092     struct list *item, *next;
00093 
00094     LIST_FOR_EACH_SAFE( item, next, &domain->cookies )
00095     {
00096         cookie = LIST_ENTRY( item, cookie_t, entry );
00097         delete_cookie( cookie );
00098     }
00099 
00100     list_remove( &domain->entry );
00101     heap_free( domain->name );
00102     heap_free( domain );
00103 }
00104 
00105 static BOOL add_cookie( session_t *session, cookie_t *cookie, WCHAR *domain_name, WCHAR *path )
00106 {
00107     domain_t *domain = NULL;
00108     cookie_t *old_cookie;
00109     struct list *item;
00110 
00111     LIST_FOR_EACH( item, &session->cookie_cache )
00112     {
00113         domain = LIST_ENTRY( item, domain_t, entry );
00114         if (domain_match( domain_name, domain, FALSE )) break;
00115         domain = NULL;
00116     }
00117     if (!domain)
00118     {
00119         if (!(domain = add_domain( session, domain_name ))) return FALSE;
00120     }
00121     else if ((old_cookie = find_cookie( domain, path, cookie->name ))) delete_cookie( old_cookie );
00122 
00123     cookie->path = strdupW( path );
00124     list_add_tail( &domain->cookies, &cookie->entry );
00125 
00126     TRACE("domain %s path %s <- %s=%s\n", debugstr_w(domain_name), debugstr_w(cookie->path),
00127           debugstr_w(cookie->name), debugstr_w(cookie->value));
00128     return TRUE;
00129 }
00130 
00131 static cookie_t *parse_cookie( const WCHAR *string )
00132 {
00133     cookie_t *cookie;
00134     const WCHAR *p;
00135     int len;
00136 
00137     if (!(cookie = heap_alloc_zero( sizeof(cookie_t) ))) return NULL;
00138 
00139     list_init( &cookie->entry );
00140 
00141     if (!(p = strchrW( string, '=' )))
00142     {
00143         WARN("no '=' in %s\n", debugstr_w(string));
00144         return NULL;
00145     }
00146     if (p == string)
00147     {
00148         WARN("empty cookie name in %s\n", debugstr_w(string));
00149         return NULL;
00150     }
00151     len = p - string;
00152     if (!(cookie->name = heap_alloc( (len + 1) * sizeof(WCHAR) )))
00153     {
00154         heap_free( cookie );
00155         return NULL;
00156     }
00157     memcpy( cookie->name, string, len * sizeof(WCHAR) );
00158     cookie->name[len] = 0;
00159 
00160     p++; /* skip '=' */
00161     while (*p == ' ') p++;
00162 
00163     len = strlenW( p );
00164     if (!(cookie->value = heap_alloc( (len + 1) * sizeof(WCHAR) )))
00165     {
00166         free_cookie( cookie );
00167         return NULL;
00168     }
00169     memcpy( cookie->value, p, len * sizeof(WCHAR) );
00170     cookie->value[len] = 0;
00171 
00172     return cookie;
00173 }
00174 
00175 BOOL set_cookies( request_t *request, const WCHAR *cookies )
00176 {
00177     static const WCHAR pathW[] = {'p','a','t','h',0};
00178     static const WCHAR domainW[] = {'d','o','m','a','i','n',0};
00179 
00180     BOOL ret = FALSE;
00181     WCHAR *buffer, *p, *q, *r;
00182     WCHAR *cookie_domain = NULL, *cookie_path = NULL;
00183     session_t *session = request->connect->session;
00184     cookie_t *cookie;
00185     int len;
00186 
00187     len = strlenW( cookies );
00188     if (!(buffer = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
00189     strcpyW( buffer, cookies );
00190 
00191     p = buffer;
00192     while (*p && *p != ';') p++;
00193     if (*p == ';') *p++ = 0;
00194     if (!(cookie = parse_cookie( buffer )))
00195     {
00196         heap_free( buffer );
00197         return FALSE;
00198     }
00199     if ((q = strstrW( p, domainW ))) /* FIXME: do real attribute parsing */
00200     {
00201         while (*q && *q != '=') q++;
00202         if (!*q) goto end;
00203 
00204         r = ++q;
00205         while (*r && *r != ';') r++;
00206         len = r - q;
00207 
00208         if (!(cookie_domain = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
00209         memcpy( cookie_domain, q, len * sizeof(WCHAR) );
00210         cookie_domain[len] = 0;
00211 
00212     }
00213     if ((q = strstrW( p, pathW )))
00214     {
00215         while (*q && *q != '=') q++;
00216         if (!*q) goto end;
00217 
00218         r = ++q;
00219         while (*r && *r != ';') r++;
00220         len = r - q;
00221 
00222         if (!(cookie_path = heap_alloc( (len + 1) * sizeof(WCHAR) ))) goto end;
00223         memcpy( cookie_path, q, len * sizeof(WCHAR) );
00224         cookie_path[len] = 0;
00225     }
00226     if (!cookie_domain && !(cookie_domain = strdupW( request->connect->servername ))) goto end;
00227     if (!cookie_path && !(cookie_path = strdupW( request->path ))) goto end;
00228 
00229     if ((p = strrchrW( cookie_path, '/' )) && p != cookie_path) *p = 0;
00230     ret = add_cookie( session, cookie, cookie_domain, cookie_path );
00231 
00232 end:
00233     if (!ret) free_cookie( cookie );
00234     heap_free( cookie_domain );
00235     heap_free( cookie_path );
00236     heap_free( buffer );
00237     return ret;
00238 }
00239 
00240 BOOL add_cookie_headers( request_t *request )
00241 {
00242     struct list *domain_cursor;
00243     session_t *session = request->connect->session;
00244 
00245     LIST_FOR_EACH( domain_cursor, &session->cookie_cache )
00246     {
00247         domain_t *domain = LIST_ENTRY( domain_cursor, domain_t, entry );
00248         if (domain_match( request->connect->servername, domain, TRUE ))
00249         {
00250             struct list *cookie_cursor;
00251             TRACE("found domain %s\n", debugstr_w(domain->name));
00252 
00253             LIST_FOR_EACH( cookie_cursor, &domain->cookies )
00254             {
00255                 cookie_t *cookie = LIST_ENTRY( cookie_cursor, cookie_t, entry );
00256 
00257                 TRACE("comparing path %s with %s\n", debugstr_w(request->path), debugstr_w(cookie->path));
00258 
00259                 if (strstrW( request->path, cookie->path ) == request->path)
00260                 {
00261                     const WCHAR format[] = {'C','o','o','k','i','e',':',' ','%','s','=','%','s',0};
00262                     int len;
00263                     WCHAR *header;
00264 
00265                     len = strlenW( cookie->name ) + strlenW( format ) + strlenW( cookie->value );
00266                     if (!(header = heap_alloc( (len + 1) * sizeof(WCHAR) ))) return FALSE;
00267 
00268                     sprintfW( header, format, cookie->name, cookie->value );
00269 
00270                     TRACE("%s\n", debugstr_w(header));
00271                     add_request_headers( request, header, len, WINHTTP_ADDREQ_FLAG_ADD );
00272                     heap_free( header );
00273                 }
00274             }
00275         }
00276     }
00277     return TRUE;
00278 }

Generated on Sun May 27 2012 04:26:55 for ReactOS by doxygen 1.7.6.1

ReactOS is a registered trademark or a trademark of ReactOS Foundation in the United States and other countries.