Allow to customiz mime types used by GCDWebServerFileResponse
diff --git a/GCDWebServer/Core/GCDWebServerFunctions.h b/GCDWebServer/Core/GCDWebServerFunctions.h
index 0752bce..4235ecc 100644
--- a/GCDWebServer/Core/GCDWebServerFunctions.h
+++ b/GCDWebServer/Core/GCDWebServerFunctions.h
@@ -36,8 +36,12 @@
/**
* Converts a file extension to the corresponding MIME type.
* If there is no match, "application/octet-stream" is returned.
+ *
+ * Overrides allow to customize the built-in mapping from extensions to MIME
+ * types. Keys of the dictionary must be lowercased file extensions without
+ * the period, and the values must be the corresponding MIME types.
*/
-NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension);
+NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension, NSDictionary* _Nullable overrides);
/**
* Add percent-escapes to a string so it can be used in a URL.
diff --git a/GCDWebServer/Core/GCDWebServerFunctions.m b/GCDWebServer/Core/GCDWebServerFunctions.m
index 7c72e34..ec50086 100644
--- a/GCDWebServer/Core/GCDWebServerFunctions.m
+++ b/GCDWebServer/Core/GCDWebServerFunctions.m
@@ -166,13 +166,16 @@
return [NSString stringWithFormat:@"<%lu bytes>", (unsigned long)data.length];
}
-NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension) {
- NSDictionary* overrides = @{@"css": @"text/css"};
+NSString* GCDWebServerGetMimeTypeForExtension(NSString* extension, NSDictionary* overrides) {
+ NSDictionary* builtInOverrides = @{@"css": @"text/css"};
NSString* mimeType = nil;
extension = [extension lowercaseString];
if (extension.length) {
mimeType = [overrides objectForKey:extension];
if (mimeType == nil) {
+ mimeType = [builtInOverrides objectForKey:extension];
+ }
+ if (mimeType == nil) {
CFStringRef uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, (__bridge CFStringRef)extension, NULL);
if (uti) {
mimeType = CFBridgingRelease(UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType));
diff --git a/GCDWebServer/Responses/GCDWebServerFileResponse.h b/GCDWebServer/Responses/GCDWebServerFileResponse.h
index f7dbd47..9403835 100644
--- a/GCDWebServer/Responses/GCDWebServerFileResponse.h
+++ b/GCDWebServer/Responses/GCDWebServerFileResponse.h
@@ -95,8 +95,13 @@
/**
* This method is the designated initializer for the class.
+ *
+ * If MIME type overrides are specified, they allow to customize the built-in
+ * mapping from extensions to MIME types. Keys of the dictionary must be lowercased
+ * file extensions without the period, and the values must be the corresponding
+ * MIME types.
*/
-- (nullable instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment;
+- (nullable instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment mimeTypeOverrides:(nullable NSDictionary*)overrides;
@end
diff --git a/GCDWebServer/Responses/GCDWebServerFileResponse.m b/GCDWebServer/Responses/GCDWebServerFileResponse.m
index f693e1b..bd07518 100644
--- a/GCDWebServer/Responses/GCDWebServerFileResponse.m
+++ b/GCDWebServer/Responses/GCDWebServerFileResponse.m
@@ -57,26 +57,26 @@
}
+ (instancetype)responseWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment {
- return [[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment];
+ return [[[self class] alloc] initWithFile:path byteRange:range isAttachment:attachment mimeTypeOverrides:nil];
}
- (instancetype)initWithFile:(NSString*)path {
- return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:NO];
+ return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:NO mimeTypeOverrides:nil];
}
- (instancetype)initWithFile:(NSString*)path isAttachment:(BOOL)attachment {
- return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:attachment];
+ return [self initWithFile:path byteRange:NSMakeRange(NSUIntegerMax, 0) isAttachment:attachment mimeTypeOverrides:nil];
}
- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range {
- return [self initWithFile:path byteRange:range isAttachment:NO];
+ return [self initWithFile:path byteRange:range isAttachment:NO mimeTypeOverrides:nil];
}
static inline NSDate* _NSDateFromTimeSpec(const struct timespec* t) {
return [NSDate dateWithTimeIntervalSince1970:((NSTimeInterval)t->tv_sec + (NSTimeInterval)t->tv_nsec / 1000000000.0)];
}
-- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment {
+- (instancetype)initWithFile:(NSString*)path byteRange:(NSRange)range isAttachment:(BOOL)attachment mimeTypeOverrides:(NSDictionary*)overrides {
struct stat info;
if (lstat([path fileSystemRepresentation], &info) || !(info.st_mode & S_IFREG)) {
GWS_DNOT_REACHED();
@@ -129,7 +129,7 @@
}
}
- self.contentType = GCDWebServerGetMimeTypeForExtension([_path pathExtension]);
+ self.contentType = GCDWebServerGetMimeTypeForExtension([_path pathExtension], overrides);
self.contentLength = _size;
self.lastModifiedDate = _NSDateFromTimeSpec(&info.st_mtimespec);
self.eTag = [NSString stringWithFormat:@"%llu/%li/%li", info.st_ino, info.st_mtimespec.tv_sec, info.st_mtimespec.tv_nsec];