diff --git a/.gitignore b/.gitignore index 52c62f0..7fb530a 100644 --- a/.gitignore +++ b/.gitignore @@ -2,4 +2,4 @@ /.build /Packages /*.xcodeproj -Sources/Prorsum/main.swift +Package.resolved diff --git a/.travis.yml b/.travis.yml index c8c08f9..9c26e62 100644 --- a/.travis.yml +++ b/.travis.yml @@ -3,8 +3,8 @@ os: - osx language: generic sudo: required -dist: trusty -osx_image: xcode9 +dist: xenial +osx_image: xcode10.3 install: - source Scripts/install-swift.sh diff --git a/Package.resolved b/Package.resolved deleted file mode 100644 index 7046498..0000000 --- a/Package.resolved +++ /dev/null @@ -1,34 +0,0 @@ -{ - "object": { - "pins": [ - { - "package": "CHTTPParser", - "repositoryURL": "https://github.com/Zewo/CHTTPParser.git", - "state": { - "branch": null, - "revision": "88306ab33bb316b2eedd39c90f4be8f4ebf65a11", - "version": "0.14.0" - } - }, - { - "package": "CLibreSSL", - "repositoryURL": "https://github.com/vapor/clibressl.git", - "state": { - "branch": null, - "revision": "23ddb296981d17a8ee6c7418742a40cad5d2f9d0", - "version": "1.0.0" - } - }, - { - "package": "ProrsumNet", - "repositoryURL": "https://github.com/noppoman/ProrsumNet.git", - "state": { - "branch": null, - "revision": "941e0c65df620467130e9eb2496a3c1275c1d307", - "version": "0.1.3" - } - } - ] - }, - "version": 1 -} diff --git a/Package.swift b/Package.swift index 83d578e..649525c 100644 --- a/Package.swift +++ b/Package.swift @@ -1,4 +1,4 @@ -// swift-tools-version:4.0 +// swift-tools-version:5.0 import PackageDescription let package = Package( @@ -8,8 +8,8 @@ let package = Package( .library(name: "Prorsum", targets: ["Prorsum"]) ], dependencies: [ - .package(url: "https://github.com/Zewo/CHTTPParser.git", .exact("0.14.0")), - .package(url: "https://github.com/noppoman/ProrsumNet.git", .upToNextMajor(from: "0.1.2")) + .package(url: "https://github.com/tuken/CHTTPParser.git", from: "0.15.0"), + .package(url: "https://github.com/tuken/ProrsumNet.git", from: "0.3.0"), ], targets: [ .target(name: "Prorsum", dependencies: ["CHTTPParser", "ProrsumNet"]), diff --git a/Package@swift-4.0.swift b/Package@swift-4.0.swift new file mode 100644 index 0000000..22f8f52 --- /dev/null +++ b/Package@swift-4.0.swift @@ -0,0 +1,19 @@ +// swift-tools-version:4.0 +import PackageDescription + +let package = Package( + name: "Prorsum", + products: [ + .executable(name: "prorsum-performance", targets: ["Performance"]), + .library(name: "Prorsum", targets: ["Prorsum"]) + ], + dependencies: [ + .package(url: "https://github.com/Zewo/CHTTPParser.git", .exact("0.14.0")), + .package(url: "https://github.com/tuken/ProrsumNet.git", from: "0.2.0"), + ], + targets: [ + .target(name: "Prorsum", dependencies: ["CHTTPParser", "ProrsumNet"]), + .target(name: "Performance", dependencies: ["Prorsum"]), + .testTarget(name: "ProrsumTests", dependencies: ["Prorsum"]) + ] +) diff --git a/Scripts/install-swift.sh b/Scripts/install-swift.sh index 7546ada..37e15b5 100755 --- a/Scripts/install-swift.sh +++ b/Scripts/install-swift.sh @@ -1,6 +1,6 @@ #!/usr/bin/env bash -VERSION="4.0" +VERSION="5.0.3" # Determine OS UNAME=`uname`; @@ -11,9 +11,9 @@ else if [[ $UNAME == "Linux" ]]; then UBUNTU_RELEASE=`lsb_release -a 2>/dev/null`; - if [[ $UBUNTU_RELEASE == *"15.10"* ]]; + if [[ $UBUNTU_RELEASE == *"16.04"* ]]; then - OS="ubuntu1510"; + OS="ubuntu1604"; else OS="ubuntu1404"; fi @@ -24,9 +24,9 @@ if [[ $OS != "macos" ]]; then sudo apt-get install -y clang libicu-dev uuid-dev - if [[ $OS == "ubuntu1510" ]]; + if [[ $OS == "ubuntu1604" ]]; then - SWIFTFILE="swift-$VERSION-RELEASE-ubuntu15.10"; + SWIFTFILE="swift-$VERSION-RELEASE-ubuntu16.04"; else SWIFTFILE="swift-$VERSION-RELEASE-ubuntu14.04"; fi diff --git a/Sources/Prorsum/HTTP/MediaType/MediaType.swift b/Sources/Prorsum/HTTP/MediaType/MediaType.swift index 8b1208d..bc5097c 100644 --- a/Sources/Prorsum/HTTP/MediaType/MediaType.swift +++ b/Sources/Prorsum/HTTP/MediaType/MediaType.swift @@ -52,14 +52,14 @@ public struct MediaType : CustomStringConvertible { var parameters: [String: String] = [:] if mediaTypeTokens.count == 2 { - let parametersTokens = mediaTypeTokens[1].trim().split(separator: " ") + let parametersTokens = mediaTypeTokens[1].trimmingCharacters(in: .whitespacesAndNewlines).split(separator: " ") for parametersToken in parametersTokens { let parameterTokens = parametersToken.split(separator: "=") if parameterTokens.count == 2 { - let key = parameterTokens[0] - let value = parameterTokens[1] + let key = String(parameterTokens[0]) + let value = String(parameterTokens[1]) parameters[key] = value } } @@ -103,9 +103,14 @@ extension Collection where Self.Iterator.Element == MediaType { } extension MediaType : Hashable { + public var hashValue: Int { return type.hashValue ^ subtype.hashValue } + + public func hash(into hasher: inout Hasher) { + hasher.combine(self.type.hashValue ^ self.subtype.hashValue) + } } public func == (lhs: MediaType, rhs: MediaType) -> Bool { diff --git a/Sources/Prorsum/HTTP/Message/AttributedCookie.swift b/Sources/Prorsum/HTTP/Message/AttributedCookie.swift index f4f4d0f..9f8698b 100644 --- a/Sources/Prorsum/HTTP/Message/AttributedCookie.swift +++ b/Sources/Prorsum/HTTP/Message/AttributedCookie.swift @@ -52,8 +52,8 @@ public struct AttributedCookie { return nil } - let name = cookieTokens[0] - let value = cookieTokens[1] + let name = String(cookieTokens[0]) + let value = String(cookieTokens[1]) var attributes: [CaseInsensitiveString: String] = [:] @@ -62,9 +62,9 @@ public struct AttributedCookie { switch attributeTokens.count { case 1: - attributes[CaseInsensitiveString(attributeTokens[0].trim())] = "" + attributes[CaseInsensitiveString(attributeTokens[0].trimmingCharacters(in: .whitespacesAndNewlines))] = "" case 2: - attributes[CaseInsensitiveString(attributeTokens[0].trim())] = attributeTokens[1].trim() + attributes[CaseInsensitiveString(attributeTokens[0].trimmingCharacters(in: .whitespacesAndNewlines))] = attributeTokens[1].trimmingCharacters(in: .whitespacesAndNewlines) default: return nil } @@ -98,9 +98,14 @@ public struct AttributedCookie { } extension AttributedCookie : Hashable { + public var hashValue: Int { return name.hashValue } + + public func hash(into hasher: inout Hasher) { + hasher.combine(self.name.hashValue) + } } public func == (lhs: AttributedCookie, rhs: AttributedCookie) -> Bool { diff --git a/Sources/Prorsum/HTTP/Message/Cookie.swift b/Sources/Prorsum/HTTP/Message/Cookie.swift index c25e22c..fac8c04 100644 --- a/Sources/Prorsum/HTTP/Message/Cookie.swift +++ b/Sources/Prorsum/HTTP/Message/Cookie.swift @@ -31,9 +31,14 @@ public struct Cookie : CookieProtocol { } extension Cookie : Hashable { + public var hashValue: Int { return name.hashValue } + + public func hash(into hasher: inout Hasher) { + hasher.combine(self.name.hashValue) + } } extension Cookie : Equatable {} @@ -64,7 +69,7 @@ extension Set where Element : CookieProtocol { return nil } - cookies.insert(Element(name: cookieTokens[0].trim(), value: cookieTokens[1].trim())) + cookies.insert(Element(name: cookieTokens[0].trimmingCharacters(in: .whitespacesAndNewlines), value: cookieTokens[1].trimmingCharacters(in: .whitespacesAndNewlines))) } self = cookies diff --git a/Sources/Prorsum/HTTP/Message/Request.swift b/Sources/Prorsum/HTTP/Message/Request.swift index 3d27f3b..ff0bdd9 100644 --- a/Sources/Prorsum/HTTP/Message/Request.swift +++ b/Sources/Prorsum/HTTP/Message/Request.swift @@ -182,7 +182,7 @@ extension Request { let acceptedTypeTokens = acceptedTypeString.split(separator: ";") if acceptedTypeTokens.count >= 1 { - let mediaTypeString = acceptedTypeTokens[0].trim() + let mediaTypeString = acceptedTypeTokens[0].trimmingCharacters(in: .whitespacesAndNewlines) if let acceptedMediaType = try? MediaType(string: mediaTypeString) { acceptedMediaTypes.append(acceptedMediaType) } diff --git a/Sources/Prorsum/HTTP/Message/Status.swift b/Sources/Prorsum/HTTP/Message/Status.swift index 30394e7..1991660 100644 --- a/Sources/Prorsum/HTTP/Message/Status.swift +++ b/Sources/Prorsum/HTTP/Message/Status.swift @@ -262,9 +262,14 @@ extension Response.Status { } extension Response.Status : Hashable { + public var hashValue: Int { return statusCode } + + public func hash(into hasher: inout Hasher) { + hasher.combine(self.statusCode) + } } public func ==(lhs: Response.Status, rhs: Response.Status) -> Bool { diff --git a/Sources/Prorsum/HTTP/Message/Versioin.swift b/Sources/Prorsum/HTTP/Message/Versioin.swift index edd94c6..d842afa 100644 --- a/Sources/Prorsum/HTTP/Message/Versioin.swift +++ b/Sources/Prorsum/HTTP/Message/Versioin.swift @@ -21,7 +21,9 @@ //SOFTWARE. public struct Version { + public var major: Int + public var minor: Int public init(major: Int, minor: Int) { @@ -31,9 +33,14 @@ public struct Version { } extension Version : Hashable { + public var hashValue: Int { return major ^ minor } + + public func hash(into hasher: inout Hasher) { + hasher.combine(self.major ^ self.minor) + } } extension Version : Equatable {} diff --git a/Sources/Prorsum/HTTP/Parser/Parser.swift b/Sources/Prorsum/HTTP/Parser/Parser.swift index d9f6b26..8090420 100644 --- a/Sources/Prorsum/HTTP/Parser/Parser.swift +++ b/Sources/Prorsum/HTTP/Parser/Parser.swift @@ -89,14 +89,6 @@ public final class MessageParser { } } - public func parse(_ from: DataRepresentable) throws -> [Message] { - let buffer = from.data - - return try buffer.withUnsafeBytes { - try self.parse(UnsafeBufferPointer(start: $0, count: buffer.count)) - } - } - public func parse(_ bytes: UnsafeBufferPointer) throws -> [Message] { let final = bytes.isEmpty let needsMessage: Bool diff --git a/Sources/Prorsum/HTTP/Serializer/RequestSerializer.swift b/Sources/Prorsum/HTTP/Serializer/RequestSerializer.swift index 3faafd8..55ed664 100644 --- a/Sources/Prorsum/HTTP/Serializer/RequestSerializer.swift +++ b/Sources/Prorsum/HTTP/Serializer/RequestSerializer.swift @@ -47,7 +47,8 @@ public struct RequestSerializer { switch request.body { case .buffer(let buffer): - try stream.write(buffer.bytes, deadline: deadline) +// try stream.write(buffer.withUnsafeBytes { [UInt8](UnsafeBufferPointer(start: $0, count: buffer.count)) }, deadline: deadline) + try stream.write([UInt8](buffer), deadline: deadline) case .reader(let reader): while !reader.isClosed { let buffer = try reader.read(upTo: bufferSize, deadline: deadline) diff --git a/Sources/Prorsum/HTTP/Serializer/ResponseSerializer.swift b/Sources/Prorsum/HTTP/Serializer/ResponseSerializer.swift index 74952a5..2dbce20 100644 --- a/Sources/Prorsum/HTTP/Serializer/ResponseSerializer.swift +++ b/Sources/Prorsum/HTTP/Serializer/ResponseSerializer.swift @@ -41,11 +41,11 @@ public struct ResponseSerializer { header += "\r\n" - try stream.write(header.bytes, deadline: deadline) + try stream.write(Array(header.utf8), deadline: deadline) switch response.body { case .buffer(let buffer): - try stream.write(buffer.bytes, deadline: deadline) + try stream.write(buffer.withUnsafeBytes { [UInt8]($0) }, deadline: deadline) case .reader(let reader): while !reader.isClosed { let bytes = try reader.read(upTo: bufferSize, deadline: deadline) diff --git a/Sources/Prorsum/WebSocket/Client/WebSocketClient.swift b/Sources/Prorsum/WebSocket/Client/WebSocketClient.swift index 9e70914..b63fbad 100644 --- a/Sources/Prorsum/WebSocket/Client/WebSocketClient.swift +++ b/Sources/Prorsum/WebSocket/Client/WebSocketClient.swift @@ -25,7 +25,7 @@ public class WebSocketClient { } public func connect() throws { - let key = Data(bytes: Array(URandom().bytes(16))).base64EncodedString(options: []) + let key = Data(Array(URandom().bytes(16))).base64EncodedString(options: []) let headers: Headers = [ "Connection": "Upgrade", diff --git a/Sources/Prorsum/WebSocket/Data+WebsocketCompute.swift b/Sources/Prorsum/WebSocket/Data+WebsocketCompute.swift index 9fdf5a1..7d8569e 100644 --- a/Sources/Prorsum/WebSocket/Data+WebsocketCompute.swift +++ b/Sources/Prorsum/WebSocket/Data+WebsocketCompute.swift @@ -45,8 +45,8 @@ extension Data { let valuePointer = UnsafeMutablePointer.allocate(capacity: 1) valuePointer.pointee = number defer { - valuePointer.deinitialize() - valuePointer.deallocate(capacity: 1) + valuePointer.deinitialize(count: 1) + valuePointer.deallocate() } var bytes = [UInt8](repeating: 0, count: totalBytes) diff --git a/Sources/Prorsum/WebSocket/Frame.swift b/Sources/Prorsum/WebSocket/Frame.swift index 092062e..bacb236 100644 --- a/Sources/Prorsum/WebSocket/Frame.swift +++ b/Sources/Prorsum/WebSocket/Frame.swift @@ -170,8 +170,12 @@ struct Frame { let data = data.data let maskKey = maskKey.data - let op = (1 << 7) | (0 << 6) | (0 << 5) | (0 << 4) | opCode.rawValue - self.data.append(op) + let op7 = 1 << 7 + let op6 = 0 << 6 + let op5 = 0 << 5 + let op4 = 0 << 4 + var op = op7 | op6 | op5 | op4 | Int(opCode.rawValue) + self.data.append([UInt8](Data(bytes: &op, count: MemoryLayout.size))) let masked: Bool = maskKey.count == 4 let mask: UInt8 = masked ? 1 : 0 diff --git a/Sources/Prorsum/WebSocket/WebSocket.swift b/Sources/Prorsum/WebSocket/WebSocket.swift index 530156c..afd5584 100644 --- a/Sources/Prorsum/WebSocket/WebSocket.swift +++ b/Sources/Prorsum/WebSocket/WebSocket.swift @@ -356,13 +356,13 @@ public final class WebSocket { let frame = Frame(opCode: opCode, data: data, maskKey: maskKey) let data = frame.data - try stream.write(data.bytes, deadline: 5) + try stream.write(data.withUnsafeBytes { [UInt8]($0) }, deadline: 5) } public static func accept(_ key: String) -> String? { let hashed = sha1(Array((key + GUID).utf8)) - let encoded = Data(bytes: hashed).base64EncodedString(options: []) + let encoded = Data(hashed).base64EncodedString(options: []) return encoded }