Skip to content

Commit

Permalink
Improve mime-type handling
Browse files Browse the repository at this point in the history
  • Loading branch information
yvbeek committed Aug 28, 2020
1 parent 8a95757 commit 7d61572
Show file tree
Hide file tree
Showing 6 changed files with 68 additions and 13 deletions.
10 changes: 10 additions & 0 deletions Sources/Helpers/Deprecations.swift
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,16 @@ public extension DispatchTimer {
}
}

// MARK: - FileManager

public extension FileManager {
/// Provides the mime-type of the url based on the path extension.
@available(*, deprecated, message: "use <url>.mimeType")
func mimeType(of url: URL) -> String {
return url.mimeType
}
}

// MARK: - HTTPHeader

@available(*, deprecated, renamed: "HTTPHeaderName")
Expand Down
27 changes: 15 additions & 12 deletions Sources/Helpers/Extensions/FileManager+Ext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -13,19 +13,22 @@ import Foundation
#endif

public extension FileManager {
/// Returns the mime type of a file.
func mimeType(of url: URL) -> String {
let fallback = "application/octet-stream"
let fileExt = url.pathExtension as CFString

// Wasm extensions must return `application/wasm`
// Or else browsers will throw an error
if fileExt as String == "wasm" {
return "application/wasm"
/// Returns the mime type for a path extension (e.g. wasm).
func mimeType(pathExtension: String) -> String {
// Check if there is an override for the extension
switch pathExtension {
case "wasm": return "application/wasm"
default: break
}

guard let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, fileExt, nil)?.takeRetainedValue() else { return fallback }
guard let mimeType = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() else { return fallback }
return mimeType as String
// Let the system determine the proper mime-type
if
let uti = UTTypeCreatePreferredIdentifierForTag(kUTTagClassFilenameExtension, pathExtension as CFString, nil)?.takeRetainedValue(),
let mimeType = UTTypeCopyPreferredTagWithClass(uti, kUTTagClassMIMEType)?.takeRetainedValue() {
return mimeType as String
}

// No mime-type found? Return the fallback
return "application/octet-stream"
}
}
7 changes: 7 additions & 0 deletions Sources/Helpers/Extensions/URL+Ext.swift
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,10 @@ public extension URL {
return scheme == "https" || scheme == "wss"
}
}

public extension URL {
/// Provides the mime-type of the url based on the path extension.
var mimeType: String {
return FileManager.default.mimeType(pathExtension: pathExtension)
}
}
2 changes: 1 addition & 1 deletion Sources/Protocols/HTTP/Handlers/HTTPFileHandler.swift
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ open class HTTPFileHandler: HTTPRequestHandler {

// Construct a response
let response = HTTPResponse()
response.headers.contentType = fileManager.mimeType(of: url)
response.headers.contentType = url.mimeType
response.headers.lastModified = attributes.fileModificationDate()?.rfc1123

// Is a range requested?
Expand Down
4 changes: 4 additions & 0 deletions Telegraph.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,7 @@
82897603217402B60089D662 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82897602217402B60089D662 /* Endpoint.swift */; };
82897604217402B60089D662 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82897602217402B60089D662 /* Endpoint.swift */; };
82897605217402B60089D662 /* Endpoint.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82897602217402B60089D662 /* Endpoint.swift */; };
82C00C7024F9A2E4009A6B1F /* URLTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82C00C6E24F9A252009A6B1F /* URLTests.swift */; };
82D2AF04210D354600BF5BBA /* DataStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D2AF03210D354600BF5BBA /* DataStream.swift */; };
82D2AF05210D354600BF5BBA /* DataStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D2AF03210D354600BF5BBA /* DataStream.swift */; };
82D2AF06210D354600BF5BBA /* DataStream.swift in Sources */ = {isa = PBXBuildFile; fileRef = 82D2AF03210D354600BF5BBA /* DataStream.swift */; };
Expand Down Expand Up @@ -336,6 +337,7 @@
8284FF151ECE89BF00303A00 /* FileManager+Ext.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = "FileManager+Ext.swift"; sourceTree = "<group>"; };
8284FF1C1ECE8C8E00303A00 /* HTTPFileHandler.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = HTTPFileHandler.swift; sourceTree = "<group>"; };
82897602217402B60089D662 /* Endpoint.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = Endpoint.swift; sourceTree = "<group>"; };
82C00C6E24F9A252009A6B1F /* URLTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URLTests.swift; sourceTree = "<group>"; };
82D2AF03210D354600BF5BBA /* DataStream.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = DataStream.swift; sourceTree = "<group>"; };
82EB7CC924D4ACE5004C91B5 /* URITests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = URITests.swift; sourceTree = "<group>"; };
82EC461E22CD1E26008A6A22 /* HTTPHeader+Common.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = "HTTPHeader+Common.swift"; sourceTree = "<group>"; };
Expand Down Expand Up @@ -400,6 +402,7 @@
825A71831ECD22F60043AC8D /* SecurityTests.swift */,
8206413C240C7821003403F3 /* ServerTests.swift */,
82EB7CC924D4ACE5004C91B5 /* URITests.swift */,
82C00C6E24F9A252009A6B1F /* URLTests.swift */,
);
path = Tests;
sourceTree = "<group>";
Expand Down Expand Up @@ -1173,6 +1176,7 @@
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
82C00C7024F9A2E4009A6B1F /* URLTests.swift in Sources */,
825A718A1ECD230E0043AC8D /* HelperTests.swift in Sources */,
82EB7CCA24D4ACE5004C91B5 /* URITests.swift in Sources */,
82EB7CCB24D4AD78004C91B5 /* URI.swift in Sources */,
Expand Down
31 changes: 31 additions & 0 deletions Tests/URLTests.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
//
// URLTests.swift
// Telegraph iOS
//
// Created by Yvo van Beek on 8/28/20.
// Copyright © 2020 Building42. All rights reserved.
//

import XCTest
@testable import Telegraph

class URLTests: XCTestCase {
/// Tests the URL mime-type helper.
func testURLMimeType() {
let url1 = URL(string: "https://www.apple.com")
let url2 = URL(string: "https://www.apple.com/hello")
let url3 = URL(string: "https://www.apple.com/hello.wasm")
let url4 = URL(string: "https://www.apple.com/hello.jpg")
let url5 = URL(string: "https://www.apple.com/hello.png")
let url6 = URL(string: "https://www.apple.com/hello.html")
let url7 = URL(string: "https://www.apple.com/hello.mp4?hello=world")

XCTAssertEqual(url1?.mimeType, "application/octet-stream")
XCTAssertEqual(url2?.mimeType, "application/octet-stream")
XCTAssertEqual(url3?.mimeType, "application/wasm")
XCTAssertEqual(url4?.mimeType, "image/jpeg")
XCTAssertEqual(url5?.mimeType, "image/png")
XCTAssertEqual(url6?.mimeType, "text/html")
XCTAssertEqual(url7?.mimeType, "video/mp4")
}
}

0 comments on commit 7d61572

Please sign in to comment.