Browse Source

Update package dependencies

tags/v1.0.0
Matthias Neeracher 4 years ago
parent
commit
e4d1659244
3 changed files with 84 additions and 8 deletions
  1. +8
    -8
      Package.swift
  2. +76
    -0
      Sources/GzipMiddleware/GzipMiddleware.swift
  3. +0
    -0
      Sources/GzipMiddleware/GzipStream.swift

+ 8
- 8
Package.swift View File

@@ -1,19 +1,19 @@
// swift-tools-version:4.0
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(
name: "GzipMiddleware",
products: [
.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: [
.target(name: "GzipMiddleware"),
.target(name: "GzipMiddleware", dependencies: ["Vapor", "ZIPFoundation"]),
]
)

+ 76
- 0
Sources/GzipMiddleware/GzipMiddleware.swift View File

@@ -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
}
}

+ 0
- 0
Sources/GzipMiddleware/GzipStream.swift View File


Loading…
Cancel
Save