Tiny http server engine written in Swift programming language.

Last update: May 21, 2022

Platform Swift Protocols CocoaPods Carthage Compatible

What is Swifter?

Tiny http server engine written in Swift programming language.

Branches

* stable - lands on CocoaPods and others. Supports the latest non-beta Xcode and SPM. Stable.

* master - stable branch plus experimental web-framework layer.

* 2.0 - next version of Swifter (async IO). Experimental.

How to start?

let server = HttpServer()
server["/hello"] = { .ok(.htmlBody("You asked for \($0)"))  }
server.start()

How to load HTML by string?

let server = HttpServer()
server[path] = { request in
    return HttpResponse.ok(.text("<html string>"))
}
server.start()

How to share files?

let server = HttpServer()
server["/desktop/:path"] = shareFilesFromDirectory("/Users/me/Desktop")
server.start()

How to redirect?

let server = HttpServer()
server["/redirect"] = { request in
  return .movedPermanently("http://www.google.com")
}
server.start()

How to HTML ?

let server = HttpServer()
server["/my_html"] = scopes { 
  html {
    body {
      h1 { inner = "hello" }
    }
  }
}
server.start()

How to WebSockets ?

let server = HttpServer()
server["/websocket-echo"] = websocket(text: { session, text in
  session.writeText(text)
}, binary: { session, binary in
  session.writeBinary(binary)
})
server.start()

CocoaPods? Yes.

use_frameworks!

pod 'Swifter', '~> 1.5.0'

Carthage? Also yes.

github "httpswift/swifter" ~> 1.5.0

Swift Package Manager.

import PackageDescription

let package = Package(
    name: "MyServer",
    dependencies: [
        .package(url: "https://github.com/httpswift/swifter.git", .upToNextMajor(from: "1.5.0"))
    ]
)

Docker.

docker run -d -p 9080:9080 -v `pwd`:/Swifter -w /Swifter --name Swifter swift bash -c "swift run"

GitHub

https://github.com/httpswift/swifter
Comments
  • 1. Compilation in Xcode 12 beta fails with version 1.4.7 from SPM

    Hi, when I try to compile for iOS Simulator a project where I use Swifter 1.4.7 (via SPM) with Xcode 12, I get the following error:
    /Path/To/Project/SourcePackages/checkouts/swifter/XCode/Sources/Socket+File.swift:26:61: Generic parameter 'Element' could not be inferred

    image

    The version from stable works without issues.

    Reviewed by lecksfrawen at 2020-06-23 05:02
  • 2. Sinatra

    Are you planning to or know of any efforts to create a Swift framework inspired by Ruby's Sinatra?

    I see this has some similarities but wondered if you planned to take it further?

    Reviewed by jchannon at 2015-06-09 16:35
  • 3. Swift Compiler Error: cannot invoke 'subscript'

    After fixing some of the compile issues on Xcode 6 (mostly dealing with NSError initializers), I'm getting the following error:

    <unknown>:0: error: cannot invoke 'subscript' with an argument list of type '($T5, Builtin.RawPointer)'
    <unknown>:0: error: cannot invoke 'subscript' with an argument list of type '($T5, Builtin.RawPointer)'
    
    Reviewed by AquaGeek at 2014-10-22 19:49
  • 4. What is the correct way to link an external style sheet file

    Hi, I created a /Resources/Web directory as "Folder references" under my project root directory. The structure is shown below:

    -Web:
      -css:
        bootstrap.min.css
      -js:
        index.html
    

    The html can be retrieved with html = NSData(contentsOfFile:"\(rootDir)/Web/index.html") and shown in the browser, but linking to external css failed in the Chrome console.

    Below is the link tag in my index.html. I am wondering why it not works.

    <head>
    <link rel="stylesheet" type="text/css" href="css/bootstrap.min.css">
    ...
    </head>
    

    If above is not an option, does that mean css files also need to be retrieved like html files and then insert the css text into the head place of the html text, and return?

    Thanks very much! Roman

    Reviewed by roman-yu at 2016-01-05 03:11
  • 5. How can I use it for upload a file to my device

    If I change the login.html, for example: add a 'file' type input and change the form enctype to 'multipart/form-data' . How can I handler the request and write a (or multiple) file to document folder?

    Reviewed by elepone at 2015-03-23 09:08
  • 6. Regression on v1.4.6

    Hello! I am experiencing a regression on v1.4.6.

    Consider the following code.

    // Path Declaration
    var path: String {
            switch self {
            case .postOnboardingDocCheckFinishSuccess:
                return "onboarding/doc-check/finish"
            case .postOnboardingDocCheckStartSuccess:
                return "onboarding/doc-check/start"
            default:
                return "onboarding"
            }
        }
    
    // Path registration
    enum Method {
        case DELETE
        case PATCH
        case HEAD
        case POST
        case GET
        case PUT
    }
    
    protocol EndPoint {
        var method: Method { get }
        var path: String { get }
        var response: ((HttpRequest) -> HttpResponse) { get }
    }
    
    protocol JSONFileRepresentable {
        var fileName: String { get }
    }
    
    class Router {
        let server: HttpServer
        
        init() {
            server = HttpServer()
        }
        
        func stop() {
            server.stop()
        }
        
        func start() {
            try! server.start()
        }
        
        func setUp(with endPoints: [EndPoint]) {
            endPoints.forEach({
                switch $0.method {
                case .GET:
                    server.GET[$0.path] = $0.response
                case .POST:
                    server.POST[$0.path] = $0.response
                case .PUT:
                    server.PUT[$0.path] = $0.response
                case .DELETE:
                    server.DELETE[$0.path] = $0.response
                default:
                    fatalError("Method not yet supported")
                }
            })
        }
    }
    

    Registering only Onboarding success. Calls the response block normally. But registering all 3 paths makes onboarding to return 404 not found. This is part of a testing suite and it started falling after updating to v1.4.6

    It works fine on v1.4.5

    Reviewed by sonic555gr at 2019-04-30 09:11
  • 7. server.start() doesn't actually do anything

    When trying to run the following code (more or less copied from the readme)

    import Swifter
    import Foundation
    
    func createServer() -> HttpServer {
      let server = HttpServer()
    
      server["/hello"] = { request in .ok(.text("Hey")) }
    
      return server
    }
    
    
    let myServer = createServer()
    try myServer.start()
    

    The HTTP server doesn't actually start. Like, I can run swift build just fine, but actually executing the compiled binary just starts and exits normally. I would assume this isn't supposed to happen, but I can't find anything in the documentation about how one should actually start the server (the documentation also fails to mention that you need to have try before server.start()).

    Reviewed by jalavosus at 2019-03-27 19:40
  • 8. How do I add different responses based on request GET parameters?

    So is there a way to make different responses for different parameters? Im using Swifter to mock server responses and it would be great to response differently based on request’ GET parameters, but I can’t really figure how to add such responses

    Reviewed by AndrewSad at 2018-01-10 13:43
  • 9. compile errors with swift 4.1 and xcode 9.3

    I am trying to update my app from swift 3 to swift for 4 and getting compile errors on Scopes.swift on scope() "Missing argument for parameter #1 in call, public typealias Closure = (Void) -> Void "When calling this function in Swift 4 or later, you must pass a '()' tuple; did you mean for the input type to be '()'?"

    I created a small test app with just the swifter pod and getting the same thing.

    I am using xcode 9.3, in build settings I have tried setting the Swift Language Version to unspecified and Swift 4.1 but I am getting the same errors when I do a Product clean and then Product Build My podfile has: pod 'Swifter', '~> 1.3.3'

    Reviewed by benchd at 2018-04-03 10:37
  • 10. Not actually an issue just a question. How to obtain the request ip address?

    Thank you for making Swifter available for everyone. I apologize I don't mean to use you as a support agent, but I was wondering, is there any way to obtain the request ip address?

    I wanted to ask one more thing, in my case I need a small web server to send and receive plain text and not to share files or webpages. Is swifter ideal for this scenario? I'm sorry I'm not very versed in this matter.

    Reviewed by oncre at 2015-03-26 19:17
  • 11. releaseAcceptSocket() doesn't cut availability of the server

    The stop() / releaseAcceptSocket() methods don't seem to shut the server down. It is still available after I called the method. Is there a way to shut it completely down or did I misinterpreted the meaning of those? Thank you!

    Reviewed by RGreinacher at 2015-06-04 00:02
  • 12. usleep degrades when using Swifter

    I have the following server:

    import SwiftUI
    import Swifter
    
    @main
    struct MacInputServer: App {
        let server: HttpServer;
    
        var body: some Scene {
            WindowGroup {
                ContentView()
            }
        }
    
        func sleep(req: HttpRequest) -> HttpResponse {
            usleep(100_000);
            return .ok(.text(""))
        }
    
        init() {
            server = HttpServer()
            server["/sleep"] = sleep
            try! server.start(999, forceIPv4: true, priority: DispatchQoS.QoSClass.userInteractive);
        }
    }
    

    I'm running while true; do time curl localhost:999/sleep; done to test it. The first ~100 requests finish in about 120ms as expected. But after that it starts hanging for up to 10 seconds:

    curl localhost:999/sleep  0.01s user 0.01s system 11% cpu 0.118 total
    curl localhost:999/sleep  0.01s user 0.01s system 0% cpu 10.121 total
    curl localhost:999/sleep  0.01s user 0.01s system 0% cpu 5.134 total
    curl localhost:999/sleep  0.00s user 0.01s system 0% cpu 5.902 total
    

    If I just sleep in a loop, the performance stays consistent, so this is definitely the fault of Swifter. How can this be fixed?

    Reviewed by monkekode at 2022-05-12 18:07
  • 13. Bump git from 1.8.1 to 1.11.0

    Bumps git from 1.8.1 to 1.11.0.

    Release notes

    Sourced from git's releases.

    Release v1.11.0

    Full Changelog

    • 292087e Supress unneeded test output (#570)
    • 19dfe5e Add support for fetch options "--force/-f" and "--prune-tags/-P". (#563)
    • 018d919 Fix bug when grepping lines that contain numbers surrounded by colons (#566)
    • c04d16e remove from maintainer (#567)
    • 291ca09 Address command line injection in Git::Lib#fetch
    • 521b8e7 Release v1.10.2 (#561)

    Release v1.10.2

    Full Changelog

    • 57f941c Release v1.10.2
    • c987a74 Add create-release, setup, and console dev scripts (#560)
    • 12e3d03 Store tempfile objects to prevent deletion during tests (#555)

    Release v1.10.1

    Full Changelog

    • c7b12af Release v1.10.1
    • ea28118 Properly escape double quotes in shell commands on Windows (#552)
    • db060fc Properly unescape diff paths (#504)
    • ea47044 Add Ruby 3.0 to CI build (#547)
    • cb01d2b Create a Docker image to run the changelog (#546)

    v.1.10.0

    Full Changelog

    • 8acec7d Release v1.10.0 (#545)
    • 8feb4ff Refactor directory initialization (#544)
    • 3884314 Add -ff option to git clean (#529)
    • 984ff7f #533 Add --depth options for fetch call (#534)
    • 6cba37e Add support for git init --initial-branch=main argument (#539)
    • ff98c42 Add support for the git merge --no-commit argument (#538)
    • 1023f85 Require pathname module (#536)

    v1.9.1

    Full Changelog

    • 58100b0 Release v1.9.1 (#527)
    • 45aeac9 Fix the gpg_sign commit option (#525)

    v1.9.0

    Full Changelog

    • 07a1167 Release v1.9.0 (#524)
    • 8fe479b Fix worktree test when git dir includes symlinks (#522)
    • 0cef8ac feat: add --gpg-sign option on commits (#518)
    • 765df7c Adds file option to config_set to allow adding to specific git-config files (#458)

    ... (truncated)

    Changelog

    Sourced from git's changelog.

    v1.11.0

    • 292087e Supress unneeded test output (#570)
    • 19dfe5e Add support for fetch options "--force/-f" and "--prune-tags/-P". (#563)
    • 018d919 Fix bug when grepping lines that contain numbers surrounded by colons (#566)
    • c04d16e remove from maintainer (#567)
    • 291ca09 Address command line injection in Git::Lib#fetch
    • 521b8e7 Release v1.10.2 (#561)

    See https://github.com/ruby-git/ruby-git/releases/tag/v1.11.0

    v1.10.2

    See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.2

    1.10.1

    See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.1

    1.10.0

    See https://github.com/ruby-git/ruby-git/releases/tag/v1.10.0

    1.9.1

    See https://github.com/ruby-git/ruby-git/releases/tag/v1.9.1

    1.9.0

    See https://github.com/ruby-git/ruby-git/releases/tag/v1.9.0

    Commits
    • 546bc03 Release v1.11.0
    • 292087e Supress unneeded test output (#570)
    • 19dfe5e Add support for fetch options "--force/-f" and "--prune-tags/-P". (#563)
    • 018d919 Fix bug when grepping lines that contain numbers surrounded by colons (#566)
    • c04d16e remove from maintainer (#567)
    • 291ca09 Address command line injection in Git::Lib#fetch
    • 521b8e7 Release v1.10.2 (#561)
    • c987a74 Add create-release, setup, and console dev scripts (#560)
    • 12e3d03 Store tempfile objects to prevent deletion during tests (#555)
    • 735b083 Release v1.10.1 (#553)
    • Additional commits viewable in compare view

    Dependabot compatibility score

    Dependabot will resolve any conflicts with this PR as long as you don't alter it yourself. You can also trigger a rebase manually by commenting @dependabot rebase.


    Dependabot commands and options

    You can trigger Dependabot actions by commenting on this PR:

    • @dependabot rebase will rebase this PR
    • @dependabot recreate will recreate this PR, overwriting any edits that have been made to it
    • @dependabot merge will merge this PR after your CI passes on it
    • @dependabot squash and merge will squash and merge this PR after your CI passes on it
    • @dependabot cancel merge will cancel a previously requested merge and block automerging
    • @dependabot reopen will reopen this PR if it is closed
    • @dependabot close will close this PR and stop Dependabot recreating it. You can achieve the same result by closing it manually
    • @dependabot ignore this major version will close this PR and stop Dependabot creating any more for this major version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this minor version will close this PR and stop Dependabot creating any more for this minor version (unless you reopen the PR or upgrade to it yourself)
    • @dependabot ignore this dependency will close this PR and stop Dependabot creating any more for this dependency (unless you reopen the PR or upgrade to it yourself)
    • @dependabot use these labels will set the current labels as the default for future PRs for this repo and language
    • @dependabot use these reviewers will set the current reviewers as the default for future PRs for this repo and language
    • @dependabot use these assignees will set the current assignees as the default for future PRs for this repo and language
    • @dependabot use this milestone will set the current milestone as the default for future PRs for this repo and language

    You can disable automated security fix PRs for this repo from the Security Alerts page.

    Reviewed by dependabot[bot] at 2022-04-28 22:13
  • 14. LICENSE file contains placeholder text.

    The "{organization}" should be replaced.

    Or updated with something like this: "Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission."

    Reviewed by chockenberry at 2022-04-17 22:09
  • 15. how can shareFilesFromDirectory support files in subdirectory?

        let docsPath = Bundle.main.resourcePath! + "/dist.bundle"
        server["/:path"] = shareFilesFromDirectory(docsPath, defaults: ["index.html"])
        try! server.start(13001)
    

    test: curl http://127.0.0.1:13001/index.html working curl http://127.0.0.1:13001/ not working, but is this suppose to load the index.html in the directory? curl http://127.0.0.1:13001/_next/static/chunks/framework-xx.js all not woking?

    How can I make files in subdirectorys work?

    Reviewed by zhouhesheng at 2022-03-04 06:17
  • 16. Proper versioning?

    I see last release is 1.5.0, but stable branch has a lot of changes. Can you please make a new version with them so everybody can refer to it? Thanks.

    Reviewed by beefon at 2022-01-19 13:54
Super lightweight async HTTP server library in pure Swift runs in iOS / MacOS / Linux

Embassy Super lightweight async HTTP server in pure Swift. Please read: Embedded web server for iOS UI testing. See also: Our lightweight web framewor

May 12, 2022
A Swift web framework and HTTP server.
A Swift web framework and HTTP server.

A Swift Web Framework and HTTP Server Summary Kitura is a web framework and web server that is created for web services written in Swift. For more inf

May 23, 2022
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)
Server-side Swift. The Perfect core toolset and framework for Swift Developers. (For mobile back-end development, website and API development, and more…)

Perfect: Server-Side Swift 简体中文 Perfect: Server-Side Swift Perfect is a complete and powerful toolbox, framework, and application server for Linux, iO

May 22, 2022
💧 A server-side Swift web framework.
💧 A server-side Swift web framework.

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

May 23, 2022
Lightweight library for web server applications in Swift on macOS and Linux powered by coroutines.
Lightweight library for web server applications in Swift on macOS and Linux powered by coroutines.

Why Zewo? • Support • Community • Contributing Zewo Zewo is a lightweight library for web applications in Swift. What sets Zewo apart? Zewo is not a w

May 17, 2022
Meet Corvus, the first strongly declarative server-side framework.
Meet Corvus, the first strongly declarative server-side framework.

Corvus Corvus is the first truly declarative server-side framework for Swift. It provides a declarative, composable syntax which makes it easy to get

Jan 29, 2022
Super lightweight web framework in Swift based on SWSGI

Ambassador Super lightweight web framework in Swift based on SWSGI Features Super lightweight Easy to use, designed for UI automatic testing API mocki

Mar 18, 2022
A Swift Multiplatform Single-threaded Non-blocking Web and Networking Framework
A Swift Multiplatform Single-threaded Non-blocking Web and Networking Framework

Serverside non-blocking IO in Swift Ask questions in our Slack channel! Lightning (formerly Edge) Node Lightning is an HTTP Server and TCP Client/Serv

Jan 29, 2022
Evented I/O streams for Swift
Evented I/O streams for Swift

Noze.io "Das Haus das Verrückte macht." Noze.io is an attempt to carry over the Node.js ideas into pure Swift. It uses libdispatch for event-driven, n

Apr 18, 2022
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

May 16, 2022
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

May 16, 2022
Tiny http server engine written in Swift programming language.

What is Swifter? Tiny http server engine written in Swift programming language. Branches * stable - lands on CocoaPods and others. Supports the latest

May 19, 2022
A light-weight server-side service framework written in the Swift programming language.

Smoke Framework The Smoke Framework is a light-weight server-side service framework written in Swift and using SwiftNIO for its networking layer by de

May 13, 2022
A repository for showcasing my knowledge of the Swift programming language, and continuing to learn the language.
A repository for showcasing my knowledge of the Swift programming language, and continuing to learn the language.

Learning Swift (programming language) I know very little about programming in the Swift programming language. This document will go over all my knowle

Nov 27, 2021
A repository for showcasing my knowledge of the Objective-C++ programming language, and continuing to learn the language.

Learning Objective-C-Plus-Plus I hardly know anything about the Objective-C++ programming language. This document will go over all of my knowledge of

Mar 27, 2022
A repository for showcasing my knowledge of the Objective-C programming language, and continuing to learn the language.
A repository for showcasing my knowledge of the Objective-C programming language, and continuing to learn the language.

Learning Objective-C I hardly know anything about the Objective-C programming language. This document will go over all of my knowledge of the Objectiv

Mar 8, 2022
Imagine Engine - a fast, high performance Swift 2D game engine for Apple's platforms
Imagine Engine - a fast, high performance Swift 2D game engine for Apple's platforms

Welcome to Imagine Engine, an ongoing project that aims to create a fast, high performance Swift 2D game engine for Apple's platforms that is also a j

May 15, 2022
Palico Engine: Metal-Based Game Engine in Swift 🐑
 Palico Engine: Metal-Based Game Engine in Swift 🐑

Palico Engine: Metal-Based Game Engine in Swift ?? Implement a game engine on macOS using Metal API. Still in development. Currently I am working on a

May 24, 2022
RSNetworking is a networking library written entirly for the Swift programming language.

RSNetworking is a networking library written entirly for the Swift programming language.

Feb 25, 2018
A parser combinator library written in the Swift programming language.

SwiftParsec SwiftParsec is a Swift port of the Parsec parser combinator library. It allows the creation of sophisticated parsers from a set of simple

Apr 8, 2022