Skip to content

Commit c062d9d

Browse files
committed
Use internal functions for date formatting in WebDAV
1 parent bb32a72 commit c062d9d

File tree

6 files changed

+43
-20
lines changed

6 files changed

+43
-20
lines changed

CGDWebServer/GCDWebServer.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,10 @@ NSString* GCDWebServerEscapeURLString(NSString* string);
5151
NSString* GCDWebServerUnescapeURLString(NSString* string);
5252
NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form);
5353
NSString* GCDWebServerGetPrimaryIPv4Address(); // Returns IPv4 address of primary connected service on OS X or of WiFi interface on iOS if connected
54+
NSString* GCDWebServerFormatRFC822(NSDate* date);
55+
NSDate* GCDWebServerParseRFC822(NSString* string);
56+
NSString* GCDWebServerFormatISO8601(NSDate* date);
57+
NSDate* GCDWebServerParseISO8601(NSString* string);
5458

5559
#ifdef __cplusplus
5660
}

CGDWebServer/GCDWebServer.m

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@ @interface GCDWebServerHandler () {
7575
#endif
7676

7777
static NSDateFormatter* _dateFormatterRFC822 = nil;
78+
static NSDateFormatter* _dateFormatterISO8601 = nil;
7879
static dispatch_queue_t _dateFormatterQueue = NULL;
7980
#if !TARGET_OS_IPHONE
8081
static BOOL _run;
@@ -139,18 +140,34 @@ NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset) {
139140
return (encoding != kCFStringEncodingInvalidId ? encoding : NSUTF8StringEncoding);
140141
}
141142

142-
NSString* GCDWebServerFormatHTTPDate(NSDate* date) {
143+
NSString* GCDWebServerFormatRFC822(NSDate* date) {
143144
__block NSString* string;
144145
dispatch_sync(_dateFormatterQueue, ^{
145-
string = [_dateFormatterRFC822 stringFromDate:date]; // HTTP/1.1 server must use RFC822
146+
string = [_dateFormatterRFC822 stringFromDate:date];
146147
});
147148
return string;
148149
}
149150

150-
NSDate* GCDWebServerParseHTTPDate(NSString* string) {
151+
NSDate* GCDWebServerParseRFC822(NSString* string) {
151152
__block NSDate* date;
152153
dispatch_sync(_dateFormatterQueue, ^{
153-
date = [_dateFormatterRFC822 dateFromString:string]; // TODO: Handle RFC 850 and ANSI C's asctime() format (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3)
154+
date = [_dateFormatterRFC822 dateFromString:string];
155+
});
156+
return date;
157+
}
158+
159+
NSString* GCDWebServerFormatISO8601(NSDate* date) {
160+
__block NSString* string;
161+
dispatch_sync(_dateFormatterQueue, ^{
162+
string = [_dateFormatterISO8601 stringFromDate:date];
163+
});
164+
return string;
165+
}
166+
167+
NSDate* GCDWebServerParseISO8601(NSString* string) {
168+
__block NSDate* date;
169+
dispatch_sync(_dateFormatterQueue, ^{
170+
date = [_dateFormatterISO8601 dateFromString:string];
154171
});
155172
return date;
156173
}
@@ -324,6 +341,8 @@ + (void)load {
324341

325342
#endif
326343

344+
// HTTP/1.1 server must use RFC822
345+
// TODO: Handle RFC 850 and ANSI C's asctime() format (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3)
327346
+ (void)initialize {
328347
if (_dateFormatterRFC822 == nil) {
329348
DCHECK([NSThread isMainThread]); // NSDateFormatter should be initialized on main thread
@@ -333,6 +352,14 @@ + (void)initialize {
333352
_dateFormatterRFC822.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]);
334353
DCHECK(_dateFormatterRFC822);
335354
}
355+
if (_dateFormatterISO8601 == nil) {
356+
DCHECK([NSThread isMainThread]); // NSDateFormatter should be initialized on main thread
357+
_dateFormatterISO8601 = [[NSDateFormatter alloc] init];
358+
_dateFormatterISO8601.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
359+
_dateFormatterISO8601.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'+00:00'";
360+
_dateFormatterISO8601.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]);
361+
DCHECK(_dateFormatterISO8601);
362+
}
336363
if (_dateFormatterQueue == NULL) {
337364
_dateFormatterQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
338365
DCHECK(_dateFormatterQueue);

CGDWebServer/GCDWebServerConnection.m

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -435,7 +435,7 @@ - (void)_initializeResponseHeadersWithStatusCode:(NSInteger)statusCode {
435435
_responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1);
436436
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close"));
437437
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (ARC_BRIDGE CFStringRef)[[_server class] serverName]);
438-
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate([NSDate date]));
438+
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822([NSDate date]));
439439
}
440440

441441
// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
@@ -463,7 +463,7 @@ - (void)_processRequest {
463463
if (_response) {
464464
[self _initializeResponseHeadersWithStatusCode:_response.statusCode];
465465
if (_response.lastModifiedDate) {
466-
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate(_response.lastModifiedDate));
466+
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822(_response.lastModifiedDate));
467467
}
468468
if (_response.eTag) {
469469
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (ARC_BRIDGE CFStringRef)_response.eTag);

CGDWebServer/GCDWebServerPrivate.h

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,6 @@ extern NSString* GCDWebServerNormalizeHeaderValue(NSString* value);
116116
extern NSString* GCDWebServerTruncateHeaderValue(NSString* value);
117117
extern NSString* GCDWebServerExtractHeaderValueParameter(NSString* header, NSString* attribute);
118118
extern NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset);
119-
extern NSString* GCDWebServerFormatHTTPDate(NSDate* date);
120-
extern NSDate* GCDWebServerParseHTTPDate(NSString* string);
121119
extern NSString* GCDWebServerDescribeData(NSData* data, NSString* contentType);
122120

123121
@interface GCDWebServerConnection ()

CGDWebServer/GCDWebServerRequest.m

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -199,7 +199,7 @@ - (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDict
199199

200200
NSString* modifiedHeader = [_headers objectForKey:@"If-Modified-Since"];
201201
if (modifiedHeader) {
202-
_modifiedSince = [GCDWebServerParseHTTPDate(modifiedHeader) copy];
202+
_modifiedSince = [GCDWebServerParseRFC822(modifiedHeader) copy];
203203
}
204204
_noneMatch = ARC_RETAIN([_headers objectForKey:@"If-None-Match"]);
205205

GCDWebDAVServer/GCDWebDAVServer.m

Lines changed: 5 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -335,19 +335,11 @@ - (void)_addPropertyResponseForItem:(NSString*)itemPath resource:(NSString*)reso
335335
}
336336

337337
if ((properties & kDAVProperty_CreationDate) && [attributes objectForKey:NSFileCreationDate]) {
338-
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
339-
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
340-
formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];
341-
formatter.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'+00:00'";
342-
[xmlString appendFormat:@"<D:creationdate>%@</D:creationdate>", [formatter stringFromDate:[attributes fileCreationDate]]];
338+
[xmlString appendFormat:@"<D:creationdate>%@</D:creationdate>", GCDWebServerFormatISO8601([attributes fileCreationDate])];
343339
}
344340

345-
if ((properties & kDAVProperty_LastModified) && [attributes objectForKey:NSFileModificationDate]) {
346-
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
347-
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
348-
formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];
349-
formatter.dateFormat = @"EEE', 'd' 'MMM' 'yyyy' 'HH:mm:ss' GMT'";
350-
[xmlString appendFormat:@"<D:getlastmodified>%@</D:getlastmodified>", [formatter stringFromDate:[attributes fileModificationDate]]];
341+
if ((properties & kDAVProperty_LastModified) && isFile && [attributes objectForKey:NSFileModificationDate]) { // Last modification date is not useful for directories as it changes implicitely and 'Last-Modified' header is not provided for directories anyway
342+
[xmlString appendFormat:@"<D:getlastmodified>%@</D:getlastmodified>", GCDWebServerFormatRFC822([attributes fileModificationDate])];
351343
}
352344

353345
if ((properties & kDAVProperty_ContentLength) && !isDirectory && [attributes objectForKey:NSFileSize]) {
@@ -360,6 +352,8 @@ - (void)_addPropertyResponseForItem:(NSString*)itemPath resource:(NSString*)reso
360352
[xmlString appendString:@"</D:response>\n"];
361353
}
362354
CFRelease(escapedPath);
355+
} else {
356+
[self logError:@"Failed escaping path: %@", itemPath];
363357
}
364358
}
365359

0 commit comments

Comments
 (0)