Update package dependencies
This commit is contained in:
		@@ -1,19 +1,19 @@
 | 
				
			|||||||
// swift-tools-version:4.0
 | 
					// swift-tools-version:4.0
 | 
				
			||||||
import PackageDescription
 | 
					import PackageDescription
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#if os(macOS) || os(iOS) || os(watchOS) || os(tvOS)
 | 
					 | 
				
			||||||
let dependencies: [Package.Dependency] = []
 | 
					 | 
				
			||||||
#else
 | 
					 | 
				
			||||||
let dependencies: [Package.Dependency] = [.package(url: "https://github.com/IBM-Swift/CZlib.git", .exact("0.1.2"))]
 | 
					 | 
				
			||||||
#endif
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
let package = Package(
 | 
					let package = Package(
 | 
				
			||||||
    name: "GzipMiddleware",
 | 
					    name: "GzipMiddleware",
 | 
				
			||||||
    products: [
 | 
					    products: [
 | 
				
			||||||
        .library(name: "GzipMiddleware", targets: ["GzipMiddleware"])
 | 
					        .library(name: "GzipMiddleware", targets: ["GzipMiddleware"])
 | 
				
			||||||
    ],
 | 
					    ],
 | 
				
			||||||
	dependencies: dependencies,
 | 
						dependencies: [
 | 
				
			||||||
 | 
					        // 💧 A server-side Swift web framework.
 | 
				
			||||||
 | 
					        .package(url: "https://github.com/vapor/vapor.git", from: "3.0.0"),
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        // 🤐 Unzip archives
 | 
				
			||||||
 | 
					        .package(url: "https://github.com/microtherion/ZIPFoundation.git", .upToNextMajor(from: "0.9.7-µ"))
 | 
				
			||||||
 | 
					    ],
 | 
				
			||||||
    targets: [
 | 
					    targets: [
 | 
				
			||||||
        .target(name: "GzipMiddleware"),
 | 
					        .target(name: "GzipMiddleware", dependencies: ["Vapor", "ZIPFoundation"]),
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -0,0 +1,76 @@
 | 
				
			|||||||
 | 
					import HTTP
 | 
				
			||||||
 | 
					import Vapor
 | 
				
			||||||
 | 
					import gzip
 | 
				
			||||||
 | 
					import Foundation
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					public enum GzipMiddlewareError: Error {
 | 
				
			||||||
 | 
					    case unsupportedStreamType
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Client Gzip middlere:
 | 
				
			||||||
 | 
					/// 1. sets the "Accept-Encoding" header to "gzip"
 | 
				
			||||||
 | 
					/// 2. if the response has "Content-Encoding" == "gzip", uncompresses the body
 | 
				
			||||||
 | 
					public struct GzipClientMiddleware: Middleware {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public init() { }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public func respond(to request: Request, chainingTo next: Responder) throws -> Response {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        request.headers["Accept-Encoding"] = "gzip"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let response = try next.respond(to: request)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        guard response.headers["Content-Encoding"] == "gzip" else {
 | 
				
			||||||
 | 
					            return response
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let zipped = response.body
 | 
				
			||||||
 | 
					        switch zipped {
 | 
				
			||||||
 | 
					        case .data(let bytes):
 | 
				
			||||||
 | 
					            response.body = .data(Array(try Data(bytes: bytes).gzipUncompressed()))
 | 
				
			||||||
 | 
					        case .chunked(let chunker):
 | 
				
			||||||
 | 
					            response.body = .chunked({ (stream: ChunkStream) in
 | 
				
			||||||
 | 
					                let gzipStream = try GzipStream(mode: .uncompress, stream: stream.raw)
 | 
				
			||||||
 | 
					                try chunker(ChunkStream(stream: gzipStream))
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/// Server Gzip middlere:
 | 
				
			||||||
 | 
					/// 1. checks if the "Accept-Encoding" header contains "gzip"
 | 
				
			||||||
 | 
					/// 2. if so, compresses the body and sets the response header "Content-Encoding" to "gzip",
 | 
				
			||||||
 | 
					public struct GzipServerMiddleware: Middleware {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    private let shouldGzip: (_ request: Request) -> Bool
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /// The `shouldGzip` closure is asked for every request whether that request
 | 
				
			||||||
 | 
					    /// should allow response gzipping. Returns `true` always by default.
 | 
				
			||||||
 | 
					    public init(shouldGzip: @escaping (_ request: Request) -> Bool = { _ in true }) {
 | 
				
			||||||
 | 
					        self.shouldGzip = shouldGzip
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    public func respond(to request: Request, chainingTo next: Responder) throws -> Response {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let acceptsGzip = request.headers["Accept-Encoding"]?.contains("gzip") == true
 | 
				
			||||||
 | 
					        guard acceptsGzip && shouldGzip(request) else {
 | 
				
			||||||
 | 
					            return try next.respond(to: request)
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let response = try next.respond(to: request)
 | 
				
			||||||
 | 
					        response.headers["Content-Encoding"] = "gzip"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        let unzipped = response.body
 | 
				
			||||||
 | 
					        switch unzipped {
 | 
				
			||||||
 | 
					        case .data(let bytes):
 | 
				
			||||||
 | 
					            response.body = .data(Array(try Data(bytes: bytes).gzipCompressed()))
 | 
				
			||||||
 | 
					        case .chunked(let chunker):
 | 
				
			||||||
 | 
					            response.body = .chunked({ (stream: ChunkStream) in
 | 
				
			||||||
 | 
					                let gzipStream = try GzipStream(mode: .compress, stream: stream.raw)
 | 
				
			||||||
 | 
					                try chunker(ChunkStream(stream: gzipStream))
 | 
				
			||||||
 | 
					            })
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        return response
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user