2 Copyright (C) 2000-2005 SKYRIX Software AG
4 This file is part of SOPE.
6 SOPE is free software; you can redistribute it and/or modify it under
7 the terms of the GNU Lesser General Public License as published by the
8 Free Software Foundation; either version 2, or (at your option) any
11 SOPE is distributed in the hope that it will be useful, but WITHOUT ANY
12 WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public
14 License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with SOPE; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
22 #include <NGObjWeb/WOCookie.h>
25 @interface WOCookie(PrivateMethods)
27 - (id)initWithName:(NSString *)_name value:(NSString *)_value
28 path:(NSString *)_path domain:(NSString *)_domain
29 expires:(NSDate *)_date
30 isSecure:(BOOL)_secure;
34 @implementation WOCookie
36 static WOCookie *_parseCookie(const char *_bytes, unsigned _len);
38 // abbr weekday, day-of-month, abbr-month, year hour:min:sec GMT
39 static NSString *cookieDateFormat = @"%a, %d-%b-%Y %H:%M:%S %Z";
41 + (id)cookieWithString:(NSString *)_string {
42 /* private method ! */
43 return _parseCookie([_string cString], [_string cStringLength]);
46 + (id)cookieWithName:(NSString *)_name value:(NSString *)_value {
47 return [[[self alloc] initWithName:_name value:_value
49 expires:nil isSecure:NO]
53 + (id)cookieWithName:(NSString *)_name value:(NSString *)_value
54 path:(NSString *)_path domain:(NSString *)_domain
55 expires:(NSDate *)_date
56 isSecure:(BOOL)_secure
58 return [[[self alloc] initWithName:_name value:_value
59 path:_path domain:_domain
60 expires:_date isSecure:_secure]
64 - (id)initWithName:(NSString *)_name value:(NSString *)_value
65 path:(NSString *)_path domain:(NSString *)_domain
66 expires:(NSDate *)_date
67 isSecure:(BOOL)_secure
69 if ((self = [super init])) {
70 NSZone *z = [self zone];
71 self->name = [_name copyWithZone:z];
72 self->value = [_value copyWithZone:z];
73 self->path = [_path copyWithZone:z];
74 self->domainName = [_domain copyWithZone:z];
75 self->expireDate = [expireDate retain];
76 self->onlyIfSecure = _secure;
83 [self->value release];
84 [self->expireDate release];
86 [self->domainName release];
92 - (NSString *)cookieName {
97 - (void)setName:(NSString *)_name {
98 ASSIGNCOPY(self->name, _name);
104 - (void)setValue:(NSString *)_value {
105 ASSIGNCOPY(self->value, _value);
107 - (NSString *)value {
111 - (void)setPath:(NSString *)_path {
112 ASSIGNCOPY(self->path, _path);
118 - (void)setExpires:(NSDate *)_date {
119 ASSIGNCOPY(self->expireDate, _date);
121 - (NSDate *)expires {
122 return self->expireDate;
125 - (void)setDomain:(NSString *)_domain {
126 ASSIGNCOPY(self->domainName, _domain);
128 - (NSString *)domain {
129 return self->domainName;
132 - (void)setIsSecure:(BOOL)_flag {
133 self->onlyIfSecure = _flag ? YES : NO;
136 return self->onlyIfSecure;
139 - (NSDate *)expireDate {
141 return self->expireDate;
146 - (id)copyWithZone:(NSZone *)_zone {
147 return [[WOCookie alloc] initWithName:self->name value:self->value
148 path:self->path domain:self->domainName
149 expires:self->expireDate
150 isSecure:self->onlyIfSecure];
155 - (NSString *)headerString {
156 return [@"set-cookie: " stringByAppendingString:[self stringValue]];
159 - (NSString *)stringValue {
160 NSMutableString *str;
162 str = [NSMutableString stringWithCapacity:512];
163 [str appendString:[self->name stringByEscapingURL]];
164 [str appendString:@"="];
165 [str appendString:[[self->value stringValue] stringByEscapingURL]];
167 if (self->expireDate) {
168 static NSTimeZone *gmt = nil;
171 gmt = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
173 // TODO: replace, -descriptionWithCalendarFormat is *slow*
174 s = [self->expireDate descriptionWithCalendarFormat:cookieDateFormat
178 [str appendString:@"; expires="];
179 [str appendString:s];
182 [str appendString:@"; path="];
183 [str appendString:self->path];
185 if (self->domainName) {
186 [str appendString:@"; domain="];
187 [str appendString:self->domainName];
189 if (self->onlyIfSecure)
190 [str appendString:@"; secure"];
195 - (NSString *)description {
196 NSMutableString *str;
198 str = [NSMutableString stringWithCapacity:128];
199 [str appendFormat:@"<%@[0x%08X]: name=%@ value=%@",
200 NSStringFromClass([self class]), self,
201 self->name, self->value];
203 if (self->expireDate) {
204 [str appendString:@" expires="];
205 [str appendString:[self->expireDate description]];
209 [str appendString:@" path="];
210 [str appendString:self->path];
212 if (self->domainName) {
213 [str appendString:@" domain="];
214 [str appendString:self->domainName];
216 if (self->onlyIfSecure)
217 [str appendString:@" secure"];
219 [str appendString:@">"];
226 static WOCookie *_parseCookie(const char *_bytes, unsigned _len) {
227 WOCookie *cookie = nil;
230 for (pos = 0, toGo = _len; (toGo > 0) && (_bytes[pos] != '='); toGo--, pos++)
234 NSString *name = nil;
235 NSString *value = nil;
237 // NSLog(@"pos=%i toGo=%i", pos, toGo);
239 name = [[NSString alloc]
240 initWithCString:_bytes
242 value = [[NSString alloc]
243 initWithCString:&(_bytes[pos + 1])
246 //NSLog(@"pair='%@'", [NSString stringWithCString:_bytes length:_len]);
247 //NSLog(@"name='%@' value='%@'", name, value);
249 if ((name == nil) || (value == nil)) {
250 NSLog(@"ERROR: invalid cookie pair%s%s: %@",
251 value ? "" : ", no value",
252 name ? "" : ", no name",
253 [NSString stringWithCString:_bytes length:_len]);
259 cookie = [WOCookie cookieWithName:[name stringByUnescapingURL]
260 value:[value stringByUnescapingURL]];
263 [name release]; name = nil;
264 [value release]; value = nil;
268 NSLog(@"ERROR(%s:%i): invalid cookie pair: %@",
269 __PRETTY_FUNCTION__, __LINE__,
270 [NSString stringWithCString:_bytes length:_len]);