├── .gitignore ├── .swift-version ├── .travis.yml ├── LICENSE ├── Nest.podspec ├── Package.swift ├── README.md ├── Sources └── Nest.swift └── Specification.md /.gitignore: -------------------------------------------------------------------------------- 1 | /.build 2 | -------------------------------------------------------------------------------- /.swift-version: -------------------------------------------------------------------------------- 1 | 3.0 2 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: objective-c 2 | osx_image: xcode8 3 | script: 4 | - swiftc Sources/Nest.swift 5 | - pod lib lint 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2014, Kyle Fuller 2 | All rights reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 7 | 1. Redistributions of source code must retain the above copyright notice, this 8 | list of conditions and the following disclaimer. 9 | 2. Redistributions in binary form must reproduce the above copyright notice, 10 | this list of conditions and the following disclaimer in the documentation 11 | and/or other materials provided with the distribution. 12 | 13 | THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 14 | ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 15 | WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 16 | DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 17 | ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 18 | (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 19 | LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 20 | ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 21 | (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 22 | SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 23 | 24 | -------------------------------------------------------------------------------- /Nest.podspec: -------------------------------------------------------------------------------- 1 | Pod::Spec.new do |spec| 2 | spec.name = 'Nest' 3 | spec.version = '0.4.0' 4 | spec.summary = 'Swift Web Server Gateway Interface.' 5 | spec.homepage = 'https://github.com/nestproject/' 6 | spec.license = { :type => 'BSD', :file => 'LICENSE' } 7 | spec.author = { 'Kyle Fuller' => 'kyle@fuller.li' } 8 | spec.social_media_url = 'http://twitter.com/kylefuller' 9 | spec.source = { :git => 'https://github.com/nestproject/Nest.git', :tag => spec.version } 10 | spec.source_files = 'Sources/Nest.swift' 11 | spec.requires_arc = true 12 | spec.ios.deployment_target = '8.0' 13 | spec.osx.deployment_target = '10.9' 14 | end 15 | 16 | -------------------------------------------------------------------------------- /Package.swift: -------------------------------------------------------------------------------- 1 | import PackageDescription 2 | 3 | let package = Package( 4 | name: "Nest" 5 | ) 6 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Nest - Swift Web Server Gateway Interface 2 | 3 | [![Build Status](https://img.shields.io/travis/nestproject/Nest/master.svg?style=flat)](https://travis-ci.org/nestproject/Nest) 4 | 5 | Nest provides a minimal interface between web servers supporting Swift and web applications or frameworks. It’s designed to prevent tight coupling between web servers and web applications or frameworks. To enable the use of any framework or application with any server. 6 | 7 | ## Quick Links 8 | 9 | - [Specification](Specification.md) 10 | - [Nest Enhancement Proposals](https://github.com/nestproject/neps) 11 | 12 | ## Current Status 13 | 14 | The specification is currently a draft, there are a couple of planned changes in the issue tracker and we welcome anyone to contribute to help improve the specification before we release version 1.0.0. We provide a proposal system allowing you to propose changes via [NEPs](https://github.com/nestproject/neps). 15 | 16 | ## Rationale and Goals 17 | 18 | The primary goal of Nest is to enable the use of any framework or application with any server. To prevent tight coupling between web servers and web applications or frameworks. 19 | 20 | Nest provides a minimal interface supporting every feature in HTTP. It must be extremely simple, and easy to implement for both servers and web applications. 21 | 22 | The interface must not make use any external frameworks and only depend on core Swift language features. 23 | 24 | ## Example Application 25 | 26 | A simple Hello World web application using the Nest interface: 27 | 28 | ```swift 29 | func application(request:RequestType) -> ResponseType { 30 | return Response(.Ok, body: "Hello World") 31 | } 32 | ``` 33 | 34 | ## Testing 35 | 36 | Along with providing a specification, Nest also provides a [test suite](https://github.com/nestproject/NestTestSuite) to ensure that a server correctly follows the specification, and to aid development of web servers. 37 | 38 | ## Implementations 39 | 40 | ### Web Servers 41 | 42 | - [Currasow](https://github.com/kylef/Curassow) - Pre-forking worker model server. 43 | - [http4swift](https://github.com/takebayashi/http4swift) 44 | - [NestBox](https://github.com/nestproject/NestBox) - Basic Server Implementation. 45 | 46 | ### Web Frameworks 47 | 48 | - [Frank](https://github.com/nestproject/Frank) - DSL for quickly writing web applications in Swift 49 | - [Turnstone](https://github.com/kylef/Turnstone) - URI Template Routing 50 | 51 | ### Other 52 | 53 | - [Inquiline](https://github.com/nestproject/Inquiline) - A standard implementation of RequestType and ResponseType. 54 | - [NestTest](http://github.com/nestproject/NestTest) 55 | - [Padlock](https://github.com/nestproject/Padlock) - Nest middleware to lockup your web application. 56 | 57 | ## See Also 58 | 59 | - [Python WSGI](https://www.python.org/dev/peps/pep-0333/) 60 | - [Ruby Rack](http://rack.github.io) 61 | - [Perl Web Server Gateway Interface](https://en.wikipedia.org/wiki/PSGI) 62 | 63 | ## License 64 | 65 | Nest is licensed under the BSD license. See [LICENSE](LICENSE) for more information. 66 | 67 | -------------------------------------------------------------------------------- /Sources/Nest.swift: -------------------------------------------------------------------------------- 1 | /// Represents a HTTP Header, Key and Value 2 | public typealias Header = (String, String) 3 | 4 | 5 | /// Represents a HTTP request or response body 6 | public protocol PayloadType { 7 | /// Returns the next byte in the payload 8 | mutating func next() -> [UInt8]? 9 | } 10 | 11 | 12 | /// Represents a HTTP Request 13 | public protocol RequestType { 14 | var method:String { get } 15 | var path:String { get } 16 | var headers:[Header] { get } 17 | var body: PayloadType? { get set } 18 | } 19 | 20 | 21 | /// Represents a HTTP Response 22 | public protocol ResponseType { 23 | var statusLine:String { get } 24 | var headers:[Header] { get } 25 | var body: PayloadType? { get set } 26 | } 27 | 28 | public typealias Application = (RequestType) -> (ResponseType) 29 | 30 | -------------------------------------------------------------------------------- /Specification.md: -------------------------------------------------------------------------------- 1 | --- 2 | Version: 0.3.0 3 | --- 4 | 5 | # Nest Specification 6 | 7 | There are two components that make up the Nest interface, the “server” or 8 | “gateway” component, and the “application” or “framework” component. 9 | 10 | The server component invokes the function that is provided by the application. 11 | 12 | ## Application 13 | 14 | A Nest application is a simple Swift function that takes exactly one argument, 15 | an object or structure that conforms to RequestType. It returns an instance 16 | of a ResponseType which contains exactly three values, the status, headers 17 | and the body. 18 | 19 | The full type of the application function is as follows: 20 | 21 | ```swift 22 | RequestType -> ResponseType 23 | ``` 24 | 25 | ## Server 26 | 27 | The server or gateway invokes the applications function once for each request 28 | from a client. 29 | 30 | ## PayloadType 31 | 32 | Payload type represents a streamable HTTP body, either for a request or 33 | response. 34 | 35 | ``` 36 | public protocol PayloadType { 37 | mutating func next() -> [UInt8]? 38 | } 39 | ``` 40 | 41 | ```swift 42 | public typealias Header = (String, String) 43 | ``` 44 | 45 | ## RequestType 46 | 47 | ```swift 48 | public protocol RequestType { 49 | var method:String { get } 50 | var path:String { get } 51 | var headers:[Header] { get } 52 | var body: PayloadType? { get set } 53 | } 54 | ``` 55 | 56 | ### ResponseType 57 | 58 | ```swift 59 | public protocol ResponseType { 60 | var statusLine:String { get } 61 | var headers:[Header] { get } 62 | var body: PayloadType? { get set } 63 | } 64 | ``` 65 | 66 | #### Status (`String`) 67 | 68 | This is an HTTP status. It must be a string containing a 3-digit integer result code followed by a reason phrase. For example, `200 OK`. 69 | 70 | #### Headers (`[(String, String)]`) 71 | 72 | The headers is an array of tuples containing the key and value for each HTTP header for the server to send in the returned order. 73 | 74 | #### Body (`String?`) 75 | 76 | The body must be a String or nil. 77 | 78 | --------------------------------------------------------------------------------