Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygencookie.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
1.7.6.1
|