Swiftpack.co - Package - vapor/vapor
Vapor

Documentation Team Chat MIT License Continuous Integration Swift 5.2 Twitter


Vapor is a web framework for Swift. It provides a beautifully expressive and easy to use foundation for your next website, API, or cloud project.

Take a look at some of the awesome stuff created with Vapor.

💧 Community

Join the welcoming community of fellow Vapor developers on Discord.

🚀 Contributing

To contribute a feature or idea to Vapor, create an issue explaining your idea or bring it up on Discord.

If you find a bug, please create an issue.

If you find a security vulnerability, please contact security@vapor.codes as soon as possible.

💛 Sponsors

Support Vapor's development by becoming a sponsor.

Nodes Skelpo Transeo Gwynne Raskind Joannis Orlandos Kyle Browning Jari

💚 Backers

Support Vapor's development by becoming a backer.

analytics

Github

link
Stars: 19524

Releases

Array validation - 2020-10-07 00:15:16

This patch was authored and released by @tanner0101.

Adds support for validating nested arrays (#2473, #2238, fixes #2158).

Assuming the following User definition:

struct User: Codable {
    struct Hobby: Codable {
        var title: String
    }

    var hobbies: [Hobby]
}

Validations for User and its nested array of hobbies can be defined like so:

extension User: Validatable {
    static func validations(_ validations: inout Validations) {
        validations.add(each: "hobbies") { i, hobby in
            hobby.add("title", as: String.self, is: .characterSet(.alphanumerics + .whitespaces))
        }
    }
}

Note that the closure receives the items index i. This can be used to dynamically adjust validations depending on index:

validations.add(each: "hobbies") { i, hobby in
    // Don't validate first item.
    if i != 0 {
        hobby.add("title", as: String.self, is: .characterSet(.alphanumerics + .whitespaces))
    }
}

Also note how this method complements Validations.add(_:) (without the each parameter) for validating nested dictionaries:

struct User: Codable, Validatable {
    struct Hobby: Codable {
        var title: String
    }

    var hobby: Hobby

    static func validations(_ validations: inout Validations) {
        validations.add("hobbies") { hobby in
            hobby.add("title", as: String.self, is: .characterSet(.alphanumerics + .whitespaces))
        }
    }
}

OTP implementation - 2020-10-03 14:14:05

This patch was authored by @Craz1k0ek and released by @MrLotU.

Adds HOTP & TOTP support. (#2499)

The HOTP can be created as an object, or it can be statically generated once:

let key = SymmetricKey(size: .bits128)
let code = HOTP(key: key, digest: .sha1, digits: .six).generate(counter: 15)

HOTP.generate(key: key, digest: .sha1, digits: .six, counter: 15)

The TOTP can be created as an object, or it can be statically generated once:

let key = SymmetricKey(size: .bits128)
let code = TOTP(key: key, digest: .sha1, digits: .six, interval: 30).generate(time: Date())

TOTP.generate(key: key, digest: .sha1, digits: .six, interval: 30, time: Date())

Add static dotenv loading function that can be used outside of Application - 2020-10-01 10:08:16

This patch was authored and released by @JaapWijnen.
  • DotEnv files can be loaded before initializing application
  • Reduces boilerplate code when you want to bootstrap logging with environment variables loaded from a .env file
  • Can be loaded in similar fashion as Application or provide absolute and relative .env file locations using DotEnvFile.load(path: ...)
let env = try Environment.detect()
DotEnvFile.load(for: env)
LoggingSystem.bootstrap { label in 
   // use environment variables here (before application is initialized)
}
let app = Application(env)

Fix relative percent decoding in FileMiddleware - 2020-09-30 23:28:23

This patch was authored and released by @tanner0101.

Fixes an issue preventing FileMiddleware from detecting relative paths when percent encoded (#2500).

Default cookie's SameSite attribute to lax - 2020-09-24 09:27:51

This patch was authored by @t-ae and released by @0xTim.

Set a cookie's default SameSite attribute to lax.

This prevents warnings in browsers and stops functionality working when following redirects, cross site link or when browsers assume the attribute to be None, which requires Secure attribute(HTTPS only).

#2495

Fix Swift 5.3 trailing closure warnings - 2020-09-21 10:02:41

This patch was authored by @tanner0101 and released by @MrLotU.

Fixes warnings about trailing closure matching behavior changes in Swift 5.3 (#2485, #2484).

Fix crash related to setting nil hostname and port - 2020-08-27 10:58:47

This patch was authored by @dimitribouniol and released by @Joannis.

Fixes a crash that could occur if the configuration configures a hostname address with a nil host or port, and the server is started according to the default configuration (#2479, fixes #2478).

The doc comment for HTTPServer.Configuration.address also clarifies the usage of having a nil host or port when using a .hostname-based address.

Support for Unix Domain Sockets - 2020-08-20 07:32:12

This patch was authored by @dimitribouniol and released by @MrLotU.

Adds support for Unix Domain Sockets (#2471, #2226, #2371).

A server can be started using the serve command:

vapor run serve --unix-socket /tmp/vapor.socket

Alternatively, the app can be configured in code to connect to a socket:

app.http.server.configuration.unixDomainSocketPath = "/tmp/vapor.socket"

In either scenario, if a socket path is specified, it takes precedence over binding the server to a hostname/port. Note that TLS may be combined with this options if you wish the server to only listen to encrypted connections made to the socket file.

The socket file must not exist prior to starting the server. If one is left behind during an incomplete shutdown, however, and the app has permission to delete it, it will be overidden.

To assist with making connections to socket paths, URI.Scheme has a .httpUnixDomainSocket property.

try app.client.get(.init(scheme: .httpUnixDomainSocket, host: "/tmp/vapor.socket", path: "/foo"))

Server shutdown improvements - 2020-08-14 20:58:38

This patch was authored and released by @tanner0101.

Adds support for gracefully shutting down in-flight requests and idle keep-alive connections (#2472, fixes #2451).

  • In-flight requests will no longer respect connection: keep-alive after server shutdown is initiated.
  • Idle keep-alive connections will now be closed once server shutdown is initiated.
  • Adds new HTTPHeaders helper for working with connection header.
// Change to 'connection: close'.
if req.headers.connection == .keepAlive {
    req.headers.connection = .close
}

Update dependencies - 2020-08-12 17:48:18

This patch was authored and released by @tanner0101.

Updates to swift-nio 2.18, async-http-client 1.2, and swift-nio-http2 1.13 (#2470, #2467, fixes #2466).

  • Fixes any usages of deprecated methods.
  • Fixes a reentrancy bug causing "body stream deinit before closing" assertion that popped up in tests with latest dependencies.
  • Makes trace logs from the HTTP decoder more concise.

Fix decodeNil in URLEncodedFormDecoder's single value decoder - 2020-08-07 00:47:17

This patch was authored and released by @tanner0101.

Fixes an issue causing URLEncodedFormDecoder's single value decoder to not detect nil correctly (#2463, fixes #2460).

This could result in req.query.get throwing an error instead of returning nil if the key was missing.

// This code will now return `nil` instead of throwing if the key is missing.
// It will still throw an error if the value cannot be converted to an Int. 
let page = try req.query.get(Int?.self, at: "page")

Fix Xcode 12 beta 3 warnings - 2020-07-25 02:31:38

This patch was authored and released by @tanner0101.

Fixes Xcode 12 beta 3 warnings and disables some broken CI workflows (#2452).

Allow setting hostname for testable application - 2020-07-22 14:57:25

This patch was authored by @3a4oT and released by @tanner0101.

Adds .running(hostname: String, port: Int) method to allow configure testable application hostname (#2448).


try app.testable(method: .running(hostname: "127.0.0.1", port: 8080))

Make req.auth.require discardable - 2020-07-21 21:18:29

This patch was authored by @SpencerCurtis and released by @tanner0101.

Adds @discardableResult attribute to req.auth.require to allow ignoring the result without a warning (#2446, fixes #2428).

try req.auth.require(User.self) 

Fix array out of bounds error in StackTrace - 2020-07-21 15:55:26

This patch was authored by @klaas and released by @tanner0101.

Fixes an array out of bounds error in StackTrace.description(max:) (#2447).

Add webSocket route overload with array path - 2020-07-20 15:51:44

This patch was authored by @jshier and released by @tanner0101.

Adds a webSocket route overload that accepts an array instead of variadic path (#2445, #2434).

app.webSocket(["foo", "bar"]) { req, ws in 
    // Handle WebSocket client.
}

Fix misspelled property name of class Routes - 2020-07-17 14:54:51

This patch was authored by @wangyanxi and released by @tanner0101.

Fix misspelled property name of class Routes, change from caseInsenstive to caseInsensitive (#2435, fixes #2426).

The misspelled caseInsenstive is now marked as deprecated.

Add FileIO.writeFile - 2020-07-17 02:18:29

This patch was authored by @t-ae and released by @tanner0101.

Adds writeFile method to request's FileIO helper (#2418).

// Writes "hello" to /path/to/file.txt
// Returns a future indicating when the write has completed. 
req.fileio.writeFile(.init(string: "hello"), at: "/path/to/file.txt")

Add support for string interpolation to URI - 2020-07-16 17:24:27

This patch was authored by @dimitribouniol and released by @tanner0101.

Enables call sites that use URIs to allow for string literals that make use of interpolation (#2442).

app.get("hello") { req -> EventLoopFuture<String> in
    return req.client.get("\(Constants.basePath)/status")
    .flatMapThrowing { res throws in
        return "Hello, world!"
    }
}

Add validate(query:) method to Validatable protocol - 2020-07-16 17:15:02

This patch was authored by @odanylewycz and released by @tanner0101.

Adds validate(query:) method to Validatable protocol for validating decoded query parameters (#2419).

Previously, you could only validate the content that came from the request body. Now, this addition allows for validating decoded query parameters that conform to the Content protocol.

struct Hello: Content, Validatable {
    name: String?

    static func validations(_ validations: inout Validations) {
        validations.add("name", as: String.self, is: .alphanumeric)
    }
}

And the following URL, http://localhost:8080/model?name=Vapor, you can now validate the query parameter "name" as follows:

try Hello.validate(query: request)
let hello = try req.query.decode(Hello.self)

The existing content validation method validate(_:) has been renamed to validate(content:) to reduce ambiguity.

try Hello.validate(content: request)
let hello = try req.content.decode(Hello.self)

Add custom validation response example - 2020-07-16 15:43:43

This patch was authored and released by @tanner0101.

Adds a custom validation response example to tests and fixes access to some validator results (#2443).

Header directive parameter quoting - 2020-07-15 18:40:48

This patch was authored and released by @tanner0101.

Adds support for quoting HTTP header value directive parameters containing unsupported characters (#2411, fixes #2439).

For example:

- content-disposition: form-data; filename=foo bar
+ content-disposition: form-data; filename="foo bar"

Header directive parameter quoting - 2020-07-15 18:40:48

This patch was authored and released by @tanner0101.

Adds support for quoting HTTP header value directive parameters containing unsupported characters (#2411, fixes #2439).

For example:

- content-disposition: form-data; filename=foo bar
+ content-disposition: form-data; filename="foo bar"

Add require(_:) extension to Parameters. - 2020-07-15 16:44:34

This patch was authored by @ileitch and released by @tanner0101.

Adds a require(_:) helper to Parameters, allowing for more succinct parameter handling. (#2402)

Previously the optional case needed to be handled explicitly:

guard let name = req.parameters.get("name") else {
    throw Abort(.internalServerError)
}

Now it can be written as:

let name = try req.parameters.require("name")

Allow XCTAssertContent to rethrow errors - 2020-07-15 16:39:12

This patch was authored by @ileitch and released by @tanner0101.

Enables the use of XCTUnwrap within the XCTAssertContent closure (#2403).

Add non-variadic variants of RoutesBuilder group methods. - 2020-07-15 12:36:09

This patch was authored by @ileitch and released by @MrLotU.

This allows for route paths to be passed in as an array. (#2420)

routes.group(["users", ":userID"]) { lists in
    // ...
}

Add method for customizing log handler - 2020-07-14 23:52:07

This patch was authored by @tancred and released by @tanner0101.

Adds a new method for bootstrapping a custom log handler (#2348).

The new LoggingSystem.bootstrap method accepts a LogHandler factory. The detected logging level (configurable with --log or LOG_LEVEL) is passed to the closure.

LoggingSystem.bootstrap(from: &env) { logLevel in 
    MyLogHandler(logLevel: logLevel)
}

There is also a new helper for parsing Logger.Level from the environment.

let logLevel = Logger.Level.detect(from: &env)

Fix query content hooks - 2020-07-14 21:29:36

This patch was authored and released by @tanner0101.

Fixes an issue preventing Content hooks from running when using req.query (#2438, fixes #2416).

Content's beforeEncode and afterDecode now work as expected with URLQueryContainer.

Percent-encoded brackets in query strings - 2020-07-11 16:35:23

This patch was authored and released by @tanner0101.

Adds support for percent-encoded brackets in query strings (fixes #2383, #2384, #2432).

Percent-encoded square brackets are now parsed as array or dictionary delimiters in query strings. For example, both of the following query strings are now equivalent:

page[offset]=0&page[limit]=50
page%5Boffset%5D=0&page%5Blimit%5D=50

Both query strings can now be decoded by the following struct:

struct Info {
    struct Page {
        var offset: Int
        var limit: Int
    }
    let page: Page
}

Previously, the percent-encoded brackets were ignored during array and dictionary parsing.

This change brings Vapor 4's behavior in line with Vapor 3 and other frameworks.

Fix NIOSSL warning - 2020-07-10 19:18:38

This patch was authored and released by @tanner0101.

Fixes a warning caused by a change in NIOSSL 2.8.0 that made NIOSSLServerHandler's initializer non-throwing (#2431).