]> err.no Git - sope/blob - sope-appserver/NGObjWeb/WOCookie.m
fixed various warnings
[sope] / sope-appserver / NGObjWeb / WOCookie.m
1 /*
2   Copyright (C) 2000-2004 SKYRIX Software AG
3
4   This file is part of OpenGroupware.org.
5
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
9   later version.
10
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.
15
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
19   02111-1307, USA.
20 */
21 // $Id$
22
23 #include <NGObjWeb/WOCookie.h>
24 #include "common.h"
25
26 @interface WOCookie(PrivateMethods)
27
28 - (id)initWithName:(NSString *)_name value:(NSString *)_value
29   path:(NSString *)_path domain:(NSString *)_domain
30   expires:(NSDate *)_date
31   isSecure:(BOOL)_secure;
32
33 @end
34
35 @implementation WOCookie
36
37 static WOCookie *_parseCookie(const char *_bytes, unsigned _len);
38
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";
41
42 + (id)cookieWithString:(NSString *)_string {
43   /* private method ! */
44   return _parseCookie([_string cString], [_string cStringLength]);
45 }
46
47 + (id)cookieWithName:(NSString *)_name value:(NSString *)_value {
48   return [[[self alloc] initWithName:_name value:_value
49                         path:nil domain:nil
50                         expires:nil isSecure:NO]
51                         autorelease];
52 }
53
54 + (id)cookieWithName:(NSString *)_name value:(NSString *)_value
55   path:(NSString *)_path domain:(NSString *)_domain
56   expires:(NSDate *)_date
57   isSecure:(BOOL)_secure
58 {
59   return [[[self alloc] initWithName:_name value:_value
60                         path:_path domain:_domain
61                         expires:_date isSecure:_secure]
62                         autorelease];
63 }
64
65 - (id)initWithName:(NSString *)_name value:(NSString *)_value
66   path:(NSString *)_path domain:(NSString *)_domain
67   expires:(NSDate *)_date
68   isSecure:(BOOL)_secure
69 {
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;
78   }
79   return self;
80 }
81
82 - (void)dealloc {
83   [self->name       release];
84   [self->value      release];
85   [self->expireDate release];
86   [self->path       release];
87   [self->domainName release];
88   [super dealloc];
89 }
90
91 /* accessors */
92
93 - (NSString *)cookieName {
94   /* ?? */
95   return self->name;
96 }
97
98 - (void)setName:(NSString *)_name {
99   ASSIGNCOPY(self->name, _name);
100 }
101 - (NSString *)name {
102   return self->name;
103 }
104
105 - (void)setValue:(NSString *)_value {
106   ASSIGNCOPY(self->value, _value);
107 }
108 - (NSString *)value {
109   return self->value;
110 }
111
112 - (void)setPath:(NSString *)_path {
113   ASSIGNCOPY(self->path, _path);
114 }
115 - (NSString *)path {
116   return self->path;
117 }
118
119 - (void)setExpires:(NSDate *)_date {
120   ASSIGNCOPY(self->expireDate, _date);
121 }
122 - (NSDate *)expires {
123   return self->expireDate;
124 }
125
126 - (void)setDomain:(NSString *)_domain {
127   ASSIGNCOPY(self->domainName, _domain);
128 }
129 - (NSString *)domain {
130   return self->domainName;
131 }
132
133 - (void)setIsSecure:(BOOL)_flag {
134   self->onlyIfSecure = _flag ? YES : NO;
135 }
136 - (BOOL)isSecure {
137   return self->onlyIfSecure;
138 }
139
140 - (NSDate *)expireDate {
141   // DEPRECATED
142   return self->expireDate;
143 }
144
145 /* NSCopying */
146
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];
152 }
153
154 /* description */
155
156 - (NSString *)headerString {
157   return [@"set-cookie: " stringByAppendingString:[self stringValue]];
158 }
159
160 - (NSString *)stringValue {
161   NSMutableString *str;
162   
163   str = [NSMutableString stringWithCapacity:512];
164   [str appendString:[self->name stringByEscapingURL]];
165   [str appendString:@"="];
166   [str appendString:[[self->value stringValue] stringByEscapingURL]];
167   
168   if (self->expireDate) {
169     static NSTimeZone *gmt = nil;
170     NSString *s;
171     if (gmt == nil) 
172       gmt = [[NSTimeZone timeZoneWithAbbreviation:@"GMT"] retain];
173     
174     // TODO: replace, -descriptionWithCalendarFormat is *slow*
175     s = [self->expireDate descriptionWithCalendarFormat:cookieDateFormat
176                           timeZone:gmt
177                           locale:nil];
178     
179     [str appendString:@"; expires="];
180     [str appendString:s];
181   }
182   if (self->path) {
183     [str appendString:@"; path="];
184     [str appendString:self->path];
185   }
186   if (self->domainName) {
187     [str appendString:@"; domain="];
188     [str appendString:self->domainName];
189   }
190   if (self->onlyIfSecure)
191     [str appendString:@"; secure"];
192   
193   return str;
194 }
195
196 - (NSString *)description {
197   NSMutableString *str;
198
199   str = [NSMutableString stringWithCapacity:128];
200   [str appendFormat:@"<%@[0x%08X]: name=%@ value=%@",
201          NSStringFromClass([self class]), self,
202          self->name, self->value];
203
204   if (self->expireDate) {
205     [str appendString:@" expires="];
206     [str appendString:[self->expireDate description]];
207   }
208   
209   if (self->path) {
210     [str appendString:@" path="];
211     [str appendString:self->path];
212   }
213   if (self->domainName) {
214     [str appendString:@" domain="];
215     [str appendString:self->domainName];
216   }
217   if (self->onlyIfSecure)
218     [str appendString:@" secure"];
219
220   [str appendString:@">"];
221   
222   return str;
223 }
224
225 /* cookie parsing */
226
227 static WOCookie *_parseCookie(const char *_bytes, unsigned _len) {
228   WOCookie *cookie   = nil;
229   unsigned pos, toGo;
230   
231   for (pos = 0, toGo = _len; (toGo > 0) && (_bytes[pos] != '='); toGo--, pos++)
232     ;
233
234   if (toGo > 0) {
235     NSString *name   = nil;
236     NSString *value  = nil;
237
238     // NSLog(@"pos=%i toGo=%i", pos, toGo);
239     
240     name  = [[NSString alloc]
241                        initWithCString:_bytes
242                        length:pos];
243     value = [[NSString alloc]
244                        initWithCString:&(_bytes[pos + 1])
245                        length:(toGo - 1)];
246     
247     //NSLog(@"pair='%@'", [NSString stringWithCString:_bytes length:_len]);
248     //NSLog(@"name='%@' value='%@'", name, value);
249     
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]);
255       [name  release];
256       [value release];
257       return nil;
258     }
259     else {
260       cookie = [WOCookie cookieWithName:[name stringByUnescapingURL]
261                          value:[value stringByUnescapingURL]];
262     }
263     
264     [name  release];  name  = nil;
265     [value release]; value = nil;
266   }
267 #if DEBUG
268   else {
269     NSLog(@"ERROR(%s:%i): invalid cookie pair: %@",
270           __PRETTY_FUNCTION__, __LINE__,
271           [NSString stringWithCString:_bytes length:_len]);
272   }
273 #endif
274   return cookie;
275 }
276
277 @end /* WOCookie */