2 Copyright (C) 2000-2004 SKYRIX Software AG
4 This file is part of OpenGroupware.org.
6 OGo 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 OGo 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 OGo; see the file COPYING. If not, write to the
18 Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA
23 #include <NGObjWeb/WOCookie.h>
26 @interface WOCookie(PrivateMethods)
28 - (id)initWithName:(NSString *)_name value:(NSString *)_value
29 path:(NSString *)_path domain:(NSString *)_domain
30 expires:(NSDate *)_date
31 isSecure:(BOOL)_secure;
35 @implementation WOCookie
37 static WOCookie *_parseCookie(const char *_bytes, unsigned _len);
39 // abbr weekday, day-of-month, abbr-month, year hour:min:sec GMT
40 static NSString *cookieDateFormat = @"%a, %d-%b-%Y %H:%M:%S %Z";
42 + (id)cookieWithString:(NSString *)_string {
43 /* private method ! */
44 return _parseCookie([_string cString], [_string cStringLength]);
47 + (id)cookieWithName:(NSString *)_name value:(NSString *)_value {
48 return [[[self alloc] initWithName:_name value:_value
50 expires:nil isSecure:NO]
54 + (id)cookieWithName:(NSString *)_name value:(NSString *)_value
55 path:(NSString *)_path domain:(NSString *)_domain
56 expires:(NSDate *)_date
57 isSecure:(BOOL)_secure
59 return [[[self alloc] initWithName:_name value:_value
60 path:_path domain:_domain
61 expires:_date isSecure:_secure]
65 - (id)initWithName:(NSString *)_name value:(NSString *)_value
66 path:(NSString *)_path domain:(NSString *)_domain
67 expires:(NSDate *)_date
68 isSecure:(BOOL)_secure
70 if ((self = [super init])) {
71 NSZone *z = [self zone];
72 self->name = [_name copyWithZone:z];
73 self->value = [_value copyWithZone:z];
74 self->path = [_path copyWithZone:z];
75 self->domainName = [_domain copyWithZone:z];
76 self->expireDate = [expireDate retain];
77 self->onlyIfSecure = _secure;
84 [self->value release];
85 [self->expireDate release];
87 [self->domainName release];
93 - (NSString *)cookieName {
98 - (void)setName:(NSString *)_name {
99 ASSIGNCOPY(self->name, _name);
105 - (void)setValue:(NSString *)_value {
106 ASSIGNCOPY(self->value, _value);
108 - (NSString *)value {
112 - (void)setPath:(NSString *)_path {
113 ASSIGNCOPY(self->path, _path);
119 - (void)setExpires:(NSDate *)_date {
120 ASSIGNCOPY(self->expireDate, _date);
122 - (NSDate *)expires {
123 return self->expireDate;
126 - (void)setDomain:(NSString *)_domain {
127 ASSIGNCOPY(self->domainName, _domain);
129 - (NSString *)domain {
130 return self->domainName;
133 - (void)setIsSecure:(BOOL)_flag {
134 self->onlyIfSecure = _flag ? YES : NO;
137 return self->onlyIfSecure;
140 - (NSDate *)expireDate {
142 return self->expireDate;
147 - (id)copyWithZone:(NSZone *)_zone {
148 return [[WOCookie alloc] initWithName:self->name value:self->value
149 path:self->path domain:self->domainName
150 expires:self->expireDate
151 isSecure:self->onlyIfSecure];
156 - (NSString *)headerString {
157 return [@"set-cookie: " stringByAppendingString:[self stringValue]];
160 - (NSString *)stringValue {
161 NSMutableString *str;
163 str = [NSMutableString stringWithCapacity:512];
164 [str appendString:[self->name stringByEscapingURL]];
165 [str appendString:@"="];
166 [str appendString:[[self->value stringValue] stringByEscapingURL]];
168 if (self->expireDate) {
169 static NSTimeZone *gmt = nil;
172 gmt = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
174 // TODO: replace, -descriptionWithCalendarFormat is *slow*
175 s = [self->expireDate descriptionWithCalendarFormat:cookieDateFormat
179 [str appendString:@"; expires="];
180 [str appendString:s];
183 [str appendString:@"; path="];
184 [str appendString:self->path];
186 if (self->domainName) {
187 [str appendString:@"; domain="];
188 [str appendString:self->domainName];
190 if (self->onlyIfSecure)
191 [str appendString:@"; secure"];
196 - (NSString *)description {
197 NSMutableString *str;
199 str = [NSMutableString stringWithCapacity:128];
200 [str appendFormat:@"<%@[0x%08X]: name=%@ value=%@",
201 NSStringFromClass([self class]), self,
202 self->name, self->value];
204 if (self->expireDate) {
205 [str appendString:@" expires="];
206 [str appendString:[self->expireDate description]];
210 [str appendString:@" path="];
211 [str appendString:self->path];
213 if (self->domainName) {
214 [str appendString:@" domain="];
215 [str appendString:self->domainName];
217 if (self->onlyIfSecure)
218 [str appendString:@" secure"];
220 [str appendString:@">"];
227 static WOCookie *_parseCookie(const char *_bytes, unsigned _len) {
228 WOCookie *cookie = nil;
231 for (pos = 0, toGo = _len; (toGo > 0) && (_bytes[pos] != '='); toGo--, pos++)
235 NSString *name = nil;
236 NSString *value = nil;
238 // NSLog(@"pos=%i toGo=%i", pos, toGo);
240 name = [[NSString alloc]
241 initWithCString:_bytes
243 value = [[NSString alloc]
244 initWithCString:&(_bytes[pos + 1])
247 //NSLog(@"pair='%@'", [NSString stringWithCString:_bytes length:_len]);
248 //NSLog(@"name='%@' value='%@'", name, value);
250 if ((name == nil) || (value == nil)) {
251 NSLog(@"ERROR: invalid cookie pair%s%s: %@",
252 value ? "" : ", no value",
253 name ? "" : ", no name",
254 [NSString stringWithCString:_bytes length:_len]);
260 cookie = [WOCookie cookieWithName:[name stringByUnescapingURL]
261 value:[value stringByUnescapingURL]];
264 [name release]; name = nil;
265 [value release]; value = nil;
269 NSLog(@"ERROR(%s:%i): invalid cookie pair: %@",
270 __PRETTY_FUNCTION__, __LINE__,
271 [NSString stringWithCString:_bytes length:_len]);