Compare commits

...

45 Commits

Author SHA1 Message Date
daltoniam df8d82047f 4.0.4 release 2020-08-01 15:04:10 -05:00
Dalton 85c8412646 Merge pull request #807 from varahash/conditional-zlib-dependency
Conditionally include 'swift-nio-zlib-support' dependency to avoid warning on macOS
2020-07-18 19:48:29 -05:00
Dalton 4820831260 Merge pull request #799 from amayers/xcode12
Fix compile error on Xcode 12
2020-07-18 19:47:50 -05:00
Dalton 024a27711e Merge pull request #808 from dvshelley/deployTarget9
move deployment target to iOS 9 to fix compile for archive with Xcode 12
2020-07-18 19:47:10 -05:00
Daniel Shelley 5987db1605 move deployment target to iOS 9 to fix compile for archive with Xcode 12 2020-07-16 16:50:35 -06:00
Mykola Varahash fe5769f2ae Conditionally include 'swift-nio-zlib-support' dependency to avoid warning on macOS 2020-07-13 01:35:26 +03:00
Andrew Mayers 263b9419bb Fix compile error on Xcode 12
Now you can build on both Xcode 11.5 & 12.0 b1.

On 12, the unit tests would fail to compile because it wasn't finding the `Starscream` framework. So I added `Starscream` as a dependency of the test target.

In `FoundationHTTPServerHandler` the `method` is of type `CFString`, while `getVerb` is `NSString`. Looks like Xcode 12 doesn't like equality comparison between those types without a cast as `NSString`.
2020-06-22 17:23:47 -04:00
Dalton 5fbeab4c12 Merge pull request #777 from jaltreuter/crash_after_disconnect
In FoundationTransport deinit, remove self as a delegate to InputStream and OutputStream to prevent EXC_BAD_ACCESS
2020-06-20 19:20:04 -05:00
Dalton 07bccd9c16 Merge pull request #790 from sdidla/fix_readLoop
Improve conditions for calling readLoop() and prevent infinite looping
2020-06-20 19:18:12 -05:00
Dalton 51b6c789bd Merge pull request #788 from SemyonBaryshev/master
Fix error when trying to convert text message partial payload to UTF-8
2020-06-20 19:15:56 -05:00
Dalton 0c7e7abfd7 Merge pull request #764 from ameyjain/fix/data-extension-swift-version-check
Fix the deadlock issue on iOS 11
2020-06-20 19:13:26 -05:00
Dalton d2f22783b6 Merge pull request #768 from michalsrutek/patch-1
Update README.md
2020-06-20 19:12:03 -05:00
Dalton e6236acc00 Merge pull request #797 from amayers/swift52
Switch SPM to use Swift 5.2
2020-06-20 19:11:18 -05:00
Dalton d003b62b54 Merge pull request #766 from urbanairship/fixUnsafeMutablePointerDeprecation
Fix deprecation warning in WSCompression
2020-06-20 19:07:41 -05:00
Andrew Mayers 70d9e6ec5c Switch SPM to use Swift 5.2 2020-06-17 09:52:36 -04:00
Shammi Didla c0e7d40284 improve conditions for calling readLoop() 2020-06-06 15:27:27 +02:00
Semyon Baryshev 06945ada8b Fix error when trying to convert text message partial payload to UTF-8 2020-06-05 18:39:16 +03:00
Jamie Altreuter 7e5a96341c In FoundationTransport deinit, remove self as a delegate to InputStream and OutputStream to prevent EXC_BAD_ACCESS 2020-05-12 18:14:25 -07:00
Michal Šrůtek ce4fcdc967 Update README.md
Update Autobahn link
2020-04-26 10:00:02 +02:00
Nick Ratelle da1d9c69a7 Fix deprecation warning in WSCompression
Apple recommends using the withUnsafeMutableBytes method on the buffer
to bind an unsafe pointer.
2020-04-21 17:54:17 -04:00
Amey Jain b6630118fe Fix the deadlock issue on iOS 11 2020-04-16 11:47:42 -04:00
daltoniam cfc7b7b8dc version bump 2020-04-08 19:59:30 -05:00
daltoniam 311b6dd9c7 fixes #760 2020-04-08 19:58:07 -05:00
daltoniam 339ca39461 improved native engine and a few bug fixes 2020-04-06 14:29:55 -05:00
Dalton 4e8973e3fc Merge pull request #697 from mikaryyn/feature/v4-refactor
Fix for a buffer overflow when close code has not been received from the socket
2020-04-06 14:16:00 -05:00
daltoniam 990a4c858e enabled native engine. Updated Changelog and README 2020-04-04 14:28:42 -05:00
Dalton 3b4c81547a Merge pull request #755 from dylanmaryk/patch-1
Fix "viabilityChanged" typos
2020-04-04 13:57:40 -05:00
Dalton 9e8fcba42e Merge pull request #749 from YellEngineering/feature/fix-foundation-transport-tls
Enable SSL in FoundationTransport for secure hosts
2020-04-04 13:57:16 -05:00
Dylan Maryk d84552f944 Fix typo 2020-03-27 17:54:35 +01:00
Dylan Maryk c3ac0a9df7 Fix typo 2020-03-27 17:50:56 +01:00
Nick Dowell 97538bc11d Enable SSL in FoundationTransport for secure hosts
This fixes connection to secure hosts such as
wss://echo.websocket.org
2020-03-11 16:03:14 +00:00
Patrick Maltagliati 4e8dca654d Use the host for evaluating trust, not the entire URL (#721)
* Use the host for evaluating trust, not the entire URL

* Get host from URLParts
2020-01-13 14:46:07 -06:00
Kristaps Grinbergs 547cb80ef6 Update Travis CI build (#723)
Update Travis CI build
2020-01-06 11:03:23 +02:00
Kristaps Grinbergs 12946fc610 Update Travis CI build 2020-01-06 10:43:29 +02:00
daltoniam 850f620441 resolved conflicts 2020-01-02 16:38:34 -06:00
daltoniam ced0725e4b update gem file to remove warnings 2020-01-02 16:37:50 -06:00
Dalton 9d1bac8ede Merge pull request #716 from TomasLinhart/macCatalystSupport
Add macCatalyst support
2020-01-02 16:09:54 -06:00
Dalton eb29f2a1f9 Merge pull request #713 from daltoniam/dependabot/bundler/rubyzip-1.3.0
Bump rubyzip from 1.2.2 to 1.3.0
2020-01-02 16:09:00 -06:00
Dalton 9cf7b4dfcb Merge pull request #718 from daltoniam/dependabot/bundler/excon-0.71.0
Bump excon from 0.64.0 to 0.71.0
2020-01-02 16:08:38 -06:00
Dalton 6b2742542c Merge pull request #653 from daltoniam/feature/v4-refactor
v4 Refactor Notice (WIP)
2020-01-02 15:57:37 -06:00
dependabot[bot] a986e38e56 Bump excon from 0.64.0 to 0.71.0
Bumps [excon](https://github.com/excon/excon) from 0.64.0 to 0.71.0.
- [Release notes](https://github.com/excon/excon/releases)
- [Changelog](https://github.com/excon/excon/blob/master/changelog.txt)
- [Commits](https://github.com/excon/excon/compare/v0.64.0...v0.71.0)

Signed-off-by: dependabot[bot] <support@github.com>
2019-12-16 22:06:19 +00:00
Tomas Linhart 692f3cb14a Allow running tests with macCatalyst 2019-11-25 16:53:23 +11:00
Tomas Linhart e8c0e894aa Add macCatalyst support 2019-11-25 16:44:01 +11:00
dependabot[bot] b7e98e147f Bump rubyzip from 1.2.2 to 1.3.0
Bumps [rubyzip](https://github.com/rubyzip/rubyzip) from 1.2.2 to 1.3.0.
- [Release notes](https://github.com/rubyzip/rubyzip/releases)
- [Changelog](https://github.com/rubyzip/rubyzip/blob/master/Changelog.md)
- [Commits](https://github.com/rubyzip/rubyzip/compare/v1.2.2...v1.3.0)

Signed-off-by: dependabot[bot] <support@github.com>
2019-11-14 12:24:24 +00:00
Mika Ryynänen 281a49edd8 Fix for a buffer overflow when close code has not been received from the socket. 2019-09-24 13:13:36 +03:00
24 changed files with 323 additions and 204 deletions
+1 -1
View File
@@ -1,4 +1,4 @@
osx_image: xcode11
osx_image: xcode11.3
language: objective-c
before_install:
- gem install cocoapods --pre
+38
View File
@@ -2,6 +2,44 @@
All notable changes to this project will be documented in this file.
`Starscream` adheres to [Semantic Versioning](http://semver.org/).
### [4.0.4](https://github.com/daltoniam/Starscream/tree/4.0.4)
Bug fixes for 4.0.3.
[#808](https://github.com/daltoniam/Starscream/pull/808)
[#807](https://github.com/daltoniam/Starscream/pull/807)
[#799](https://github.com/daltoniam/Starscream/pull/799)
[#797](https://github.com/daltoniam/Starscream/pull/797)
[#790](https://github.com/daltoniam/Starscream/pull/790)
[#788](https://github.com/daltoniam/Starscream/pull/788)
[#777](https://github.com/daltoniam/Starscream/pull/777)
[#768](https://github.com/daltoniam/Starscream/pull/768)
[#766](https://github.com/daltoniam/Starscream/pull/766)
[#764](https://github.com/daltoniam/Starscream/pull/764)
### [4.0.3](https://github.com/daltoniam/Starscream/tree/4.0.3)
Bug fixes for 4.0.2.
[#760](https://github.com/daltoniam/Starscream/issues/760)
### [4.0.2](https://github.com/daltoniam/Starscream/tree/4.0.2)
Bug fixes for 4.0.1. Fixed native engine is connected/disconnected. Native engine isn't the default since the API lacks features.
[#697](https://github.com/daltoniam/Starscream/pull/697)
### [4.0.1](https://github.com/daltoniam/Starscream/tree/4.0.1)
Bug fixes for 4.0.0. Enabled Native engine now that the API is out of beta and works properly.
[#749](https://github.com/daltoniam/Starscream/pull/749)
[#755](https://github.com/daltoniam/Starscream/pull/755)
### [4.0.0](https://github.com/daltoniam/Starscream/tree/4.0.0)
Major API refactor.
### [3.1.1](https://github.com/daltoniam/Starscream/tree/3.1.1)
Small version number fix for 3.1.0: [#703](https://github.com/daltoniam/Starscream/issues/703)
+64 -59
View File
@@ -1,47 +1,52 @@
GEM
remote: https://rubygems.org/
specs:
CFPropertyList (3.0.0)
CFPropertyList (3.0.2)
activesupport (4.2.11.1)
i18n (~> 0.7)
minitest (~> 5.1)
thread_safe (~> 0.3, >= 0.3.4)
tzinfo (~> 1.1)
addressable (2.6.0)
public_suffix (>= 2.0.2, < 4.0)
addressable (2.7.0)
public_suffix (>= 2.0.2, < 5.0)
algoliasearch (1.27.1)
httpclient (~> 2.8, >= 2.8.3)
json (>= 1.5.1)
atomos (0.1.3)
babosa (1.0.2)
claide (1.0.2)
cocoapods (1.6.1)
babosa (1.0.3)
claide (1.0.3)
cocoapods (1.8.4)
activesupport (>= 4.0.2, < 5)
claide (>= 1.0.2, < 2.0)
cocoapods-core (= 1.6.1)
cocoapods-deintegrate (>= 1.0.2, < 2.0)
cocoapods-core (= 1.8.4)
cocoapods-deintegrate (>= 1.0.3, < 2.0)
cocoapods-downloader (>= 1.2.2, < 2.0)
cocoapods-plugins (>= 1.0.0, < 2.0)
cocoapods-search (>= 1.0.0, < 2.0)
cocoapods-stats (>= 1.0.0, < 2.0)
cocoapods-trunk (>= 1.3.1, < 2.0)
cocoapods-trunk (>= 1.4.0, < 2.0)
cocoapods-try (>= 1.1.0, < 2.0)
colored2 (~> 3.1)
escape (~> 0.0.4)
fourflusher (>= 2.2.0, < 3.0)
fourflusher (>= 2.3.0, < 3.0)
gh_inspector (~> 1.0)
molinillo (~> 0.6.6)
nap (~> 1.0)
ruby-macho (~> 1.4)
xcodeproj (>= 1.8.1, < 2.0)
cocoapods-core (1.6.1)
xcodeproj (>= 1.11.1, < 2.0)
cocoapods-core (1.8.4)
activesupport (>= 4.0.2, < 6)
algoliasearch (~> 1.0)
concurrent-ruby (~> 1.1)
fuzzy_match (~> 2.0.4)
nap (~> 1.0)
cocoapods-deintegrate (1.0.4)
cocoapods-downloader (1.2.2)
cocoapods-downloader (1.3.0)
cocoapods-plugins (1.0.0)
nap
cocoapods-search (1.0.0)
cocoapods-stats (1.1.0)
cocoapods-trunk (1.3.1)
cocoapods-trunk (1.4.1)
nap (>= 0.8, < 2.0)
netrc (~> 0.11)
cocoapods-try (1.1.0)
@@ -53,21 +58,21 @@ GEM
declarative (0.0.10)
declarative-option (0.1.0)
digest-crc (0.4.1)
domain_name (0.5.20180417)
domain_name (0.5.20190701)
unf (>= 0.0.5, < 1.0.0)
dotenv (2.7.2)
dotenv (2.7.5)
emoji_regex (1.0.1)
escape (0.0.4)
excon (0.64.0)
faraday (0.15.4)
excon (0.71.1)
faraday (0.17.3)
multipart-post (>= 1.2, < 3)
faraday-cookie_jar (0.0.6)
faraday (>= 0.7.4)
http-cookie (~> 1.0.0)
faraday_middleware (0.13.1)
faraday (>= 0.7.4, < 1.0)
fastimage (2.1.5)
fastlane (2.122.0)
fastimage (2.1.7)
fastlane (2.139.0)
CFPropertyList (>= 2.3, < 4.0.0)
addressable (>= 2.3, < 3.0.0)
babosa (>= 1.0.2, < 2.0.0)
@@ -76,23 +81,23 @@ GEM
commander-fastlane (>= 4.4.6, < 5.0.0)
dotenv (>= 2.1.1, < 3.0.0)
emoji_regex (>= 0.1, < 2.0)
excon (>= 0.45.0, < 1.0.0)
faraday (~> 0.9)
excon (>= 0.71.0, < 1.0.0)
faraday (~> 0.17)
faraday-cookie_jar (~> 0.0.6)
faraday_middleware (~> 0.9)
faraday_middleware (~> 0.13.1)
fastimage (>= 2.1.0, < 3.0.0)
gh_inspector (>= 1.1.2, < 2.0.0)
google-api-client (>= 0.21.2, < 0.24.0)
google-api-client (>= 0.29.2, < 0.37.0)
google-cloud-storage (>= 1.15.0, < 2.0.0)
highline (>= 1.7.2, < 2.0.0)
json (< 3.0.0)
mini_magick (~> 4.5.1)
multi_json
jwt (~> 2.1.0)
mini_magick (>= 4.9.4, < 5.0.0)
multi_xml (~> 0.5)
multipart-post (~> 2.0.0)
plist (>= 3.1.0, < 4.0.0)
public_suffix (~> 2.0.0)
rubyzip (>= 1.2.2, < 2.0.0)
rubyzip (>= 1.3.0, < 2.0.0)
security (= 0.1.3)
simctl (~> 1.6.3)
slack-notifier (>= 2.0.0, < 3.0.0)
@@ -101,52 +106,52 @@ GEM
tty-screen (>= 0.6.3, < 1.0.0)
tty-spinner (>= 0.8.0, < 1.0.0)
word_wrap (~> 1.0.0)
xcodeproj (>= 1.8.1, < 2.0.0)
xcodeproj (>= 1.13.0, < 2.0.0)
xcpretty (~> 0.3.0)
xcpretty-travis-formatter (>= 0.0.3)
fourflusher (2.2.0)
fourflusher (2.3.1)
fuzzy_match (2.0.4)
gh_inspector (1.1.3)
google-api-client (0.23.9)
google-api-client (0.36.3)
addressable (~> 2.5, >= 2.5.1)
googleauth (>= 0.5, < 0.7.0)
googleauth (~> 0.9)
httpclient (>= 2.8.1, < 3.0)
mime-types (~> 3.0)
mini_mime (~> 1.0)
representable (~> 3.0)
retriable (>= 2.0, < 4.0)
signet (~> 0.9)
google-cloud-core (1.3.0)
signet (~> 0.12)
google-cloud-core (1.4.1)
google-cloud-env (~> 1.0)
google-cloud-env (1.0.5)
google-cloud-env (1.3.0)
faraday (~> 0.11)
google-cloud-storage (1.16.0)
google-cloud-storage (1.25.0)
addressable (~> 2.5)
digest-crc (~> 0.4)
google-api-client (~> 0.23)
google-api-client (~> 0.33)
google-cloud-core (~> 1.2)
googleauth (>= 0.6.2, < 0.10.0)
googleauth (0.6.7)
googleauth (~> 0.9)
mini_mime (~> 1.0)
googleauth (0.10.0)
faraday (~> 0.12)
jwt (>= 1.4, < 3.0)
memoist (~> 0.16)
multi_json (~> 1.11)
os (>= 0.9, < 2.0)
signet (~> 0.7)
signet (~> 0.12)
highline (1.7.10)
http-cookie (1.0.3)
domain_name (~> 0.5)
httpclient (2.8.3)
i18n (0.9.5)
concurrent-ruby (~> 1.0)
json (2.2.0)
json (2.3.0)
jwt (2.1.0)
memoist (0.16.0)
mime-types (3.2.2)
mime-types-data (~> 3.2015)
mime-types-data (3.2019.0331)
mini_magick (4.5.1)
minitest (5.11.3)
memoist (0.16.2)
mini_magick (4.9.5)
mini_mime (1.0.2)
minitest (5.13.0)
molinillo (0.6.6)
multi_json (1.13.1)
multi_json (1.14.1)
multi_xml (0.6.0)
multipart-post (2.0.0)
nanaimo (0.2.6)
@@ -163,14 +168,14 @@ GEM
retriable (3.1.2)
rouge (2.0.7)
ruby-macho (1.4.0)
rubyzip (1.2.2)
rubyzip (1.3.0)
security (0.1.3)
signet (0.11.0)
signet (0.12.0)
addressable (~> 2.3)
faraday (~> 0.9)
jwt (>= 1.5, < 3.0)
multi_json (~> 1.10)
simctl (1.6.5)
simctl (1.6.7)
CFPropertyList
naturally
slack-notifier (2.3.2)
@@ -178,19 +183,19 @@ GEM
terminal-table (1.8.0)
unicode-display_width (~> 1.1, >= 1.1.1)
thread_safe (0.3.6)
tty-cursor (0.6.1)
tty-screen (0.6.5)
tty-spinner (0.9.0)
tty-cursor (~> 0.6.0)
tzinfo (1.2.5)
tty-cursor (0.7.0)
tty-screen (0.7.0)
tty-spinner (0.9.2)
tty-cursor (~> 0.7)
tzinfo (1.2.6)
thread_safe (~> 0.1)
uber (0.1.0)
unf (0.1.4)
unf_ext
unf_ext (0.0.7.6)
unicode-display_width (1.5.0)
unicode-display_width (1.6.0)
word_wrap (1.0.0)
xcodeproj (1.9.0)
xcodeproj (1.14.0)
CFPropertyList (>= 2.3.3, < 4.0)
atomos (~> 0.1.3)
claide (>= 1.0.2, < 2.0)
@@ -209,4 +214,4 @@ DEPENDENCIES
fastlane
BUNDLED WITH
1.17.2
2.1.3
+6 -4
View File
@@ -1,4 +1,4 @@
// swift-tools-version:4.2
// swift-tools-version:5.2
//
// Package.Swift
@@ -27,11 +27,13 @@ let package = Package(
products: [
.library(name: "Starscream", targets: ["Starscream"])
],
dependencies: [
.package(url: "https://github.com/apple/swift-nio-zlib-support.git", from: "1.0.0")
],
dependencies: [],
targets: [
.target(name: "Starscream",
path: "Sources")
]
)
#if os(Linux)
package.dependencies.append(.package(url: "https://github.com/apple/swift-nio-zlib-support.git", from: "1.0.0"))
#endif
+17 -5
View File
@@ -4,7 +4,7 @@ Starscream is a conforming WebSocket ([RFC 6455](http://tools.ietf.org/html/rfc6
## Features
- Conforms to all of the base [Autobahn test suite](http://autobahn.ws/testsuite/).
- Conforms to all of the base [Autobahn test suite](https://crossbar.io/autobahn/).
- Nonblocking. Everything happens in the background, thanks to GCD.
- TLS/WSS support.
- Compression Extensions support ([RFC 7692](https://tools.ietf.org/html/rfc7692))
@@ -22,7 +22,9 @@ import Starscream
Once imported, you can open a connection to your WebSocket server. Note that `socket` is probably best as a property, so it doesn't get deallocated right after being setup.
```swift
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!)
var request = URLRequest(url: URL(string: "http://localhost:8080")!)
request.timeoutInterval = 5
socket = WebSocket(request: request)
socket.delegate = self
socket.connect()
```
@@ -50,7 +52,7 @@ func didReceive(event: WebSocketEvent, client: WebSocket) {
break
case .pong(_):
break
case .viablityChanged(_):
case .viabilityChanged(_):
break
case .reconnectSuggested(_):
break
@@ -150,6 +152,15 @@ let socket = WebSocket(request: request)
SSL Pinning is also supported in Starscream.
Allow Self-signed certificates:
```swift
var request = URLRequest(url: URL(string: "ws://localhost:8080/")!)
let pinner = FoundationSecurity(allowSelfSigned: true) // don't validate SSL certificates
let socket = WebSocket(request: request, certPinner: pinner)
```
TODO: Update docs on how to load certificates and public keys into an app bundle, use the builtin pinner and TrustKit.
### Compression Extensions
@@ -157,8 +168,9 @@ TODO: Update docs on how to load certificates and public keys into an app bundle
Compression Extensions ([RFC 7692](https://tools.ietf.org/html/rfc7692)) is supported in Starscream. Compression is enabled by default, however compression will only be used if it is supported by the server as well. You may enable or disable compression via the `.enableCompression` property:
```swift
socket = WebSocket(url: URL(string: "ws://localhost:8080/")!)
socket.enableCompression = false
var request = URLRequest(url: URL(string: "ws://localhost:8080/")!)
let compression = WSCompression()
let socket = WebSocket(request: request, compressionHandler: compression)
```
Compression should be disabled if your application is transmitting already-compressed, random, or other uncompressable data.
+10 -6
View File
@@ -147,10 +147,12 @@ class Decompressor {
strm.avail_in = CUnsignedInt(count)
repeat {
strm.next_out = UnsafeMutablePointer<UInt8>(&buffer)
strm.avail_out = CUnsignedInt(buffer.count)
buffer.withUnsafeMutableBytes { (bufferPtr) in
strm.next_out = bufferPtr.bindMemory(to: UInt8.self).baseAddress
strm.avail_out = CUnsignedInt(bufferPtr.count)
res = inflate(&strm, 0)
res = inflate(&strm, 0)
}
let byteCount = buffer.count - Int(strm.avail_out)
out.append(buffer, count: byteCount)
@@ -209,10 +211,12 @@ class Compressor {
strm.avail_in = CUnsignedInt(data.count)
repeat {
strm.next_out = UnsafeMutablePointer<UInt8>(&buffer)
strm.avail_out = CUnsignedInt(buffer.count)
buffer.withUnsafeMutableBytes { (bufferPtr) in
strm.next_out = bufferPtr.bindMemory(to: UInt8.self).baseAddress
strm.avail_out = CUnsignedInt(bufferPtr.count)
res = deflate(&strm, Z_SYNC_FLUSH)
res = deflate(&strm, Z_SYNC_FLUSH)
}
let byteCount = buffer.count - Int(strm.avail_out)
compressed.append(buffer, count: byteCount)
+5 -9
View File
@@ -27,22 +27,20 @@ import Foundation
internal extension Data {
struct ByteError: Swift.Error {}
#if swift(>=5.0)
func withUnsafeBytes<ResultType, ContentType>(_ completion: (UnsafePointer<ContentType>) throws -> ResultType) rethrows -> ResultType {
#if swift(>=5.0)
return try withUnsafeBytes {
return try withUnsafeBytes {
if let baseAddress = $0.baseAddress, $0.count > 0 {
return try completion(baseAddress.assumingMemoryBound(to: ContentType.self))
} else {
throw ByteError()
}
}
#else
return try withUnsafeBytes(completion)
#endif
}
#endif
#if swift(>=5.0)
mutating func withUnsafeMutableBytes<ResultType, ContentType>(_ completion: (UnsafeMutablePointer<ContentType>) throws -> ResultType) rethrows -> ResultType {
#if swift(>=5.0)
return try withUnsafeMutableBytes {
if let baseAddress = $0.baseAddress, $0.count > 0 {
return try completion(baseAddress.assumingMemoryBound(to: ContentType.self))
@@ -50,8 +48,6 @@ internal extension Data {
throw ByteError()
}
}
#else
return try withUnsafeMutableBytes(completion)
#endif
}
#endif
}
+88 -82
View File
@@ -6,85 +6,91 @@
// Copyright © 2019 Vluxe. All rights reserved.
//
//import Foundation
//
//@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
//public class NativeEngine: Engine {
// private var task: URLSessionWebSocketTask?
// weak var delegate: EngineDelegate?
//
// public init() {
// //TODO: I probably need to drop down into the NWConnection APIs to get this to work with all of Starscream's features
// //
// //NOTE: URLSessionWebSocketTask doesn't work with our ruby web server in the SimpleTest example.
// //It allows crashes. It works fine with https://echo.websocket.org in either http or https. Not sure why though
// //needs more debugging and probably needs radar filed.
// }
//
// public func register(delegate: EngineDelegate) {
// self.delegate = delegate
// }
//
// public func start(request: URLRequest) {
// task = URLSession.shared.webSocketTask(with: request)
// doRead()
// task?.resume()
// }
//
// public func stop(closeCode: UInt16) {
// let closeCode = URLSessionWebSocketTask.CloseCode(rawValue: Int(closeCode)) ?? .normalClosure
// task?.cancel(with: closeCode, reason: nil)
// }
//
// public func forceStop() {
// stop(closeCode: UInt16(URLSessionWebSocketTask.CloseCode.abnormalClosure.rawValue))
// }
//
// public func write(string: String, completion: (() -> ())?) {
// task?.send(.string(string), completionHandler: { (error) in
// completion?()
// })
// }
//
// public func write(data: Data, opcode: FrameOpCode, completion: (() -> ())?) {
// switch opcode {
// case .binaryFrame:
// task?.send(.data(data), completionHandler: { (error) in
// completion?()
// })
// case .textFrame:
// let text = String(data: data, encoding: .utf8)!
// write(string: text, completion: completion)
// case .ping:
// task?.sendPing(pongReceiveHandler: { (error) in
// completion?()
// })
// default:
// break //unsupported
// }
// }
//
// private func doRead() {
// task?.receive { [weak self] (result) in
// switch result {
// case .success(let message):
// switch message {
// case .string(let string):
// self?.broadcast(event: .text(string))
// case .data(let data):
// self?.broadcast(event: .binary(data))
// @unknown default:
// break
// }
// break
// case .failure(let error):
// self?.broadcast(event: .error(error))
// }
// self?.doRead()
// }
// }
//
// private func broadcast(event: WebSocketEvent) {
// delegate?.didReceive(event: event)
// }
//}
import Foundation
@available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *)
public class NativeEngine: NSObject, Engine, URLSessionDataDelegate, URLSessionWebSocketDelegate {
private var task: URLSessionWebSocketTask?
weak var delegate: EngineDelegate?
public func register(delegate: EngineDelegate) {
self.delegate = delegate
}
public func start(request: URLRequest) {
let session = URLSession(configuration: URLSessionConfiguration.default, delegate: self, delegateQueue: nil)
task = session.webSocketTask(with: request)
doRead()
task?.resume()
}
public func stop(closeCode: UInt16) {
let closeCode = URLSessionWebSocketTask.CloseCode(rawValue: Int(closeCode)) ?? .normalClosure
task?.cancel(with: closeCode, reason: nil)
}
public func forceStop() {
stop(closeCode: UInt16(URLSessionWebSocketTask.CloseCode.abnormalClosure.rawValue))
}
public func write(string: String, completion: (() -> ())?) {
task?.send(.string(string), completionHandler: { (error) in
completion?()
})
}
public func write(data: Data, opcode: FrameOpCode, completion: (() -> ())?) {
switch opcode {
case .binaryFrame:
task?.send(.data(data), completionHandler: { (error) in
completion?()
})
case .textFrame:
let text = String(data: data, encoding: .utf8)!
write(string: text, completion: completion)
case .ping:
task?.sendPing(pongReceiveHandler: { (error) in
completion?()
})
default:
break //unsupported
}
}
private func doRead() {
task?.receive { [weak self] (result) in
switch result {
case .success(let message):
switch message {
case .string(let string):
self?.broadcast(event: .text(string))
case .data(let data):
self?.broadcast(event: .binary(data))
@unknown default:
break
}
break
case .failure(let error):
self?.broadcast(event: .error(error))
}
self?.doRead()
}
}
private func broadcast(event: WebSocketEvent) {
delegate?.didReceive(event: event)
}
public func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didOpenWithProtocol protocol: String?) {
let p = `protocol` ?? ""
broadcast(event: .connected([HTTPWSHeader.protocolName: p]))
}
public func urlSession(_ session: URLSession, webSocketTask: URLSessionWebSocketTask, didCloseWith closeCode: URLSessionWebSocketTask.CloseCode, reason: Data?) {
var r = ""
if let d = reason {
r = String(data: d, encoding: .utf8) ?? ""
}
broadcast(event: .disconnected(r, UInt16(closeCode.rawValue)))
}
}
+7 -1
View File
@@ -125,7 +125,7 @@ FrameCollectorDelegate, HTTPHandlerDelegate {
case .failed(let error):
handleError(error)
case .viability(let isViable):
broadcast(event: .viablityChanged(isViable))
broadcast(event: .viabilityChanged(isViable))
case .shouldReconnect(let status):
broadcast(event: .reconnectSuggested(status))
case .receive(let data):
@@ -157,6 +157,12 @@ FrameCollectorDelegate, HTTPHandlerDelegate {
canSend = true
mutex.signal()
compressionHandler?.load(headers: headers)
if let url = request.url {
HTTPCookie.cookies(withResponseHeaderFields: headers, for: url).forEach {
HTTPCookieStorage.shared.setCookie($0)
}
}
broadcast(event: .connected(headers))
case .failure(let error):
handleError(error)
@@ -74,7 +74,7 @@ public class FoundationHTTPServerHandler: HTTPServerHandler {
return false //not enough data, wait for more
}
if let method = CFHTTPMessageCopyRequestMethod(response)?.takeRetainedValue() {
if method != getVerb {
if (method as NSString) != getVerb {
delegate?.didReceive(event: .failure(HTTPUpgradeError.invalidData))
return true
}
+7 -11
View File
@@ -84,19 +84,15 @@ public class FrameCollector {
}
buffer.append(payload)
frameCount += 1
if isText {
if String(data: buffer, encoding: .utf8) == nil {
let errCode = CloseCode.protocolError.rawValue
delegate?.didForm(event: .error(WSError(type: .protocolError, message: "not valid UTF-8 data", code: errCode)))
reset()
return
}
}
if frame.isFin {
if isText {
let string = String(data: buffer, encoding: .utf8) ?? ""
delegate?.didForm(event: .text(string))
if let string = String(data: buffer, encoding: .utf8) {
delegate?.didForm(event: .text(string))
} else {
let errCode = CloseCode.protocolError.rawValue
delegate?.didForm(event: .error(WSError(type: .protocolError, message: "not valid UTF-8 data", code: errCode)))
}
} else {
delegate?.didForm(event: .binary(buffer))
}
+3
View File
@@ -183,6 +183,9 @@ public class WSFramer: Framer {
closeCode = CloseCode.protocolError.rawValue
dataLength = 0
} else if payloadLen > 1 {
if pointer.count < 4 {
return .needsMoreData
}
let size = MemoryLayout<UInt16>.size
closeCode = pointer.readUint16(offset: offset)
offset += size
+7
View File
@@ -67,6 +67,13 @@ public struct HTTPWSHeader {
req.setValue(HTTPWSHeader.versionValue, forHTTPHeaderField: HTTPWSHeader.versionName)
req.setValue(secKeyValue, forHTTPHeaderField: HTTPWSHeader.keyName)
if let cookies = HTTPCookieStorage.shared.cookies(for: url), !cookies.isEmpty {
let headers = HTTPCookie.requestHeaderFields(with: cookies)
for (key, val) in headers {
req.setValue(val, forHTTPHeaderField: key)
}
}
if supportsCompression {
let val = "permessage-deflate; client_max_window_bits; server_max_window_bits=15"
req.setValue(val, forHTTPHeaderField: HTTPWSHeader.extensionName)
+3 -4
View File
@@ -101,10 +101,9 @@ public class StringHTTPHandler: HTTPHandler {
code = c
}
} else {
let responseSplit = str.components(separatedBy: ":")
guard responseSplit.count > 1 else { break }
let key = responseSplit[0].trimmingCharacters(in: .whitespaces)
let val = responseSplit[1].trimmingCharacters(in: .whitespaces)
guard let separatorIndex = str.firstIndex(of: ":") else { break }
let key = str.prefix(upTo: separatorIndex).trimmingCharacters(in: .whitespaces)
let val = str.suffix(from: str.index(after: separatorIndex)).trimmingCharacters(in: .whitespaces)
headers[key.lowercased()] = val
}
i += 1
+1 -1
View File
@@ -15,7 +15,7 @@
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>4.0.0</string>
<string>$(MARKETING_VERSION)</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
+5 -7
View File
@@ -82,7 +82,7 @@ public enum WebSocketEvent {
case pong(Data?)
case ping(Data?)
case error(Error?)
case viablityChanged(Bool)
case viabilityChanged(Bool)
case reconnectSuggested(Bool)
case cancelled
}
@@ -120,12 +120,10 @@ open class WebSocket: WebSocketClient, EngineDelegate {
self.engine = engine
}
public convenience init(request: URLRequest, certPinner: CertificatePinning? = FoundationSecurity(), compressionHandler: CompressionHandler? = nil) {
//TODO: will release once Xcode 11 is out of beta
// if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) {
// self.init(request: request, engine: NativeEngine())
// } else
if #available(macOS 10.14, iOS 12.0, watchOS 5.0, tvOS 12.0, *) {
public convenience init(request: URLRequest, certPinner: CertificatePinning? = FoundationSecurity(), compressionHandler: CompressionHandler? = nil, useCustomEngine: Bool = true) {
if #available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *), !useCustomEngine {
self.init(request: request, engine: NativeEngine())
} else if #available(macOS 10.14, iOS 12.0, watchOS 5.0, tvOS 12.0, *) {
self.init(request: request, engine: WSEngine(transport: TCPTransport(), certPinner: certPinner, compressionHandler: compressionHandler))
} else {
self.init(request: request, engine: WSEngine(transport: FoundationTransport(), certPinner: certPinner, compressionHandler: compressionHandler))
+12 -1
View File
@@ -47,7 +47,12 @@ public class FoundationTransport: NSObject, Transport, StreamDelegate {
onConnect = streamConfiguration
}
public func connect(url: URL, timeout: Double = 10, certificatePinning: CertificatePinning? = nil) {
deinit {
inputStream?.delegate = nil
outputStream?.delegate = nil
}
public func connect(url: URL, timeout: Double = 10, certificatePinning: CertificatePinning? = nil) {
guard let parts = url.getParts() else {
delegate?.connectionChanged(state: .failed(FoundationTransportError.invalidRequest))
return
@@ -66,6 +71,12 @@ public class FoundationTransport: NSObject, Transport, StreamDelegate {
inStream.delegate = self
outStream.delegate = self
if isTLS {
let key = CFStreamPropertyKey(rawValue: kCFStreamPropertySocketSecurityLevel)
CFReadStreamSetProperty(inStream, key, kCFStreamSocketSecurityLevelNegotiatedSSL)
CFWriteStreamSetProperty(outStream, key, kCFStreamSocketSecurityLevelNegotiatedSSL)
}
onConnect?(inStream, outStream)
isOpen = false
+11 -2
View File
@@ -66,7 +66,7 @@ public class TCPTransport: Transport {
sec_protocol_verify_complete(true)
return
}
pinner.evaluateTrust(trust: trust, domain: url.absoluteString, completion: { (state) in
pinner.evaluateTrust(trust: trust, domain: parts.host, completion: { (state) in
switch state {
case .success:
sec_protocol_verify_complete(true)
@@ -141,7 +141,16 @@ public class TCPTransport: Transport {
if let data = data {
s.delegate?.connectionChanged(state: .receive(data))
}
s.readLoop()
// Refer to https://developer.apple.com/documentation/network/implementing_netcat_with_network_framework
if let context = context, context.isFinal, isComplete {
return
}
if error == nil {
s.readLoop()
}
})
}
}
+1 -1
View File
@@ -1,6 +1,6 @@
Pod::Spec.new do |s|
s.name = "Starscream"
s.version = "4.0.0"
s.version = "4.0.4"
s.summary = "A conforming WebSocket RFC 6455 client library in Swift."
s.homepage = "https://github.com/daltoniam/Starscream"
s.license = 'Apache License, Version 2.0'
+32 -5
View File
@@ -38,6 +38,16 @@
BBB5ABE8215E2217005B48B6 /* WebSocket.swift in Sources */ = {isa = PBXBuildFile; fileRef = BBB5ABE4215E2217005B48B6 /* WebSocket.swift */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
6B0BE7AA24A157BB0051F7A7 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 6B3E79DD19D48B7F006071F7 /* Project object */;
proxyType = 1;
remoteGlobalIDString = 33CCF0841F5DDC030099B092;
remoteInfo = Starscream;
};
/* End PBXContainerItemProxy section */
/* Begin PBXFileReference section */
335FA2021F5DF71D00F6D2EC /* Starscream Tests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = "Starscream Tests.xctest"; sourceTree = BUILT_PRODUCTS_DIR; };
33CCF0921F5DDC030099B092 /* Starscream.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = Starscream.framework; sourceTree = BUILT_PRODUCTS_DIR; };
@@ -250,6 +260,7 @@
buildRules = (
);
dependencies = (
6B0BE7AB24A157BB0051F7A7 /* PBXTargetDependency */,
);
name = "Starscream Tests";
productName = StarscreamTests;
@@ -298,8 +309,8 @@
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
English,
en,
Base,
);
mainGroup = 6B3E79DC19D48B7F006071F7;
productRefGroup = 6B3E79E719D48B7F006071F7 /* Products */;
@@ -372,12 +383,21 @@
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
6B0BE7AB24A157BB0051F7A7 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 33CCF0841F5DDC030099B092 /* Starscream */;
targetProxy = 6B0BE7AA24A157BB0051F7A7 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin XCBuildConfiguration section */
335FA2001F5DF71D00F6D2EC /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "-";
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
@@ -388,6 +408,7 @@
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvos appletvsimulator macosx";
SUPPORTS_MACCATALYST = YES;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
@@ -400,12 +421,14 @@
buildSettings = {
APPLICATION_EXTENSION_API_ONLY = NO;
CLANG_ENABLE_MODULES = YES;
CODE_SIGN_IDENTITY = "-";
INFOPLIST_FILE = "$(SRCROOT)/Tests/Info.plist";
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
"LD_RUNPATH_SEARCH_PATHS[sdk=macosx*]" = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks @executable_path/../Frameworks @loader_path/../Frameworks";
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos appletvos appletvsimulator macosx";
SUPPORTS_MACCATALYST = YES;
SWIFT_INSTALL_OBJC_HEADER = NO;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
@@ -424,13 +447,15 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
MARKETING_VERSION = 4.0.4;
OTHER_LDFLAGS = "-all_load";
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
@@ -450,13 +475,15 @@
DYLIB_INSTALL_NAME_BASE = "@rpath";
INFOPLIST_FILE = "$(SRCROOT)/Sources/Info.plist";
INSTALL_PATH = "$(LOCAL_LIBRARY_DIR)/Frameworks";
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks @loader_path/Frameworks";
MACOSX_DEPLOYMENT_TARGET = 10.10;
MARKETING_VERSION = 4.0.4;
OTHER_LDFLAGS = "-all_load";
PRODUCT_BUNDLE_IDENTIFIER = "com.vluxe.$(PRODUCT_NAME:rfc1034identifier)";
PRODUCT_NAME = "$(TARGET_NAME)";
SKIP_INSTALL = YES;
SUPPORTS_MACCATALYST = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Owholemodule";
SWIFT_SWIFT3_OBJC_INFERENCE = Off;
SWIFT_VERSION = 5.0;
@@ -513,7 +540,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvos appletvsimulator watchsimulator watchos";
@@ -566,7 +593,7 @@
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 8.0;
IPHONEOS_DEPLOYMENT_TARGET = 9.0;
MTL_ENABLE_DEBUG_INFO = NO;
SUPPORTED_PLATFORMS = "iphonesimulator iphoneos macosx appletvos appletvsimulator watchsimulator watchos";
SWIFT_VERSION = 5.0;
+1 -1
View File
@@ -60,7 +60,7 @@ class FuzzingTests: XCTestCase {
print("reason: \(reason) code: \(code)")
case .error(_):
break
case .viablityChanged(_):
case .viabilityChanged(_):
break
case .reconnectSuggested(_):
break
@@ -44,7 +44,7 @@ class ViewController: UIViewController, WebSocketDelegate {
// }
// }
//https://echo.websocket.org
var request = URLRequest(url: URL(string: "http://localhost:8080")!)//https://localhost:8080
var request = URLRequest(url: URL(string: "http://localhost:8080")!) //https://localhost:8080
request.timeoutInterval = 5
socket = WebSocket(request: request)
socket.delegate = self
@@ -68,7 +68,7 @@ class ViewController: UIViewController, WebSocketDelegate {
break
case .pong(_):
break
case .viablityChanged(_):
case .viabilityChanged(_):
break
case .reconnectSuggested(_):
break
+1 -1
View File
@@ -20,7 +20,7 @@ or alternatively using `brew cask install fastlane`
```
fastlane ios release
```
Depoy new version
Deploy new version
----