Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

swift-nio server upgrade with latest swift-nio-extras library #10

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
37 changes: 23 additions & 14 deletions servers/swift-nio/ExampleServer/Package.resolved
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,17 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-atomics.git",
"state" : {
"revision" : "6c89474e62719ddcc1e9614989fff2f68208fe10",
"version" : "1.1.0"
"revision" : "cd142fd2f64be2100422d658e7411e39489da985",
"version" : "1.2.0"
}
},
{
"identity" : "swift-collections",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-collections.git",
"state" : {
"revision" : "937e904258d22af6e447a0b72c0bc67583ef64a2",
"version" : "1.0.4"
"revision" : "671108c96644956dddcd89dd59c203dcdb36cec7",
"version" : "1.1.4"
}
},
{
Expand All @@ -32,35 +32,44 @@
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-http-types",
"state" : {
"revision" : "39661f4ca82db8ad050cc060a471c8e2c542b24f",
"version" : "0.1.1"
"revision" : "ef18d829e8b92d731ad27bb81583edd2094d1ce3",
"version" : "1.3.1"
}
},
{
"identity" : "swift-nio",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio.git",
"state" : {
"revision" : "a2e487b77f17edbce9a65f2b7415f2f479dc8e48",
"version" : "2.57.0"
"revision" : "ba72f31e11275fc5bf060c966cf6c1f36842a291",
"version" : "2.79.0"
}
},
{
"identity" : "swift-nio-extras",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-extras.git",
"state" : {
"revision" : "2e9746cfc57554f70b650b021b6ae4738abef3e6",
"version" : "1.24.1"
}
},
{
"identity" : "swift-nio-http2",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-http2.git",
"state" : {
"revision" : "a8ccf13fa62775277a5d56844878c828bbb3be1a",
"version" : "1.27.0"
"revision" : "170f4ca06b6a9c57b811293cebcb96e81b661310",
"version" : "1.35.0"
}
},
{
"identity" : "swift-nio-transport-services",
"identity" : "swift-system",
"kind" : "remoteSourceControl",
"location" : "https://github.com/apple/swift-nio-transport-services.git",
"location" : "https://github.com/apple/swift-system.git",
"state" : {
"revision" : "41f4098903878418537020075a4d8a6e20a0b182",
"version" : "1.17.0"
"revision" : "c8a44d836fe7913603e246acab7c528c2e780168",
"version" : "1.4.0"
}
}
],
Expand Down
34 changes: 19 additions & 15 deletions servers/swift-nio/ExampleServer/Package.swift
Original file line number Diff line number Diff line change
@@ -1,33 +1,37 @@
// swift-tools-version: 5.7
// swift-tools-version: 5.8
// The swift-tools-version declares the minimum version of Swift required to build this package.

import PackageDescription

let package = Package(
name: "ExampleServer",
platforms: [
.macOS(.v10_15),
.macOS(.v10_15)
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio.git", from: "2.0.0"),
.package(url: "https://github.com/apple/swift-nio-transport-services.git", from: "1.13.0"),
.package(url: "https://github.com/apple/swift-nio.git", from: "2.32.0"),
.package(url: "https://github.com/apple/swift-nio-extras.git", from: "1.0.0"),
.package(url: "https://github.com/apple/swift-http-types.git", from: "1.0.0"),
.package(path: "../NIOResumableUpload"),
.package(path: "../NIOResumableUpload/Dependencies/NIOHTTPTypes"),
],

targets: [
// Targets are the basic building blocks of a package, defining a module or a test suite.
// Targets can depend on other targets in this package and products from dependencies.
.executableTarget(
name: "ExampleServer",
dependencies: [
.product(name: "NIO", package: "swift-nio"),
.product(name: "NIOExtras", package: "swift-nio-extras"),
.product(name: "NIOHTTP1", package: "swift-nio"),
.product(name: "NIOCore", package: "swift-nio"),
.product(name: "NIOHTTP1", package: "swift-nio"),
.product(name: "NIOTransportServices", package: "swift-nio-transport-services"),
.product(name: "NIOPosix", package: "swift-nio"),
.product(name: "HTTPTypes", package: "swift-http-types"),
.product(name: "NIOHTTPTypesHTTP1", package: "swift-nio-extras"),
.product(name: "NIOHTTPTypes", package: "swift-nio-extras"),
.product(name: "NIOResumableUpload", package: "NIOResumableUpload"),
.product(name: "NIOHTTPTypesHTTP1", package: "NIOHTTPTypes"),
.product(name: "NIOHTTPTypes", package: "NIOHTTPTypes"),
],
path: "Sources"),
]
),
.testTarget(
name: "ExampleServerTests",
dependencies: ["ExampleServer"],
path: "Tests/ExampleServerTests"
)
]
)
113 changes: 113 additions & 0 deletions servers/swift-nio/ExampleServer/Sources/ExampleServer/main.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,113 @@
import Foundation
import HTTPTypes
import NIOCore
import NIOHTTP1
import NIOHTTPTypes
import NIOHTTPTypesHTTP1
import NIOPosix
import NIOResumableUpload

let HOST = "127.0.0.1"
let PORT = 8080

@available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *)
final class UploadServerHandler: ChannelDuplexHandler {
typealias InboundIn = HTTPRequestPart
typealias OutboundIn = Never
typealias OutboundOut = HTTPResponsePart

let uploadDirectory: URL
var fileHandle: FileHandle? = nil

init() {
self.uploadDirectory = URL(fileURLWithPath: "uploads", isDirectory: true).standardized
try? FileManager.default.createDirectory(at: self.uploadDirectory, withIntermediateDirectories: true)
print("Upload directory created at \(self.uploadDirectory.path)")
}

func channelRead(context: ChannelHandlerContext, data: NIOAny) {
switch self.unwrapInboundIn(data) {
case .head(let request):
print("Received request head: \(request)")
switch request.method {
case .post, .put:
let fileName = UUID().uuidString
let url = self.uploadDirectory.appendingPathComponent(fileName, isDirectory: false).standardized
print("Generated file path: \(url.path)")
if url.path.hasPrefix(self.uploadDirectory.path) {
_ = FileManager.default.createFile(atPath: url.path, contents: nil)
self.fileHandle = try? FileHandle(forWritingTo: url)
print("Creating file at \(url.path)")
}
if self.fileHandle == nil {
print("Failed to create file handle")
let response = HTTPResponse(status: .badRequest)
self.write(context: context, data: self.wrapOutboundOut(.head(response)), promise: nil)
self.write(context: context, data: self.wrapOutboundOut(.end(nil)), promise: nil)
self.flush(context: context)
}
default:
print("Request method not implemented: \(request.method)")
let response = HTTPResponse(status: .notImplemented)
self.write(context: context, data: self.wrapOutboundOut(.head(response)), promise: nil)
self.write(context: context, data: self.wrapOutboundOut(.end(nil)), promise: nil)
self.flush(context: context)
}
case .body(let body):
do {
print("Received body data: \(body)")
try body.withUnsafeReadableBytes { buffer in
try fileHandle?.write(contentsOf: buffer)
}
} catch {
print("Failed to write data to file: \(error)")
exit(1)
}
case .end:
if let fileHandle = self.fileHandle {
do {
try fileHandle.close()
print("File closed successfully")
let response = HTTPResponse(status: .created)
self.write(context: context, data: self.wrapOutboundOut(.head(response)), promise: nil)
self.write(context: context, data: self.wrapOutboundOut(.end(nil)), promise: nil)
self.flush(context: context)
} catch {
print("Failed to close file handle: \(error)")
let response = HTTPResponse(status: .internalServerError)
self.write(context: context, data: self.wrapOutboundOut(.head(response)), promise: nil)
self.write(context: context, data: self.wrapOutboundOut(.end(nil)), promise: nil)
self.flush(context: context)
}
}
}
}
}

if #available(macOS 10.15.4, iOS 13.4, watchOS 6.2, tvOS 13.4, *) {
let uploadContext = HTTPResumableUploadContext(origin: "http://\(HOST):\(PORT)")
print("Upload context created with origin http://\(HOST):\(PORT)")

let group = MultiThreadedEventLoopGroup(numberOfThreads: System.coreCount)
let server = try ServerBootstrap(group: group).childChannelInitializer { channel in
channel.pipeline.configureHTTPServerPipeline().flatMap {
channel.pipeline.addHandlers([
HTTP1ToHTTPServerCodec(secure: false),
HTTPResumableUploadHandler(
context: uploadContext,
handlers: [
UploadServerHandler()
]
),
])
}
}
.bind(host: HOST, port: PORT)
.wait()

print("Server listening on \(HOST):\(PORT)")
try server.closeFuture.wait()
} else {
print("Unsupported OS")
exit(1)
}
80 changes: 0 additions & 80 deletions servers/swift-nio/ExampleServer/Sources/main.swift

This file was deleted.

Loading