Skip to content
This repository has been archived by the owner on Jan 11, 2023. It is now read-only.

Commit

Permalink
Use internal functions for date formatting in WebDAV
Browse files Browse the repository at this point in the history
  • Loading branch information
swisspol committed Apr 12, 2014
1 parent bb32a72 commit c062d9d
Show file tree
Hide file tree
Showing 6 changed files with 43 additions and 20 deletions.
4 changes: 4 additions & 0 deletions CGDWebServer/GCDWebServer.h
Original file line number Diff line number Diff line change
Expand Up @@ -51,6 +51,10 @@ NSString* GCDWebServerEscapeURLString(NSString* string);
NSString* GCDWebServerUnescapeURLString(NSString* string);
NSDictionary* GCDWebServerParseURLEncodedForm(NSString* form);
NSString* GCDWebServerGetPrimaryIPv4Address(); // Returns IPv4 address of primary connected service on OS X or of WiFi interface on iOS if connected
NSString* GCDWebServerFormatRFC822(NSDate* date);
NSDate* GCDWebServerParseRFC822(NSString* string);
NSString* GCDWebServerFormatISO8601(NSDate* date);
NSDate* GCDWebServerParseISO8601(NSString* string);

#ifdef __cplusplus
}
Expand Down
35 changes: 31 additions & 4 deletions CGDWebServer/GCDWebServer.m
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ @interface GCDWebServerHandler () {
#endif

static NSDateFormatter* _dateFormatterRFC822 = nil;
static NSDateFormatter* _dateFormatterISO8601 = nil;
static dispatch_queue_t _dateFormatterQueue = NULL;
#if !TARGET_OS_IPHONE
static BOOL _run;
Expand Down Expand Up @@ -139,18 +140,34 @@ NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset) {
return (encoding != kCFStringEncodingInvalidId ? encoding : NSUTF8StringEncoding);
}

NSString* GCDWebServerFormatHTTPDate(NSDate* date) {
NSString* GCDWebServerFormatRFC822(NSDate* date) {
__block NSString* string;
dispatch_sync(_dateFormatterQueue, ^{
string = [_dateFormatterRFC822 stringFromDate:date]; // HTTP/1.1 server must use RFC822
string = [_dateFormatterRFC822 stringFromDate:date];
});
return string;
}

NSDate* GCDWebServerParseHTTPDate(NSString* string) {
NSDate* GCDWebServerParseRFC822(NSString* string) {
__block NSDate* date;
dispatch_sync(_dateFormatterQueue, ^{
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)
date = [_dateFormatterRFC822 dateFromString:string];
});
return date;
}

NSString* GCDWebServerFormatISO8601(NSDate* date) {
__block NSString* string;
dispatch_sync(_dateFormatterQueue, ^{
string = [_dateFormatterISO8601 stringFromDate:date];
});
return string;
}

NSDate* GCDWebServerParseISO8601(NSString* string) {
__block NSDate* date;
dispatch_sync(_dateFormatterQueue, ^{
date = [_dateFormatterISO8601 dateFromString:string];
});
return date;
}
Expand Down Expand Up @@ -324,6 +341,8 @@ + (void)load {

#endif

// HTTP/1.1 server must use RFC822
// TODO: Handle RFC 850 and ANSI C's asctime() format (http://www.w3.org/Protocols/rfc2616/rfc2616-sec3.html#sec3.3)
+ (void)initialize {
if (_dateFormatterRFC822 == nil) {
DCHECK([NSThread isMainThread]); // NSDateFormatter should be initialized on main thread
Expand All @@ -333,6 +352,14 @@ + (void)initialize {
_dateFormatterRFC822.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]);
DCHECK(_dateFormatterRFC822);
}
if (_dateFormatterISO8601 == nil) {
DCHECK([NSThread isMainThread]); // NSDateFormatter should be initialized on main thread
_dateFormatterISO8601 = [[NSDateFormatter alloc] init];
_dateFormatterISO8601.timeZone = [NSTimeZone timeZoneWithAbbreviation:@"GMT"];
_dateFormatterISO8601.dateFormat = @"yyyy-MM-dd'T'HH:mm:ss'+00:00'";
_dateFormatterISO8601.locale = ARC_AUTORELEASE([[NSLocale alloc] initWithLocaleIdentifier:@"en_US"]);
DCHECK(_dateFormatterISO8601);
}
if (_dateFormatterQueue == NULL) {
_dateFormatterQueue = dispatch_queue_create(NULL, DISPATCH_QUEUE_SERIAL);
DCHECK(_dateFormatterQueue);
Expand Down
4 changes: 2 additions & 2 deletions CGDWebServer/GCDWebServerConnection.m
Original file line number Diff line number Diff line change
Expand Up @@ -435,7 +435,7 @@ - (void)_initializeResponseHeadersWithStatusCode:(NSInteger)statusCode {
_responseMessage = CFHTTPMessageCreateResponse(kCFAllocatorDefault, statusCode, NULL, kCFHTTPVersion1_1);
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Connection"), CFSTR("Close"));
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Server"), (ARC_BRIDGE CFStringRef)[[_server class] serverName]);
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate([NSDate date]));
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Date"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822([NSDate date]));
}

// http://www.w3.org/Protocols/rfc2616/rfc2616-sec10.html
Expand Down Expand Up @@ -463,7 +463,7 @@ - (void)_processRequest {
if (_response) {
[self _initializeResponseHeadersWithStatusCode:_response.statusCode];
if (_response.lastModifiedDate) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatHTTPDate(_response.lastModifiedDate));
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("Last-Modified"), (ARC_BRIDGE CFStringRef)GCDWebServerFormatRFC822(_response.lastModifiedDate));
}
if (_response.eTag) {
CFHTTPMessageSetHeaderFieldValue(_responseMessage, CFSTR("ETag"), (ARC_BRIDGE CFStringRef)_response.eTag);
Expand Down
2 changes: 0 additions & 2 deletions CGDWebServer/GCDWebServerPrivate.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,8 +116,6 @@ extern NSString* GCDWebServerNormalizeHeaderValue(NSString* value);
extern NSString* GCDWebServerTruncateHeaderValue(NSString* value);
extern NSString* GCDWebServerExtractHeaderValueParameter(NSString* header, NSString* attribute);
extern NSStringEncoding GCDWebServerStringEncodingFromCharset(NSString* charset);
extern NSString* GCDWebServerFormatHTTPDate(NSDate* date);
extern NSDate* GCDWebServerParseHTTPDate(NSString* string);
extern NSString* GCDWebServerDescribeData(NSData* data, NSString* contentType);

@interface GCDWebServerConnection ()
Expand Down
2 changes: 1 addition & 1 deletion CGDWebServer/GCDWebServerRequest.m
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ - (instancetype)initWithMethod:(NSString*)method url:(NSURL*)url headers:(NSDict

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

Expand Down
16 changes: 5 additions & 11 deletions GCDWebDAVServer/GCDWebDAVServer.m
Original file line number Diff line number Diff line change
Expand Up @@ -335,19 +335,11 @@ - (void)_addPropertyResponseForItem:(NSString*)itemPath resource:(NSString*)reso
}

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

if ((properties & kDAVProperty_LastModified) && [attributes objectForKey:NSFileModificationDate]) {
NSDateFormatter* formatter = [[NSDateFormatter alloc] init];
formatter.locale = [[NSLocale alloc] initWithLocaleIdentifier:@"en_US"];
formatter.timeZone = [NSTimeZone timeZoneWithName:@"GMT"];
formatter.dateFormat = @"EEE', 'd' 'MMM' 'yyyy' 'HH:mm:ss' GMT'";
[xmlString appendFormat:@"<D:getlastmodified>%@</D:getlastmodified>", [formatter stringFromDate:[attributes fileModificationDate]]];
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
[xmlString appendFormat:@"<D:getlastmodified>%@</D:getlastmodified>", GCDWebServerFormatRFC822([attributes fileModificationDate])];
}

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

Expand Down

0 comments on commit c062d9d

Please sign in to comment.