Skip to content

Commit 4ded068

Browse files
authored
Add method to generate a random mask (apple#1824)
* add static method to generate a random mask * use SystemRandomNumberGenerator by default and add documentation * use WebSocketMaskingKey instead of Self to support Swift 5.0 * add tests for random masking key * add return keyword to support Swift 5.0 * run scripts/generate_linux_tests.rb * rename T to Generator * test SystemRandomNumberGenerator * Revert "test SystemRandomNumberGenerator" This reverts commit d9bdbe5. * work around thread sanitizer bug on Swift 5.3
1 parent d161bf6 commit 4ded068

File tree

4 files changed

+92
-0
lines changed

4 files changed

+92
-0
lines changed

Sources/NIOWebSocket/WebSocketFrame.swift

+22
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ public struct WebSocketMaskingKey {
5454
/// - parameters:
5555
/// - integer: The encoded network representation of the
5656
/// masking key.
57+
@usableFromInline
5758
internal init(networkRepresentation integer: UInt32) {
5859
self._key = (UInt8((integer & 0xFF000000) >> 24),
5960
UInt8((integer & 0x00FF0000) >> 16),
@@ -71,6 +72,27 @@ extension WebSocketMaskingKey: ExpressibleByArrayLiteral {
7172
}
7273
}
7374

75+
extension WebSocketMaskingKey {
76+
/// Returns a random masking key, using the given generator as a source for randomness.
77+
/// - Parameter generator: The random number generator to use when creating the
78+
/// new random masking key.
79+
/// - Returns: A random masking key
80+
@inlinable
81+
public static func random<Generator>(
82+
using generator: inout Generator
83+
) -> WebSocketMaskingKey where Generator: RandomNumberGenerator {
84+
return WebSocketMaskingKey(networkRepresentation: .random(in: UInt32.min...UInt32.max, using: &generator))
85+
}
86+
87+
/// Returns a random masking key, using the `SystemRandomNumberGenerator` as a source for randomness.
88+
/// - Returns: A random masking key
89+
@inlinable
90+
public static func random() -> WebSocketMaskingKey {
91+
var generator = SystemRandomNumberGenerator()
92+
return .random(using: &generator)
93+
}
94+
}
95+
7496
extension WebSocketMaskingKey: Equatable {
7597
public static func ==(lhs: WebSocketMaskingKey, rhs: WebSocketMaskingKey) -> Bool {
7698
return lhs._key == rhs._key

Tests/LinuxMain.swift

+1
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,7 @@ class LinuxMainRunnerImpl: LinuxMainRunner {
125125
testCase(WebSocketClientEndToEndTests.allTests),
126126
testCase(WebSocketFrameDecoderTest.allTests),
127127
testCase(WebSocketFrameEncoderTest.allTests),
128+
testCase(WebSocketMaskingKeyTests.allTests),
128129
testCase(WebSocketServerEndToEndTests.allTests),
129130
])
130131
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
//
15+
// WebSocketMaskingKeyTests+XCTest.swift
16+
//
17+
import XCTest
18+
19+
///
20+
/// NOTE: This file was generated by generate_linux_tests.rb
21+
///
22+
/// Do NOT edit this file directly as it will be regenerated automatically when needed.
23+
///
24+
25+
extension WebSocketMaskingKeyTests {
26+
27+
@available(*, deprecated, message: "not actually deprecated. Just deprecated to allow deprecated tests (which test deprecated functionality) without warnings")
28+
static var allTests : [(String, (WebSocketMaskingKeyTests) -> () throws -> Void)] {
29+
return [
30+
("testRandomMaskingKey", testRandomMaskingKey),
31+
("testRandomMaskingKeyIsNotAlwaysZero", testRandomMaskingKeyIsNotAlwaysZero),
32+
]
33+
}
34+
}
35+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
//===----------------------------------------------------------------------===//
2+
//
3+
// This source file is part of the SwiftNIO open source project
4+
//
5+
// Copyright (c) 2021 Apple Inc. and the SwiftNIO project authors
6+
// Licensed under Apache License v2.0
7+
//
8+
// See LICENSE.txt for license information
9+
// See CONTRIBUTORS.txt for the list of SwiftNIO project authors
10+
//
11+
// SPDX-License-Identifier: Apache-2.0
12+
//
13+
//===----------------------------------------------------------------------===//
14+
15+
import XCTest
16+
import NIO
17+
import NIOWebSocket
18+
19+
final class WebSocketMaskingKeyTests: XCTestCase {
20+
var generator = SystemRandomNumberGenerator()
21+
func testRandomMaskingKey() {
22+
let key = WebSocketMaskingKey.random(using: &generator)
23+
var buffer = ByteBuffer(bytes: [1, 2, 3, 4, 5, 6, 7, 8])
24+
buffer.webSocketMask(key)
25+
buffer.webSocketUnmask(key)
26+
XCTAssertEqual(buffer, ByteBuffer(bytes: [1, 2, 3, 4, 5, 6, 7, 8]))
27+
}
28+
29+
func testRandomMaskingKeyIsNotAlwaysZero() {
30+
XCTAssertTrue((0..<1000).contains { _ in
31+
WebSocketMaskingKey.random(using: &generator) != [0, 0, 0, 0]
32+
}, "at least 1 of 1000 random masking keys should not be all zeros")
33+
}
34+
}

0 commit comments

Comments
 (0)