HTTPHeaders.swift 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111
  1. //
  2. // HTTPHeaders.swift
  3. //
  4. // Copyright (c) 2014-2018 Alamofire Software Foundation (http://alamofire.org/)
  5. //
  6. // Permission is hereby granted, free of charge, to any person obtaining a copy
  7. // of this software and associated documentation files (the "Software"), to deal
  8. // in the Software without restriction, including without limitation the rights
  9. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  10. // copies of the Software, and to permit persons to whom the Software is
  11. // furnished to do so, subject to the following conditions:
  12. //
  13. // The above copyright notice and this permission notice shall be included in
  14. // all copies or substantial portions of the Software.
  15. //
  16. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  17. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  18. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  19. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  20. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  21. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  22. // THE SOFTWARE.
  23. //
  24. import Foundation
  25. public typealias HTTPHeaders = [String: String]
  26. // TODO: Make HTTPHeaders a real type.
  27. extension Dictionary where Key == String, Value == String {
  28. public static func authorization(withUsername username: String, password: String) -> HTTPHeaders {
  29. let credential = Data("\(username):\(password)".utf8).base64EncodedString()
  30. return ["Authorization": "Basic \(credential)"]
  31. }
  32. /// Creates default values for the "Accept-Encoding", "Accept-Language" and "User-Agent" headers.
  33. public static let defaultHTTPHeaders: HTTPHeaders = {
  34. // Accept-Encoding HTTP Header; see https://tools.ietf.org/html/rfc7230#section-4.2.3
  35. let acceptEncoding: String = {
  36. let encodings: [String]
  37. if #available(iOS 11.0, macOS 10.13, tvOS 11.0, watchOS 4.0, *) {
  38. encodings = ["br", "gzip", "deflate"]
  39. } else {
  40. encodings = ["gzip", "deflate"]
  41. }
  42. return encodings.enumerated().map { (index, encoding) in
  43. let quality = 1.0 - (Double(index) * 0.1)
  44. return "\(encoding);q=\(quality)"
  45. }.joined(separator: ", ")
  46. }()
  47. // Accept-Language HTTP Header; see https://tools.ietf.org/html/rfc7231#section-5.3.5
  48. let acceptLanguage = Locale.preferredLanguages.prefix(6).enumerated().map { (index, languageCode) in
  49. let quality = 1.0 - (Double(index) * 0.1)
  50. return "\(languageCode);q=\(quality)"
  51. }.joined(separator: ", ")
  52. // User-Agent Header; see https://tools.ietf.org/html/rfc7231#section-5.5.3
  53. // Example: `iOS Example/1.0 (org.alamofire.iOS-Example; build:1; iOS 10.0.0) Alamofire/4.0.0`
  54. let userAgent: String = {
  55. if let info = Bundle.main.infoDictionary {
  56. let executable = info[kCFBundleExecutableKey as String] as? String ?? "Unknown"
  57. let bundle = info[kCFBundleIdentifierKey as String] as? String ?? "Unknown"
  58. let appVersion = info["CFBundleShortVersionString"] as? String ?? "Unknown"
  59. let appBuild = info[kCFBundleVersionKey as String] as? String ?? "Unknown"
  60. let osNameVersion: String = {
  61. let version = ProcessInfo.processInfo.operatingSystemVersion
  62. let versionString = "\(version.majorVersion).\(version.minorVersion).\(version.patchVersion)"
  63. let osName: String = {
  64. #if os(iOS)
  65. return "iOS"
  66. #elseif os(watchOS)
  67. return "watchOS"
  68. #elseif os(tvOS)
  69. return "tvOS"
  70. #elseif os(macOS)
  71. return "macOS"
  72. #elseif os(Linux)
  73. return "Linux"
  74. #else
  75. return "Unknown"
  76. #endif
  77. }()
  78. return "\(osName) \(versionString)"
  79. }()
  80. let alamofireVersion: String = {
  81. guard
  82. let afInfo = Bundle(for: SessionManager.self).infoDictionary,
  83. let build = afInfo["CFBundleShortVersionString"]
  84. else { return "Unknown" }
  85. return "Alamofire/\(build)"
  86. }()
  87. return "\(executable)/\(appVersion) (\(bundle); build:\(appBuild); \(osNameVersion)) \(alamofireVersion)"
  88. }
  89. return "Alamofire"
  90. }()
  91. return ["Accept-Encoding": acceptEncoding,
  92. "Accept-Language": acceptLanguage,
  93. "User-Agent": userAgent]
  94. }()
  95. }