Skip to content

Commit

Permalink
add Example and README.md
Browse files Browse the repository at this point in the history
  • Loading branch information
alephao committed Sep 19, 2024
1 parent 7cfbe66 commit 6d2e535
Show file tree
Hide file tree
Showing 11 changed files with 415 additions and 7 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@ DerivedData/
.swiftpm/configuration/registries.json
.swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata
.netrc
.swiftpm/
182 changes: 181 additions & 1 deletion Example/Package.resolved
Original file line number Diff line number Diff line change
@@ -1,6 +1,33 @@
{
"originHash" : "dbaa0cc854ccca734e0006243c75abcc401b6ee02e6c4341acbe3f185e761d6a",
"originHash" : "849d20d85fdb00eb5aebb6573fccee8963ef1dd68fa27dcd56ce7c46556f05fe",
"pins" : [
{
"identity" : "async-http-client",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/async-http-client.git",
"state" : {
"revision" : "6df8e1c17e68f0f93de2443b8c8cafca9ddcc89a",
"version" : "1.22.2"
}
},
{
"identity" : "hummingbird",
"kind" : "remoteSourceControl",
"location" : "https://github.com/hummingbird-project/hummingbird.git",
"state" : {
"revision" : "d4f792d209f02b26a17c0105751220da65207fb2",
"version" : "2.0.1"
}
},
{
"identity" : "swift-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-algorithms",
"state" : {
"revision" : "f6919dfc309e7f1b56224378b11e28bab5bccc42",
"version" : "1.2.0"
}
},
{
"identity" : "swift-argument-parser",
"kind" : "remoteSourceControl",
Expand All @@ -10,6 +37,33 @@
"version" : "1.5.0"
}
},
{
"identity" : "swift-async-algorithms",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-async-algorithms.git",
"state" : {
"revision" : "6ae9a051f76b81cc668305ceed5b0e0a7fd93d20",
"version" : "1.0.1"
}
},
{
"identity" : "swift-atomics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "9bf03ff58ce34478e66aaee630e491823326fd06",
"version" : "1.1.3"
}
},
{
"identity" : "swift-crypto",
"kind" : "remoteSourceControl",
Expand All @@ -18,6 +72,132 @@
"revision" : "81bee98e706aee68d39ed5996db069ef2b313d62",
"version" : "3.7.1"
}
},
{
"identity" : "swift-distributed-tracing",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-distributed-tracing.git",
"state" : {
"revision" : "11c756c5c4d7de0eeed8595695cadd7fa107aa19",
"version" : "1.1.1"
}
},
{
"identity" : "swift-http-types",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types.git",
"state" : {
"revision" : "ae67c8178eb46944fd85e4dc6dd970e1f3ed6ccd",
"version" : "1.3.0"
}
},
{
"identity" : "swift-log",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-log.git",
"state" : {
"revision" : "9cb486020ebf03bfa5b5df985387a14a98744537",
"version" : "1.6.1"
}
},
{
"identity" : "swift-metrics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-metrics.git",
"state" : {
"revision" : "e0165b53d49b413dd987526b641e05e246782685",
"version" : "2.5.0"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "9746cf80e29edfef2a39924a66731249223f42a3",
"version" : "2.72.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "d1ead62745cc3269e482f1c51f27608057174379",
"version" : "1.24.0"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "b5f7062b60e4add1e8c343ba4eb8da2e324b3a94",
"version" : "1.34.0"
}
},
{
"identity" : "swift-nio-ssl",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-ssl.git",
"state" : {
"revision" : "7b84abbdcef69cc3be6573ac12440220789dcd69",
"version" : "2.27.2"
}
},
{
"identity" : "swift-nio-transport-services",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"state" : {
"revision" : "38ac8221dd20674682148d6451367f89c2652980",
"version" : "1.21.0"
}
},
{
"identity" : "swift-numerics",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-numerics.git",
"state" : {
"revision" : "0a5bc04095a675662cf24757cc0640aa2204253b",
"version" : "1.0.2"
}
},
{
"identity" : "swift-sacoge-hummingbird",
"kind" : "remoteSourceControl",
"location" : "https://github.com/alephao/swift-sacoge-hummingbird.git",
"state" : {
"branch" : "09314f8",
"revision" : "09314f833c869c8b148457ccedd82c0f3f40fc6e"
}
},
{
"identity" : "swift-service-context",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-service-context.git",
"state" : {
"revision" : "0c62c5b4601d6c125050b5c3a97f20cce881d32b",
"version" : "1.1.0"
}
},
{
"identity" : "swift-service-lifecycle",
"kind" : "remoteSourceControl",
"location" : "https://github.com/swift-server/swift-service-lifecycle.git",
"state" : {
"revision" : "24c800fb494fbee6e42bc156dc94232dc08971af",
"version" : "2.6.1"
}
},
{
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "d2ba781702a1d8285419c15ee62fd734a9437ff5",
"version" : "1.3.2"
}
}
],
"version" : 3
Expand Down
10 changes: 9 additions & 1 deletion Example/Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,25 @@ import PackageDescription
let package = Package(
name: "Example",
platforms: [
.macOS(.v13),
.macOS(.v14),
],
products: [
.executable(name: "Example", targets: ["Example"]),
],
dependencies: [
.package(name: "swift-sacoge", path: "../"),
.package(url: "https://github.com/apple/swift-argument-parser.git", from: "1.3.0"),
.package(url: "https://github.com/hummingbird-project/hummingbird.git", from: "2.0.0"),
.package(url: "https://github.com/alephao/swift-sacoge-hummingbird.git", revision: "09314f8"),
],
targets: [
.executableTarget(
name: "Example",
dependencies: [
.product(name: "ArgumentParser", package: "swift-argument-parser"),
.product(name: "Hummingbird", package: "hummingbird"),
.product(name: "SacogeHummingbird", package: "swift-sacoge-hummingbird"),
],
plugins: [
.plugin(name: "SacogePlugin", package: "swift-sacoge"),
]
Expand Down
14 changes: 14 additions & 0 deletions Example/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
# Sacoge Hummingbird Example

This example server uses `Sacoge` and `Sacoge Hummingbird` to serve assets.

The server has a custom sacoge configuration [here](.sacoge) and sets up the `SacogeMiddleware` [here](Sources/Example/Application+build.swift). There is one route, the root route `/`. The root route serves an html document with an `<img>` element referencing `Asset.swift_png`.

## Running

* If you run in DEBUG mode (`swift run`), assets are served with `no-cache`
* If you run in RELEASE mode (`swift run -c release`), assets are served with an immutable cache policy

> ⚠️ **Xcode**: If you want to run the project on Xcode, you need to update the `Example` scheme, edit the scheme, go to `Run > Options > Working Directory` and set the value to the root of this project.
After startin the server, open [`localhost:8080`](http://localhost:8080), it serves the [`swift.png`](my_public_folder/swift.png) image, check the Network logs to and see Cache-Control header.
61 changes: 61 additions & 0 deletions Example/Sources/Example/Application+build.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
import Hummingbird
import Logging
import SacogeHummingbird

/// Application arguments protocol. We use a protocol so we can call
/// `buildApplication` inside Tests as well as in the App executable.
/// Any variables added here also have to be added to `App` in App.swift and
/// `TestArguments` in AppTest.swift
public protocol AppArguments {
var hostname: String { get }
var port: Int { get }
var logLevel: Logger.Level? { get }
}

// Request context used by application
typealias AppRequestContext = BasicRequestContext

/// Build application
/// - Parameter arguments: application arguments
public func buildApplication(_ arguments: some AppArguments) async throws
-> some ApplicationProtocol
{
let environment = Environment()
let logger = {
var logger = Logger(label: "Sacoge Example")
logger.logLevel =
arguments.logLevel ?? environment.get("LOG_LEVEL").map { Logger.Level(rawValue: $0) ?? .info }
?? .info
return logger
}()
let router = buildRouter()
let app = Application(
router: router,
configuration: .init(
address: .hostname(arguments.hostname, port: arguments.port),
serverName: "Sacoge Example"
),
logger: logger
)
return app
}

/// Build router
func buildRouter() -> Router<AppRequestContext> {
let router = Router(context: AppRequestContext.self)
// Add middleware
router.addMiddleware {
// logging middleware
LogRequestsMiddleware(.info)
SacogeMiddleware(
"my_public_folder",
externalToInternalMapping: Asset.externalToInternalMapping)
}

router.get("/") { _, _ -> Response in
return .html(htmlLayout("""
<img src="\(Asset.swift_png)">
"""))
}
return router
}
27 changes: 22 additions & 5 deletions Example/Sources/Example/Example.swift
Original file line number Diff line number Diff line change
@@ -1,10 +1,27 @@
// The Swift Programming Language
// https://docs.swift.org/swift-book
import ArgumentParser
import Hummingbird
import Logging

@main
struct Example {
static func main() throws {
dump(Asset.externalToInternalMapping)
struct Example: AsyncParsableCommand, AppArguments {
@Option(name: .shortAndLong)
var hostname: String = "127.0.0.1"

@Option(name: .shortAndLong)
var port: Int = 8080

@Option(name: .shortAndLong)
var logLevel: Logger.Level?

func run() async throws {
let app = try await buildApplication(self)
try await app.runService()
}
}

/// Extend `Logger.Level` so it can be used as an argument
#if hasFeature(RetroactiveAttribute)
extension Logger.Level: @retroactive ExpressibleByArgument {}
#else
extension Logger.Level: ExpressibleByArgument {}
#endif
13 changes: 13 additions & 0 deletions Example/Sources/Example/HtmlLayout.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
func htmlLayout(_ content: String) -> String {
"""
<!DOCTYPE html>
<html>
<head>
<title>sacoge example</title>
</head>
<body>
\(content)
</body>
</html>
"""
}
20 changes: 20 additions & 0 deletions Example/Sources/Example/Hummingbird+Html.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import Hummingbird

extension Response {
// Helper to respond with an HTML string
static func html(
status: HTTPResponse.Status = .ok,
extraHeaders: HTTPFields = [:],
_ htmlString: String
) -> Response {
var headers: HTTPFields = [
.contentType: MediaType.textHtml.description
]
headers.append(contentsOf: extraHeaders)
return .init(
status: .ok,
headers: headers,
body: .init(byteBuffer: .init(string: htmlString))
)
}
}
Empty file.
Binary file added Example/my_public_folder/swift.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading

0 comments on commit 6d2e535

Please sign in to comment.