├── .editorconfig ├── .git-blame-ignore-revs ├── .gitattributes ├── .github ├── ISSUE_TEMPLATE │ └── bug-report.md ├── PULL_REQUEST_TEMPLATE.md ├── actions │ └── pull_request_semver_label_checker │ │ └── action.yml ├── release.yml └── workflows │ ├── benchmarks.yml │ ├── cmake_tests.yml │ ├── cxx_interop.yml │ ├── macos_tests.yml │ ├── main.yml │ ├── pull_request.yml │ ├── pull_request_label.yml │ ├── static_sdk.yml │ ├── swift_6_language_mode.yml │ ├── swift_load_test_matrix.yml │ ├── swift_matrix.yml │ ├── swift_test_matrix.yml │ └── unit_tests.yml ├── .gitignore ├── .licenseignore ├── .mailfilter ├── .mailmap ├── .spi.yml ├── .swift-format ├── Benchmarks ├── .gitignore ├── Benchmarks │ ├── NIOCoreBenchmarks │ │ └── Benchmarks.swift │ └── NIOPosixBenchmarks │ │ ├── Benchmarks.swift │ │ ├── TCPEcho.swift │ │ ├── TCPEchoAsyncChannel.swift │ │ └── Util │ │ └── GlobalExecutor.swift ├── Package.swift └── Thresholds │ ├── 5.10 │ ├── NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json │ ├── NIOCoreBenchmarks.WaitOnPromise.p90.json │ ├── NIOPosixBenchmarks.TCPEcho.p90.json │ └── NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json │ ├── 6.0 │ ├── NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json │ ├── NIOPosixBenchmarks.TCPEcho.p90.json │ └── NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json │ ├── 6.1 │ ├── NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json │ ├── NIOPosixBenchmarks.TCPEcho.p90.json │ └── NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json │ ├── nightly-main │ ├── NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json │ ├── NIOPosixBenchmarks.TCPEcho.p90.json │ └── NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json │ └── nightly-next │ ├── NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json │ ├── NIOPosixBenchmarks.TCPEcho.p90.json │ └── NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── CONTRIBUTORS.txt ├── IntegrationTests ├── allocation-counter-tests-framework │ ├── run-allocation-counter.sh │ └── template │ │ ├── AtomicCounter │ │ ├── Package.swift │ │ └── Sources │ │ │ └── AtomicCounter │ │ │ ├── include │ │ │ └── atomic-counter.h │ │ │ └── src │ │ │ └── atomic-counter.c │ │ ├── HookedFunctionsDoHook │ │ ├── Package.swift │ │ └── Sources │ │ │ └── HookedFunctions │ │ │ ├── include │ │ │ └── hooked-functions.h │ │ │ └── src │ │ │ ├── hooked-functions-darwin.c │ │ │ └── hooked-functions-unix.c │ │ ├── HookedFunctionsDoNotHook │ │ ├── Package.swift │ │ └── Sources │ │ │ └── HookedFunctions │ │ │ ├── include │ │ │ └── hooked-functions.h │ │ │ └── src │ │ │ └── hooked-functions.c │ │ ├── Sources │ │ ├── bootstrapDoHook │ │ │ └── main.c │ │ └── bootstrapDoNotHook │ │ │ └── main.c │ │ └── scaffolding.swift ├── plugin_echo.sh ├── plugin_junit_xml.sh ├── run-single-test.sh ├── run-tests.sh ├── test_functions.sh ├── tests_01_http │ ├── defines.sh │ ├── test_01_get_file.sh │ ├── test_02_get_random_bytes.sh │ ├── test_03_post_random_bytes.sh │ ├── test_04_keep_alive_works.sh │ ├── test_05_repeated_reqs_work.sh │ ├── test_06_http_1.0.sh │ ├── test_07_headers_work.sh │ ├── test_08_survive_signals.sh │ ├── test_09_curl_happy_with_trailers.sh │ ├── test_10_connection_drop_in_body_ok.sh │ ├── test_11_res_body_streaming.sh │ ├── test_12_headers_too_large.sh │ ├── test_13_http_pipelining.sh │ ├── test_14_strict_mode_assertion.sh │ ├── test_15_post_in_chunked_encoding.sh │ ├── test_16_tcp_client_ip.sh │ ├── test_17_serve_massive_sparse_file.sh │ ├── test_18_close_with_no_keepalive.sh │ ├── test_19_connection_drop_while_waiting_for_response_uds.sh │ ├── test_20_connection_drop_while_waiting_for_response_tcp.sh │ ├── test_21_connection_reset_tcp.sh │ ├── test_22_http_1.0_keep_alive.sh │ ├── test_23_repeated_reqs_with_half_closure.sh │ └── test_24_http_over_stdio.sh ├── tests_02_syscall_wrappers │ ├── defines.sh │ ├── test_01_syscall_wrapper_fast.sh │ ├── test_02_unacceptable_errnos.sh │ └── test_03_unacceptable_read_errnos.sh ├── tests_03_debug_binary_checks │ ├── defines.sh │ ├── test_01_check_we_do_not_link_Foundation.sh │ └── test_02_expected_crashes_work.sh ├── tests_04_performance │ ├── Thresholds │ │ ├── 5.10.json │ │ ├── 5.8.json │ │ ├── 6.0.json │ │ ├── 6.1.json │ │ ├── nightly-main.json │ │ └── nightly-next.json │ ├── defines.sh │ ├── test_01_allocation_counts.sh │ └── test_01_resources │ │ ├── README.md │ │ ├── run-nio-alloc-counter-tests.sh │ │ ├── shared.swift │ │ ├── test_10000000_asyncsequenceproducer.swift │ │ ├── test_1000000_asyncwriter.swift │ │ ├── test_1000_addHandlers.swift │ │ ├── test_1000_addHandlers_sync.swift │ │ ├── test_1000_addRemoveHandlers.swift │ │ ├── test_1000_autoReadGetAndSet.swift │ │ ├── test_1000_autoReadGetAndSet_sync.swift │ │ ├── test_1000_copying_bytebufferview_to_array.swift │ │ ├── test_1000_copying_circularbuffer_to_array.swift │ │ ├── test_1000_getHandlers.swift │ │ ├── test_1000_getHandlers_sync.swift │ │ ├── test_1000_reqs_1_conn.swift │ │ ├── test_1000_rst_connections.swift │ │ ├── test_1000_tcpbootstraps.swift │ │ ├── test_1000_tcpconnections.swift │ │ ├── test_1000_udp_reqs.swift │ │ ├── test_1000_udpbootstraps.swift │ │ ├── test_1000_udpconnections.swift │ │ ├── test_1_reqs_1000_conn.swift │ │ ├── test_assume_isolated_scheduling_10000_executions.swift │ │ ├── test_bytebuffer_lots_of_rw.swift │ │ ├── test_creating_10000_headers.swift │ │ ├── test_decode_1000_ws_frames.swift │ │ ├── test_encode_1000_ws_frames.swift │ │ ├── test_execute_hop_10000_tasks.swift │ │ ├── test_flat_schedule_10000_tasks.swift │ │ ├── test_flat_schedule_assume_isolated_10000_tasks.swift │ │ ├── test_future_assume_isolated_lots_of_callbacks.swift │ │ ├── test_future_erase_result.swift │ │ ├── test_future_lots_of_callbacks.swift │ │ ├── test_get_100000_headers_canonical_form.swift │ │ ├── test_modifying_1000_circular_buffer_elements.swift │ │ ├── test_modifying_byte_buffer_view.swift │ │ ├── test_ping_pong_1000_reqs_1_conn.swift │ │ ├── test_read_10000_chunks_from_file.swift │ │ ├── test_schedule_10000_tasks.swift │ │ ├── test_schedule_and_run_10000_tasks.swift │ │ ├── test_schedule_assume_isolated_10000_tasks.swift │ │ ├── test_schedule_with_deadline_10000_tasks.swift │ │ ├── test_schedule_with_deadline_assume_isolated_10000_tasks.swift │ │ ├── test_scheduling_10000_executions.swift │ │ ├── test_submit_10000_tasks.swift │ │ ├── test_submit_assume_isolated_10000_tasks.swift │ │ ├── test_udp_1000_reqs_1_conn.swift │ │ └── test_udp_1_reqs_1000_conn.swift └── tests_05_assertions │ ├── defines.sh │ └── test_01_syscall_wrapper_fast.sh ├── LICENSE.txt ├── NOTICE.txt ├── Package.swift ├── README.md ├── SECURITY.md ├── Snippets └── NIOFileSystemTour.swift ├── Sources ├── CNIOAtomics │ ├── include │ │ └── CNIOAtomics.h │ └── src │ │ ├── c-atomics.c │ │ ├── c-nioatomics.c │ │ └── cpp_magic.h ├── CNIODarwin │ ├── include │ │ └── CNIODarwin.h │ └── shim.c ├── CNIOLLHTTP │ ├── LICENSE │ ├── c_nio_api.c │ ├── c_nio_http.c │ ├── c_nio_llhttp.c │ ├── include │ │ ├── CNIOLLHTTP.h │ │ └── c_nio_llhttp.h │ └── update_and_patch_llhttp.sh ├── CNIOLinux │ ├── include │ │ ├── CNIOLinux.h │ │ └── liburing_nio.h │ ├── liburing_shims.c │ └── shim.c ├── CNIOSHA1 │ ├── c_nio_sha1.c │ ├── include │ │ └── CNIOSHA1.h │ └── update_and_patch_sha1.sh ├── CNIOWASI │ ├── CNIOWASI.c │ └── include │ │ └── CNIOWASI.h ├── CNIOWindows │ ├── WSAStartup.c │ ├── include │ │ ├── CNIOWindows.h │ │ └── module.modulemap │ └── shim.c ├── NIO │ ├── Docs.docc │ │ └── index.md │ └── Exports.swift ├── NIOAsyncAwaitDemo │ ├── AsyncChannelIO.swift │ ├── FullRequestResponse.swift │ └── main.swift ├── NIOChatClient │ ├── README.md │ └── main.swift ├── NIOChatServer │ ├── README.md │ └── main.swift ├── NIOConcurrencyHelpers │ ├── NIOAtomic.swift │ ├── NIOLock.swift │ ├── NIOLockedValueBox.swift │ ├── atomics.swift │ └── lock.swift ├── NIOCore │ ├── AddressedEnvelope.swift │ ├── AsyncAwaitSupport.swift │ ├── AsyncChannel │ │ ├── AsyncChannel.swift │ │ ├── AsyncChannelHandler.swift │ │ ├── AsyncChannelInboundStream.swift │ │ └── AsyncChannelOutboundWriter.swift │ ├── AsyncSequences │ │ ├── NIOAsyncSequenceProducer.swift │ │ ├── NIOAsyncSequenceProducerStrategies.swift │ │ ├── NIOAsyncWriter.swift │ │ └── NIOThrowingAsyncSequenceProducer.swift │ ├── BSDSocketAPI.swift │ ├── ByteBuffer-aux.swift │ ├── ByteBuffer-binaryEncodedLengthPrefix.swift │ ├── ByteBuffer-conversions.swift │ ├── ByteBuffer-core.swift │ ├── ByteBuffer-hex.swift │ ├── ByteBuffer-int.swift │ ├── ByteBuffer-lengthPrefix.swift │ ├── ByteBuffer-multi-int.swift │ ├── ByteBuffer-quicBinaryEncodingStrategy.swift │ ├── ByteBuffer-views.swift │ ├── Channel.swift │ ├── ChannelHandler.swift │ ├── ChannelHandlers.swift │ ├── ChannelInvoker.swift │ ├── ChannelOption.swift │ ├── ChannelPipeline.swift │ ├── CircularBuffer.swift │ ├── Codec.swift │ ├── ConvenienceOptionSupport.swift │ ├── DeadChannel.swift │ ├── DispatchQueue+WithFuture.swift │ ├── Docs.docc │ │ ├── ByteBuffer-lengthPrefix.md │ │ ├── index.md │ │ ├── loops-futures-concurrency.md │ │ └── swift-concurrency.md │ ├── EventLoop+Deprecated.swift │ ├── EventLoop+SerialExecutor.swift │ ├── EventLoop.swift │ ├── EventLoopFuture+AssumeIsolated.swift │ ├── EventLoopFuture+Deprecated.swift │ ├── EventLoopFuture+WithEventLoop.swift │ ├── EventLoopFuture.swift │ ├── FileDescriptor.swift │ ├── FileHandle.swift │ ├── FileRegion.swift │ ├── GlobalSingletons.swift │ ├── IO.swift │ ├── IOData.swift │ ├── IPProtocol.swift │ ├── IntegerBitPacking.swift │ ├── IntegerTypes.swift │ ├── Interfaces.swift │ ├── Linux.swift │ ├── MarkedCircularBuffer.swift │ ├── MulticastChannel.swift │ ├── NIOAny.swift │ ├── NIOCloseOnErrorHandler.swift │ ├── NIOLoopBound.swift │ ├── NIOPooledRecvBufferAllocator.swift │ ├── NIOScheduledCallback.swift │ ├── NIOSendable.swift │ ├── RecvByteBufferAllocator.swift │ ├── SingleStepByteToMessageDecoder.swift │ ├── SocketAddresses.swift │ ├── SocketOptionProvider.swift │ ├── SystemCallHelpers.swift │ ├── TimeAmount+Duration.swift │ ├── TypeAssistedChannelHandler.swift │ ├── UniversalBootstrapSupport.swift │ └── Utilities.swift ├── NIOCrashTester │ ├── CrashTestSuites.swift │ ├── CrashTests+ByteBuffer.swift │ ├── CrashTests+EventLoop.swift │ ├── CrashTests+HTTP.swift │ ├── CrashTests+LoopBound.swift │ ├── CrashTests+Strict.swift │ ├── CrashTests+System.swift │ ├── OutputGrepper.swift │ └── main.swift ├── NIOEchoClient │ ├── README.md │ └── main.swift ├── NIOEchoServer │ ├── README.md │ └── main.swift ├── NIOEmbedded │ ├── AsyncTestingChannel.swift │ ├── AsyncTestingEventLoop.swift │ └── Embedded.swift ├── NIOFileSystem │ ├── Array+FileSystem.swift │ ├── ArraySlice+FileSystem.swift │ ├── BufferedReader.swift │ ├── BufferedWriter.swift │ ├── ByteBuffer+FileSystem.swift │ ├── ByteCount.swift │ ├── Convenience.swift │ ├── DirectoryEntries.swift │ ├── DirectoryEntry.swift │ ├── Docs.docc │ │ ├── Extensions │ │ │ ├── DirectoryFileHandleProtocol.md │ │ │ ├── FileHandleProtocol.md │ │ │ ├── FileSystemProtocol.md │ │ │ ├── ReadableFileHandleProtocol.md │ │ │ └── WritableFileHandleProtocol.md │ │ └── index.md │ ├── Exports.swift │ ├── FileChunks.swift │ ├── FileHandle.swift │ ├── FileHandleProtocol.swift │ ├── FileInfo.swift │ ├── FileSystem.swift │ ├── FileSystemError+Syscall.swift │ ├── FileSystemError.swift │ ├── FileSystemProtocol.swift │ ├── FileType.swift │ ├── IOStrategy.swift │ ├── Internal │ │ ├── BufferedOrAnyStream.swift │ │ ├── BufferedStream.swift │ │ ├── Cancellation.swift │ │ ├── Concurrency Primitives │ │ │ ├── TokenBucket.swift │ │ │ └── UnsafeTransfer.swift │ │ ├── ParallelDirCopy.swift │ │ ├── ParallelRemoval.swift │ │ ├── String+UnsafeUnititializedCapacity.swift │ │ ├── System Calls │ │ │ ├── CInterop.swift │ │ │ ├── Errno.swift │ │ │ ├── FileDescriptor+Syscalls.swift │ │ │ ├── Mocking.swift │ │ │ ├── Syscall.swift │ │ │ └── Syscalls.swift │ │ ├── SystemFileHandle.swift │ │ └── Utilities.swift │ ├── OpenOptions.swift │ ├── PrivacyInfo.xcprivacy │ └── String+FileSystem.swift ├── NIOFileSystemFoundationCompat │ ├── Data+FileSystem.swift │ └── Date+FileInfo.swift ├── NIOFoundationCompat │ ├── ByteBuffer-foundation.swift │ ├── Codable+ByteBuffer.swift │ ├── JSONSerialization+ByteBuffer.swift │ └── WaitSpinningRunLoop.swift ├── NIOHTTP1 │ ├── ByteCollectionUtils.swift │ ├── HTTPDecoder.swift │ ├── HTTPEncoder.swift │ ├── HTTPHeaderValidator.swift │ ├── HTTPHeaders+Validation.swift │ ├── HTTPPipelineSetup.swift │ ├── HTTPServerPipelineHandler.swift │ ├── HTTPServerProtocolErrorHandler.swift │ ├── HTTPServerUpgradeHandler.swift │ ├── HTTPTypedPipelineSetup.swift │ ├── HTTPTypes.swift │ ├── NIOHTTPClientUpgradeHandler.swift │ ├── NIOHTTPObjectAggregator.swift │ ├── NIOTypedHTTPClientUpgradeHandler.swift │ ├── NIOTypedHTTPClientUpgraderStateMachine.swift │ ├── NIOTypedHTTPServerUpgradeHandler.swift │ └── NIOTypedHTTPServerUpgraderStateMachine.swift ├── NIOHTTP1Client │ ├── README.md │ └── main.swift ├── NIOHTTP1Server │ ├── README.md │ └── main.swift ├── NIOMulticastChat │ └── main.swift ├── NIOPerformanceTester │ ├── Benchmark.swift │ ├── ByteBufferViewContainsBenchmark.swift │ ├── ByteBufferViewCopyToArrayBenchmark.swift │ ├── ByteBufferViewIteratorBenchmark.swift │ ├── ByteBufferWriteMultipleBenchmarks.swift │ ├── ByteToMessageDecoderDecodeManySmallsBenchmark.swift │ ├── ChannelPipelineBenchmark.swift │ ├── CircularBufferCopyToArrayBenchmark.swift │ ├── CircularBufferIntoByteBufferBenchmark.swift │ ├── DeadlineNowBenchmark.swift │ ├── ExecuteBenchmark.swift │ ├── LockBenchmark.swift │ ├── NIOAsyncSequenceProducerBenchmark.swift │ ├── NIOAsyncWriterSingleWritesBenchmark.swift │ ├── RunIfActiveBenchmark.swift │ ├── SchedulingAndRunningBenchmark.swift │ ├── TCPThroughputBenchmark.swift │ ├── UDPBenchmark.swift │ ├── WebSocketFrameDecoderBenchmark.swift │ ├── WebSocketFrameEncoderBenchmark.swift │ ├── main.swift │ └── resources.swift ├── NIOPosix │ ├── BSDSocketAPICommon.swift │ ├── BSDSocketAPIPosix.swift │ ├── BSDSocketAPIWindows.swift │ ├── BaseSocket.swift │ ├── BaseSocketChannel+SocketOptionProvider.swift │ ├── BaseSocketChannel.swift │ ├── BaseStreamSocketChannel.swift │ ├── Bootstrap.swift │ ├── ControlMessage.swift │ ├── DatagramVectorReadManager.swift │ ├── Errors+Any.swift │ ├── FileDescriptor.swift │ ├── GetaddrinfoResolver.swift │ ├── HappyEyeballs.swift │ ├── IO.swift │ ├── IntegerBitPacking.swift │ ├── IntegerTypes.swift │ ├── Linux.swift │ ├── LinuxCPUSet.swift │ ├── LinuxUring.swift │ ├── MultiThreadedEventLoopGroup.swift │ ├── NIOThreadPool.swift │ ├── NonBlockingFileIO.swift │ ├── PendingDatagramWritesManager.swift │ ├── PendingWritesManager.swift │ ├── PipeChannel.swift │ ├── PipePair.swift │ ├── Pool.swift │ ├── PosixSingletons+ConcurrencyTakeOver.swift │ ├── PosixSingletons.swift │ ├── PrivacyInfo.xcprivacy │ ├── RawSocketBootstrap.swift │ ├── Resolver.swift │ ├── Selectable.swift │ ├── SelectableChannel.swift │ ├── SelectableEventLoop.swift │ ├── SelectorEpoll.swift │ ├── SelectorGeneric.swift │ ├── SelectorKqueue.swift │ ├── SelectorUring.swift │ ├── ServerSocket.swift │ ├── Socket.swift │ ├── SocketChannel.swift │ ├── SocketProtocols.swift │ ├── System.swift │ ├── Thread.swift │ ├── ThreadPosix.swift │ ├── ThreadWindows.swift │ ├── UnsafeTransfer.swift │ ├── Utilities.swift │ ├── VsockAddress.swift │ └── VsockChannelEvents.swift ├── NIOTCPEchoClient │ ├── Client.swift │ └── README.md ├── NIOTCPEchoServer │ ├── README.md │ └── Server.swift ├── NIOTLS │ ├── ApplicationProtocolNegotiationHandler.swift │ ├── NIOTypedApplicationProtocolNegotiationHandler.swift │ ├── ProtocolNegotiationHandlerStateMachine.swift │ ├── SNIHandler.swift │ └── TLSEvents.swift ├── NIOTestUtils │ ├── ByteToMessageDecoderVerifier.swift │ ├── EventCounterHandler.swift │ ├── ManualTaskExecutor.swift │ └── NIOHTTP1TestServer.swift ├── NIOUDPEchoClient │ ├── README.md │ └── main.swift ├── NIOUDPEchoServer │ ├── README.md │ └── main.swift ├── NIOWebSocket │ ├── NIOWebSocketClientUpgrader.swift │ ├── NIOWebSocketFrameAggregator.swift │ ├── NIOWebSocketServerUpgrader.swift │ ├── SHA1.swift │ ├── WebSocketErrorCodes.swift │ ├── WebSocketFrame.swift │ ├── WebSocketFrameDecoder.swift │ ├── WebSocketFrameEncoder.swift │ ├── WebSocketOpcode.swift │ └── WebSocketProtocolErrorHandler.swift ├── NIOWebSocketClient │ ├── Client.swift │ └── README.md ├── NIOWebSocketServer │ ├── README.md │ └── Server.swift ├── _NIOBase64 │ └── Base64.swift ├── _NIOConcurrency │ └── Empty.swift ├── _NIODataStructures │ ├── Heap.swift │ ├── PriorityQueue.swift │ └── _TinyArray.swift └── _NIOFileSystemExported │ └── Exports.swift ├── Tests ├── NIOBase64Tests │ └── Base64Test.swift ├── NIOConcurrencyHelpersTests │ └── NIOConcurrencyHelpersTests.swift ├── NIOCoreTests │ ├── AddressedEnvelopeTests.swift │ ├── AsyncChannel │ │ ├── AsyncChannelInboundStreamTests.swift │ │ ├── AsyncChannelOutboundWriterTests.swift │ │ └── AsyncChannelTests.swift │ ├── AsyncSequenceTests.swift │ ├── AsyncSequences │ │ ├── NIOAsyncSequenceProducer+HighLowWatermarkBackPressureStrategyTests.swift │ │ ├── NIOAsyncSequenceTests.swift │ │ ├── NIOAsyncWriterTests.swift │ │ └── NIOThrowingAsyncSequenceTests.swift │ ├── BaseObjectsTest.swift │ ├── ByteBufferBinaryEncodedLengthPrefixTests.swift │ ├── ByteBufferLengthPrefixTests.swift │ ├── ByteBufferQUICBinaryEncodingStrategyTests.swift │ ├── ByteBufferTest.swift │ ├── ChannelOptionStorageTest.swift │ ├── CircularBufferTests.swift │ ├── CustomChannelTests.swift │ ├── DispatchQueue+WithFutureTest.swift │ ├── IOErrorTest.swift │ ├── IntegerTypesTest.swift │ ├── LinuxTest.swift │ ├── MarkedCircularBufferTests.swift │ ├── NIOAnyDebugTest.swift │ ├── NIOCloseOnErrorHandlerTest.swift │ ├── NIOIsolatedEventLoopTests.swift │ ├── NIOPooledRecvBufferAllocatorTests.swift │ ├── RecvByteBufAllocatorTest.swift │ ├── SingleStepByteToMessageDecoderTest.swift │ ├── TimeAmount+DurationTests.swift │ ├── TimeAmountTests.swift │ ├── TypeAssistedChannelHandlerTests.swift │ ├── UtilitiesTest.swift │ ├── XCTest+AsyncAwait.swift │ └── XCTest+Extensions.swift ├── NIODataStructuresTests │ ├── HeapTests.swift │ └── PriorityQueueTests.swift ├── NIOEmbeddedTests │ ├── AsyncTestingChannelTests.swift │ ├── AsyncTestingEventLoopTests.swift │ ├── EmbeddedChannelTest.swift │ ├── EmbeddedEventLoopTest.swift │ ├── TestUtils.swift │ └── XCTest+AsyncAwait.swift ├── NIOFileSystemFoundationCompatTests │ └── FileSystemFoundationCompatTests.swift ├── NIOFileSystemIntegrationTests │ ├── BufferedReaderTests.swift │ ├── BufferedWriterTests.swift │ ├── ConvenienceTests.swift │ ├── FileHandleTests.swift │ ├── FileSystemTests+SPI.swift │ ├── FileSystemTests.swift │ ├── Test Data │ │ ├── Foo.symlink │ │ ├── Foo │ │ │ └── README.txt │ │ ├── README.md │ │ └── README.md.symlink │ └── XCTestExtensions.swift ├── NIOFileSystemTests │ ├── ByteCountTests.swift │ ├── DirectoryEntriesTests.swift │ ├── FileChunksTests.swift │ ├── FileHandleTests.swift │ ├── FileInfoTests.swift │ ├── FileOpenOptionsTests.swift │ ├── FileSystemErrorTests.swift │ ├── FileTypeTests.swift │ ├── Internal │ │ ├── CancellationTests.swift │ │ ├── Concurrency Primitives │ │ │ └── BufferedStreamTests.swift │ │ ├── MockingInfrastructure.swift │ │ └── SyscallTests.swift │ └── XCTestExtensions.swift ├── NIOFoundationCompatTests │ ├── ByteBuffer+UUIDTests.swift │ ├── ByteBufferDataProtocolTests.swift │ ├── ByteBufferView+MutableDataProtocolTest.swift │ ├── Codable+ByteBufferTest.swift │ ├── JSONSerialization+ByteBufferTest.swift │ └── WaitSpinningRunLoopTests.swift ├── NIOHTTP1Tests │ ├── ByteBufferUtilsTest.swift │ ├── ContentLengthTests.swift │ ├── HTTPClientUpgradeTests.swift │ ├── HTTPDecoderLengthTest.swift │ ├── HTTPDecoderTest.swift │ ├── HTTPHeaderValidationTests.swift │ ├── HTTPHeadersTest.swift │ ├── HTTPRequestEncoderTest.swift │ ├── HTTPResponseEncoderTest.swift │ ├── HTTPResponseStatusTests.swift │ ├── HTTPServerClientTest.swift │ ├── HTTPServerPipelineHandlerTest.swift │ ├── HTTPServerProtocolErrorHandlerTest.swift │ ├── HTTPServerUpgradeTests.swift │ ├── HTTPTest.swift │ ├── HTTPTypesTest.swift │ ├── NIOHTTPObjectAggregatorTest.swift │ ├── TestUtils.swift │ └── UnsafeTransfer.swift ├── NIOPosixTests │ ├── AcceptBackoffHandlerTest.swift │ ├── AsyncChannelBootstrapTests.swift │ ├── BlockingIOThreadPoolTest.swift │ ├── BootstrapTest.swift │ ├── ChannelNotificationTest.swift │ ├── ChannelPipelineTest.swift │ ├── ChannelTests.swift │ ├── CoWValue.swift │ ├── CodecTest.swift │ ├── ControlMessageTests.swift │ ├── DatagramChannelTests.swift │ ├── EchoServerClientTest.swift │ ├── EventLoopFutureIsolatedTests.swift │ ├── EventLoopFutureTest.swift │ ├── EventLoopMetricsDelegateTests.swift │ ├── EventLoopTest.swift │ ├── FileRegionTest.swift │ ├── GetAddrInfoResolverTest.swift │ ├── HappyEyeballsTest.swift │ ├── IPv4Header.swift │ ├── IdleStateHandlerTest.swift │ ├── IntegerBitPackingTests.swift │ ├── MulticastTest.swift │ ├── NIOFileHandleTest.swift │ ├── NIOLoopBoundTests.swift │ ├── NIOScheduledCallbackTests.swift │ ├── NIOThreadPoolTest.swift │ ├── NonBlockingFileIOTest.swift │ ├── PendingDatagramWritesManagerTests.swift │ ├── PipeChannelTest.swift │ ├── RawSocketBootstrapTests.swift │ ├── SALChannelTests.swift │ ├── SALEventLoopTests.swift │ ├── SelectorTest.swift │ ├── SerialExecutorTests.swift │ ├── SocketAddressTest.swift │ ├── SocketChannelTest.swift │ ├── SocketOptionProviderTest.swift │ ├── StreamChannelsTest.swift │ ├── SyscallAbstractionLayer.swift │ ├── SyscallAbstractionLayerContext.swift │ ├── SystemCallWrapperHelpers.swift │ ├── SystemTest.swift │ ├── TestUtils.swift │ ├── ThreadTest.swift │ ├── UniversalBootstrapSupportTest.swift │ ├── VsockAddressTest.swift │ └── XCTest+AsyncAwait.swift ├── NIOSingletonsTests │ └── GlobalSingletonsTests.swift ├── NIOTLSTests │ ├── ApplicationProtocolNegotiationHandlerTests.swift │ ├── NIOTypedApplicationProtocolNegotiationHandlerTests.swift │ └── SNIHandlerTests.swift ├── NIOTestUtilsTests │ ├── ByteToMessageDecoderVerifierTest.swift │ ├── EventCounterHandlerTest.swift │ ├── ManualTaskExecutorTest.swift │ └── NIOHTTP1TestServerTest.swift ├── NIOTests │ └── NIOTests.swift └── NIOWebSocketTests │ ├── ByteBufferWebSocketTests.swift │ ├── NIOWebSocketClientUpgraderTests.swift │ ├── NIOWebSocketFrameAggregatorTests.swift │ ├── WebSocketClientEndToEndTests.swift │ ├── WebSocketFrameDecoderTest.swift │ ├── WebSocketFrameEncoderTest.swift │ ├── WebSocketMaskingKeyTests.swift │ └── WebSocketServerEndToEndTests.swift ├── dev ├── alloc-limits-from-test-output ├── boxed-existentials.d ├── generate-bytebuffer-multi-int.sh ├── git.commit.template ├── lldb-smoker ├── make-single-file-spm ├── malloc-aggregation.d ├── stackdiff-dtrace.py └── thresholds-from-benchmark-output.sh ├── docs ├── advanced-performance-analysis.md ├── debugging-allocations.md ├── io_uring.md ├── migration-guide-NIO1-to-NIO2.md ├── optimization-tips.md ├── public-api.md ├── public-async-nio-apis.md └── workarounds.md └── scripts ├── analyze_performance_results.rb ├── check-cxx-interop-compatibility.sh ├── check-matrix-job.ps1 ├── check-matrix-job.sh ├── check_benchmark_thresholds.sh ├── cmake-build.sh ├── compare_perf_of_swift_versions.sh ├── generate_matrix.sh ├── install_static_sdk.sh ├── install_swift_prerequisites.sh ├── integration_tests.sh ├── nio-diagnose └── update-cmake-lists.sh /.editorconfig: -------------------------------------------------------------------------------- 1 | root = true 2 | 3 | [*] 4 | indent_style = space 5 | indent_size = 4 6 | end_of_line = lf 7 | insert_final_newline = true 8 | trim_trailing_whitespace = true -------------------------------------------------------------------------------- /.git-blame-ignore-revs: -------------------------------------------------------------------------------- 1 | # Adopt swift-format 2 | c9756e108351a1def2e2c83ff5ee6fb9bcbc3bbf 3 | -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | Sources/CNIOHTTPParser/* linguist-vendored 2 | Sources/CNIOSHA1/* linguist-vendored 3 | Sources/CNIOLinux/ifaddrs-* linguist-vendored 4 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug-report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug Report 3 | about: File a bug report to help us improve 4 | --- 5 | 6 | ### Expected behavior 7 | _[what you expected to happen]_ 8 | 9 | ### Actual behavior 10 | _[what actually happened]_ 11 | 12 | ### Steps to reproduce 13 | 14 | 1. ... 15 | 2. ... 16 | 17 | ### If possible, minimal yet complete reproducer code (or URL to code) 18 | 19 | _[anything to help us reproducing the issue]_ 20 | 21 | ### SwiftNIO version/commit hash 22 | 23 | _[the SwiftNIO tag/commit hash]_ 24 | 25 | ### System & version information 26 | 27 | Please provide at the very least your operating system and Swift version 28 | information. 29 | 30 | Ideally, run 31 | 32 | ``` 33 | scripts/nio-diagnose -o nio-diagnose.md PID_OF_YOUR_NIO_PROGRAM 34 | ``` 35 | 36 | and attach (or paste) the resulting file `nio-diagnose.md` into this bug report 37 | or send it to the SwiftNIO maintainers privately. 38 | -------------------------------------------------------------------------------- /.github/PULL_REQUEST_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | _[One line description of your change]_ 2 | 3 | ### Motivation: 4 | 5 | _[Explain here the context, and why you're making that change. What is the problem you're trying to solve.]_ 6 | 7 | ### Modifications: 8 | 9 | _[Describe the modifications you've done.]_ 10 | 11 | ### Result: 12 | 13 | _[After your change, what will change.]_ 14 | -------------------------------------------------------------------------------- /.github/actions/pull_request_semver_label_checker/action.yml: -------------------------------------------------------------------------------- 1 | name: 'Pull request Semantic Version label checker' 2 | 3 | description: 'Checks that at least one Semantic Version label is applied to the pull request' 4 | 5 | inputs: 6 | token: 7 | description: 'A GitHub token' 8 | type: string 9 | default: ${{ github.token }} 10 | 11 | runs: 12 | using: "composite" 13 | steps: 14 | - name: Check labels 15 | if: ${{ !env.ACT }} 16 | shell: bash 17 | env: 18 | GH_TOKEN: ${{ inputs.token }} 19 | run: | 20 | gh pr view ${{ github.event.number }} --repo ${{ github.repository }} --json labels \ 21 | | jq -e '[.labels[].name] | any(. == "⚠️ semver/major" or . == "🆕 semver/minor" or . == "🔨 semver/patch" or . == "semver/none")' 22 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | categories: 3 | - title: SemVer Major 4 | labels: 5 | - ⚠️ semver/major 6 | - title: SemVer Minor 7 | labels: 8 | - 🆕 semver/minor 9 | - title: SemVer Patch 10 | labels: 11 | - 🔨 semver/patch 12 | - title: Other Changes 13 | labels: 14 | - semver/none 15 | -------------------------------------------------------------------------------- /.github/workflows/cmake_tests.yml: -------------------------------------------------------------------------------- 1 | name: CMake build 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | update_cmake_lists_config: 7 | type: string 8 | description: "The configuration used when updating the CMake lists." 9 | required: true 10 | cmake_build_target_directory: 11 | type: string 12 | description: "The directory to pass to `cmake build`." 13 | default: "." 14 | cmake_version: 15 | type: string 16 | description: "The version of CMake to install." 17 | default: "" 18 | image: 19 | type: string 20 | description: "The docker image to run the checks in." 21 | default: "swift:6.0-jammy" 22 | 23 | jobs: 24 | cmake-checks: 25 | name: CMake checks 26 | runs-on: ubuntu-latest 27 | container: 28 | image: ${{ inputs.image }} 29 | steps: 30 | - name: Checkout repository 31 | uses: actions/checkout@v4 32 | with: 33 | persist-credentials: false 34 | submodules: true 35 | - name: Mark the workspace as safe 36 | # https://github.com/actions/checkout/issues/766 37 | run: git config --global --add safe.directory ${GITHUB_WORKSPACE} 38 | - name: Check CMakeLists files 39 | run: | 40 | which curl jq || apt -q update 41 | which curl || apt -yq install curl 42 | which jq || apt -yq install jq 43 | curl -s --retry 3 https://raw.githubusercontent.com/apple/swift-nio/main/scripts/update-cmake-lists.sh | CONFIG_JSON='${{ inputs.update_cmake_lists_config }}' FAIL_ON_CHANGES=true bash 44 | - name: CMake build 45 | run: | 46 | which curl cmake ninja || apt -q update 47 | which curl || apt -yq install curl 48 | which cmake || apt -yq install cmake 49 | which ninja || apt -yq install ninja-build 50 | curl -s --retry 3 https://raw.githubusercontent.com/apple/swift-nio/main/scripts/cmake-build.sh | TARGET_DIRECTORY="${{ inputs.cmake_build_target_directory }}" CMAKE_VERSION="${{ inputs.cmake_version }}" bash 51 | -------------------------------------------------------------------------------- /.github/workflows/pull_request_label.yml: -------------------------------------------------------------------------------- 1 | name: PR label 2 | 3 | on: 4 | pull_request: 5 | types: [labeled, unlabeled, opened, reopened, synchronize] 6 | 7 | jobs: 8 | semver-label-check: 9 | name: Semantic version label check 10 | runs-on: ubuntu-latest 11 | timeout-minutes: 1 12 | steps: 13 | - name: Checkout repository 14 | uses: actions/checkout@v4 15 | with: 16 | persist-credentials: false 17 | - name: Check for Semantic Version label 18 | uses: ./.github/actions/pull_request_semver_label_checker/ 19 | -------------------------------------------------------------------------------- /.github/workflows/static_sdk.yml: -------------------------------------------------------------------------------- 1 | name: Static SDK 2 | 3 | on: 4 | workflow_call: 5 | 6 | jobs: 7 | static-sdk: 8 | name: Static SDK 9 | # Workaround https://github.com/nektos/act/issues/1875 10 | uses: apple/swift-nio/.github/workflows/swift_test_matrix.yml@main 11 | with: 12 | name: "Static SDK" 13 | matrix_string: >- 14 | { 15 | "config":[ 16 | { 17 | "name":"latest-release Jammy", 18 | "swift_version":"latest-release", 19 | "platform":"Linux", 20 | "runner":"ubuntu-latest", 21 | "image":"ubuntu:jammy", 22 | "setup_command":"apt update -q && apt install -y -q curl jq tar && curl -s --retry 3 https://raw.githubusercontent.com/apple/swift-nio/main/scripts/install_swift_prerequisites.sh | bash && curl -s --retry 3 https://raw.githubusercontent.com/apple/swift-nio/main/scripts/install_static_sdk.sh | INSTALL_SWIFT_STATIC_SDK_VERSION=latest INSTALL_SWIFT_STATIC_SDK_ARCH=x86_64 bash && hash -r", 23 | "command":"swift build", 24 | "command_arguments":"--swift-sdk x86_64-swift-linux-musl" 25 | }, 26 | { 27 | "name":"main Jammy", 28 | "swift_version":"main", 29 | "platform":"Linux", 30 | "runner":"ubuntu-latest", 31 | "image":"ubuntu:jammy", 32 | "setup_command":"apt update -q && apt install -y -q curl jq tar && curl -s --retry 3 https://raw.githubusercontent.com/apple/swift-nio/main/scripts/install_swift_prerequisites.sh | bash && curl -s --retry 3 https://raw.githubusercontent.com/apple/swift-nio/main/scripts/install_static_sdk.sh | INSTALL_SWIFT_STATIC_SDK_BRANCH=main INSTALL_SWIFT_STATIC_SDK_ARCH=x86_64 bash && hash -r", 33 | "command":"swift build", 34 | "command_arguments":"--swift-sdk x86_64-swift-linux-musl" 35 | } 36 | ] 37 | } 38 | -------------------------------------------------------------------------------- /.github/workflows/swift_6_language_mode.yml: -------------------------------------------------------------------------------- 1 | name: Swift 6 language mode 2 | 3 | on: 4 | workflow_call: 5 | 6 | # We are cancelling previously triggered workflow runs 7 | concurrency: 8 | group: ${{ github.workflow }}-${{ github.ref }}-swift-6-language-mode 9 | cancel-in-progress: true 10 | 11 | jobs: 12 | swift-6-language-mode: 13 | name: Swift 6 language mode 14 | runs-on: ubuntu-latest 15 | container: 16 | image: swift:6.0-jammy 17 | steps: 18 | - name: Checkout repository 19 | uses: actions/checkout@v4 20 | with: 21 | persist-credentials: false 22 | submodules: true 23 | - name: Set the language mode 24 | run: swift package tools-version --set 6.0 25 | - name: Build with Swift 6 language mode 26 | run: swift build -Xswiftc -warnings-as-errors 27 | -------------------------------------------------------------------------------- /.github/workflows/swift_load_test_matrix.yml: -------------------------------------------------------------------------------- 1 | name: Matrix Load 2 | 3 | on: 4 | workflow_call: 5 | inputs: 6 | name: 7 | type: string 8 | description: "The name of the workflow used for the concurrency group." 9 | required: true 10 | matrix_path: 11 | type: string 12 | description: "The path of the test matrix definition." 13 | default: "" 14 | 15 | jobs: 16 | load-matrix: 17 | name: Prepare matrices 18 | runs-on: ubuntu-latest 19 | outputs: 20 | swift-matrix: ${{ steps.load-matrix.outputs.swift-matrix }} 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@v4 24 | with: 25 | persist-credentials: false 26 | - name: Mark the workspace as safe 27 | # https://github.com/actions/checkout/issues/766 28 | run: git config --global --add safe.directory ${GITHUB_WORKSPACE} 29 | - id: load-matrix 30 | run: | 31 | printf "swift-matrix=%s" "$(jq -ec '.' ${{ inputs.matrix_path }})" >> "$GITHUB_OUTPUT" 32 | 33 | 34 | execute-matrix: 35 | name: Execute matrix 36 | needs: load-matrix 37 | # Workaround https://github.com/nektos/act/issues/1875 38 | uses: apple/swift-nio/.github/workflows/swift_test_matrix.yml@main 39 | with: 40 | name: ${{ inputs.name }} 41 | matrix_string: '${{ needs.load-matrix.outputs.swift-matrix }}' 42 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | .build 3 | /.index-build 4 | /Packages 5 | /*.xcodeproj 6 | Package.pins 7 | *.pem 8 | /docs/1.* 9 | /docs/2.* 10 | Package.resolved 11 | .podspecs 12 | DerivedData 13 | .swiftpm 14 | .*.sw? 15 | .vscode/launch.json 16 | -------------------------------------------------------------------------------- /.licenseignore: -------------------------------------------------------------------------------- 1 | .gitignore 2 | **/.gitignore 3 | .licenseignore 4 | .gitattributes 5 | .git-blame-ignore-revs 6 | .mailfilter 7 | .mailmap 8 | .spi.yml 9 | .swift-format 10 | .editorconfig 11 | .github/* 12 | *.md 13 | *.txt 14 | *.yml 15 | *.yaml 16 | *.json 17 | Package.swift 18 | **/Package.swift 19 | Package@-*.swift 20 | **/Package@-*.swift 21 | Package.resolved 22 | **/Package.resolved 23 | Makefile 24 | *.modulemap 25 | **/*.modulemap 26 | **/*.docc/* 27 | *.xcprivacy 28 | **/*.xcprivacy 29 | *.symlink 30 | **/*.symlink 31 | Dockerfile 32 | **/Dockerfile 33 | Snippets/* 34 | Sources/CNIOAtomics/src/cpp_magic.h 35 | Sources/CNIOLLHTTP/LICENSE 36 | Sources/CNIOLLHTTP/c_nio_api.c 37 | Sources/CNIOLLHTTP/c_nio_http.c 38 | Sources/CNIOLLHTTP/c_nio_llhttp.c 39 | Sources/CNIOLLHTTP/include/c_nio_llhttp.h 40 | Sources/CNIOSHA1/c_nio_sha1.c 41 | Sources/CNIOSHA1/include/CNIOSHA1.h 42 | dev/alloc-limits-from-test-output 43 | dev/boxed-existentials.d 44 | dev/git.commit.template 45 | dev/lldb-smoker 46 | dev/make-single-file-spm 47 | dev/malloc-aggregation.d 48 | dev/update-alloc-limits-to-last-completed-ci-build 49 | scripts/nio-diagnose 50 | -------------------------------------------------------------------------------- /.mailfilter: -------------------------------------------------------------------------------- 1 | # This is a list of `shasum` hashed email addresses which are filtered from CONTRIBUTORS.txt, typically for privacy. 2 | # Lines can be generated by running `echo -n 'My Name ' | shasum | head -c 40`. 3 | 4 | 38268a29b340ecfb435c5e6c5827a596acb71cc6 5 | 886d1da6503c6de1d630beaf6acb667e4ce3e2a0 6 | f0c2beeae30f3012fa02257998baca1737540bda 7 | -------------------------------------------------------------------------------- /.spi.yml: -------------------------------------------------------------------------------- 1 | version: 1 2 | builder: 3 | configs: 4 | - documentation_targets: [NIO, NIOConcurrencyHelpers, NIOCore, NIOEmbedded, NIOFoundationCompat, NIOHTTP1, NIOPosix, NIOTLS, NIOWebSocket, NIOTestUtils, _NIOFileSystem] 5 | -------------------------------------------------------------------------------- /Benchmarks/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | /.build 3 | /Packages 4 | xcuserdata/ 5 | DerivedData/ 6 | .swiftpm/configuration/registries.json 7 | .swiftpm/xcode/package.xcworkspace/contents.xcworkspacedata 8 | .netrc 9 | .benchmarkBaselines/ -------------------------------------------------------------------------------- /Benchmarks/Benchmarks/NIOPosixBenchmarks/Util/GlobalExecutor.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 | #if canImport(Darwin) 16 | import Darwin.C 17 | #elseif canImport(Glibc) 18 | import Glibc 19 | #else 20 | #error("Unsupported platform.") 21 | #endif 22 | 23 | // This file allows us to hook the global executor which 24 | // we can use to mimic task executors for now. 25 | typealias EnqueueGlobalHook = @convention(thin) (UnownedJob, @convention(thin) (UnownedJob) -> Void) -> Void 26 | 27 | var swiftTaskEnqueueGlobalHook: EnqueueGlobalHook? { 28 | get { _swiftTaskEnqueueGlobalHook.pointee } 29 | set { _swiftTaskEnqueueGlobalHook.pointee = newValue } 30 | } 31 | 32 | private let _swiftTaskEnqueueGlobalHook: UnsafeMutablePointer = 33 | dlsym(dlopen(nil, RTLD_LAZY), "swift_task_enqueueGlobal_hook").assumingMemoryBound(to: EnqueueGlobalHook?.self) 34 | -------------------------------------------------------------------------------- /Benchmarks/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.10 2 | 3 | import PackageDescription 4 | 5 | let package = Package( 6 | name: "benchmarks", 7 | platforms: [ 8 | .macOS("14") 9 | ], 10 | dependencies: [ 11 | .package(path: "../"), 12 | .package(url: "https://github.com/ordo-one/package-benchmark.git", from: "1.22.0"), 13 | ], 14 | targets: [ 15 | .executableTarget( 16 | name: "NIOPosixBenchmarks", 17 | dependencies: [ 18 | .product(name: "Benchmark", package: "package-benchmark"), 19 | .product(name: "NIOCore", package: "swift-nio"), 20 | .product(name: "NIOPosix", package: "swift-nio"), 21 | ], 22 | path: "Benchmarks/NIOPosixBenchmarks", 23 | plugins: [ 24 | .plugin(name: "BenchmarkPlugin", package: "package-benchmark") 25 | ] 26 | ), 27 | .executableTarget( 28 | name: "NIOCoreBenchmarks", 29 | dependencies: [ 30 | .product(name: "Benchmark", package: "package-benchmark"), 31 | .product(name: "NIOCore", package: "swift-nio"), 32 | .product(name: "NIOEmbedded", package: "swift-nio"), 33 | ], 34 | path: "Benchmarks/NIOCoreBenchmarks", 35 | plugins: [ 36 | .plugin(name: "BenchmarkPlugin", package: "package-benchmark") 37 | ] 38 | ), 39 | ] 40 | ) 41 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/5.10/NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 8000 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/5.10/NIOCoreBenchmarks.WaitOnPromise.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 6000, 3 | "memoryLeaked" : 0 4 | } 5 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/5.10/NIOPosixBenchmarks.TCPEcho.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 108 3 | } 4 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/5.10/NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 164375 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/6.0/NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 8000 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/6.0/NIOPosixBenchmarks.TCPEcho.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 108 3 | } 4 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/6.0/NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 164376 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/6.1/NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 8000 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/6.1/NIOPosixBenchmarks.TCPEcho.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 108 3 | } 4 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/6.1/NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 164376 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/nightly-main/NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 8000 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/nightly-main/NIOPosixBenchmarks.TCPEcho.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 108 3 | } 4 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/nightly-main/NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal": 82000 3 | } 4 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/nightly-next/NIOCoreBenchmarks.NIOAsyncChannel.init.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 8000 3 | } -------------------------------------------------------------------------------- /Benchmarks/Thresholds/nightly-next/NIOPosixBenchmarks.TCPEcho.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 108 3 | } 4 | -------------------------------------------------------------------------------- /Benchmarks/Thresholds/nightly-next/NIOPosixBenchmarks.TCPEchoAsyncChannel.p90.json: -------------------------------------------------------------------------------- 1 | { 2 | "mallocCountTotal" : 164376 3 | } -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Code of Conduct 2 | 3 | The code of conduct for this project can be found at https://swift.org/code-of-conduct. 4 | 5 | 6 | -------------------------------------------------------------------------------- /IntegrationTests/allocation-counter-tests-framework/template/AtomicCounter/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.10 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | //===----------------------------------------------------------------------===// 4 | // 5 | // This source file is part of the SwiftNIO open source project 6 | // 7 | // Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 8 | // Licensed under Apache License v2.0 9 | // 10 | // See LICENSE.txt for license information 11 | // See CONTRIBUTORS.txt for the list of SwiftNIO project authors 12 | // 13 | // SPDX-License-Identifier: Apache-2.0 14 | // 15 | //===----------------------------------------------------------------------===// 16 | 17 | import PackageDescription 18 | 19 | let package = Package( 20 | name: "AtomicCounter", 21 | products: [ 22 | .library(name: "AtomicCounter", type: .dynamic, targets: ["AtomicCounter"]) 23 | ], 24 | dependencies: [], 25 | targets: [ 26 | .target( 27 | name: "AtomicCounter", 28 | dependencies: [] 29 | ) 30 | ] 31 | ) 32 | -------------------------------------------------------------------------------- /IntegrationTests/allocation-counter-tests-framework/template/AtomicCounter/Sources/AtomicCounter/include/atomic-counter.h: -------------------------------------------------------------------------------- 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 | #ifndef ATOMIC_COUNTER 16 | #define ATOMIC_COUNTER 17 | 18 | #include 19 | 20 | void inc_free_counter(void); 21 | void reset_free_counter(void); 22 | long read_free_counter(void); 23 | 24 | void inc_malloc_counter(void); 25 | void reset_malloc_counter(void); 26 | long read_malloc_counter(void); 27 | 28 | void add_malloc_bytes_counter(intptr_t v); 29 | void reset_malloc_bytes_counter(void); 30 | intptr_t read_malloc_bytes_counter(void); 31 | 32 | typedef struct { 33 | size_t count; 34 | int *leaked; 35 | } LeakedFDs; 36 | 37 | void begin_tracking_fds(void); 38 | void track_open_fd(int fd); 39 | void track_closed_fd(int fd); 40 | LeakedFDs stop_tracking_fds(void); 41 | 42 | #endif 43 | -------------------------------------------------------------------------------- /IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoHook/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.10 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | //===----------------------------------------------------------------------===// 4 | // 5 | // This source file is part of the SwiftNIO open source project 6 | // 7 | // Copyright (c) 2017-2020 Apple Inc. and the SwiftNIO project authors 8 | // Licensed under Apache License v2.0 9 | // 10 | // See LICENSE.txt for license information 11 | // See CONTRIBUTORS.txt for the list of SwiftNIO project authors 12 | // 13 | // SPDX-License-Identifier: Apache-2.0 14 | // 15 | //===----------------------------------------------------------------------===// 16 | 17 | import PackageDescription 18 | 19 | let package = Package( 20 | name: "HookedFunctions", 21 | products: [ 22 | .library(name: "HookedFunctions", type: .dynamic, targets: ["HookedFunctions"]) 23 | ], 24 | dependencies: [ 25 | .package(url: "../AtomicCounter/", branch: "main") 26 | ], 27 | targets: [ 28 | .target(name: "HookedFunctions", dependencies: ["AtomicCounter"]) 29 | ] 30 | ) 31 | -------------------------------------------------------------------------------- /IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoNotHook/Package.swift: -------------------------------------------------------------------------------- 1 | // swift-tools-version:5.10 2 | // The swift-tools-version declares the minimum version of Swift required to build this package. 3 | //===----------------------------------------------------------------------===// 4 | // 5 | // This source file is part of the SwiftNIO open source project 6 | // 7 | // Copyright (c) 2017-2020 Apple Inc. and the SwiftNIO project authors 8 | // Licensed under Apache License v2.0 9 | // 10 | // See LICENSE.txt for license information 11 | // See CONTRIBUTORS.txt for the list of SwiftNIO project authors 12 | // 13 | // SPDX-License-Identifier: Apache-2.0 14 | // 15 | //===----------------------------------------------------------------------===// 16 | 17 | import PackageDescription 18 | 19 | let package = Package( 20 | name: "HookedFunctions", 21 | products: [ 22 | .library(name: "HookedFunctions", type: .dynamic, targets: ["HookedFunctions"]) 23 | ], 24 | dependencies: [ 25 | .package(url: "../AtomicCounter/", branch: "main") 26 | ], 27 | targets: [ 28 | .target(name: "HookedFunctions", dependencies: ["AtomicCounter"]) 29 | ] 30 | ) 31 | -------------------------------------------------------------------------------- /IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoNotHook/Sources/HookedFunctions/include/hooked-functions.h: -------------------------------------------------------------------------------- 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 | #ifndef HOOKED_FREE 16 | #define HOOKED_FREE 17 | 18 | #endif 19 | -------------------------------------------------------------------------------- /IntegrationTests/allocation-counter-tests-framework/template/HookedFunctionsDoNotHook/Sources/HookedFunctions/src/hooked-functions.c: -------------------------------------------------------------------------------- 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 | -------------------------------------------------------------------------------- /IntegrationTests/allocation-counter-tests-framework/template/Sources/bootstrapDoNotHook/main.c: -------------------------------------------------------------------------------- 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 | void swift_main(void); 16 | 17 | int main() { 18 | swift_main(); 19 | } 20 | -------------------------------------------------------------------------------- /IntegrationTests/plugin_echo.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | function plugin_echo_test_suite_begin() { 17 | echo "Running test suite '$1'" 18 | } 19 | 20 | function plugin_echo_test_suite_end() { 21 | true 22 | } 23 | 24 | # test_name 25 | function plugin_echo_test_begin() { 26 | echo -n "Running test '$1'... " 27 | } 28 | 29 | function plugin_echo_test_skip() { 30 | echo "Skipping test '$1'" 31 | } 32 | 33 | function plugin_echo_test_ok() { 34 | echo "OK (${1}s)" 35 | } 36 | 37 | function plugin_echo_test_fail() { 38 | echo "FAILURE ($1)" 39 | echo "--- OUTPUT BEGIN ---" 40 | cat "$2" 41 | echo "--- OUTPUT END ---" 42 | } 43 | 44 | function plugin_echo_test_end() { 45 | true 46 | } 47 | 48 | function plugin_echo_summary_ok() { 49 | echo "OK (ran $1 tests successfully)" 50 | } 51 | 52 | function plugin_echo_summary_fail() { 53 | echo "FAILURE (oks: $1, failures: $2)" 54 | } 55 | 56 | function plugin_echo_init() { 57 | true 58 | } 59 | -------------------------------------------------------------------------------- /IntegrationTests/run-single-test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | ( 17 | # this sub-shell is where the actual test is run 18 | set -eu 19 | set -x 20 | set -o pipefail 21 | 22 | test="$1" 23 | # shellcheck disable=SC2034 # Used by whatever we source transpile in 24 | tmp="$2" 25 | # shellcheck disable=SC2034 # Used by whatever we source transpile in 26 | root="$3" 27 | # shellcheck disable=SC2034 # Used by whatever we source transpile in 28 | g_show_info="$4" 29 | here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 30 | 31 | # shellcheck source=IntegrationTests/test_functions.sh 32 | source "$here/test_functions.sh" 33 | # shellcheck source=/dev/null 34 | source "$test" 35 | wait 36 | ) 37 | exit_code=$? 38 | exit $exit_code 39 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_01_get_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | htdocs=$(get_htdocs "$token") 22 | echo FOO BAR > "$htdocs/some_file.txt" 23 | touch "$htdocs/empty" 24 | for file in some_file.txt empty; do 25 | for method in sendfile fileio; do 26 | do_curl "$token" "http://foobar.com/$method/$file" > "${tmp:?"tmp variable not set"}/out.txt" 27 | assert_equal_files "$htdocs/$file" "$tmp/out.txt" 28 | done 29 | done 30 | stop_server "$token" 31 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_02_get_random_bytes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | htdocs=$(get_htdocs "$token") 22 | base="s/o/m/e/r/a/n/d/o/m/f/o/l/d/e/r" 23 | mkdir -p "$htdocs/$base" 24 | dd if=/dev/urandom of="$htdocs/$base/random.bytes" bs=$((1024 * 1024)) count=2 25 | for method in sendfile fileio; do 26 | do_curl "$token" "http://foobar.com/$method/$base/random.bytes" > "${tmp:?"tmp variable not set"}/random.bytes" 27 | assert_equal_files "$htdocs/$base/random.bytes" "$tmp/random.bytes" 28 | done 29 | stop_server "$token" 30 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_03_post_random_bytes.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | dd if=/dev/urandom of="${tmp:?"tmp variable not set"}/random.bytes" bs=$((64*1024)) count=1 22 | do_curl "$token" --data-binary "@$tmp/random.bytes" \ 23 | "http://foobar.com/dynamic/echo" > "$tmp/random.bytes.out" 24 | cmp "$tmp/random.bytes" "$tmp/random.bytes.out" 25 | stop_server "$token" 26 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_04_keep_alive_works.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | server_pid=$(get_server_pid "$token") 22 | echo -n \ 23 | "$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid$server_pid" \ 24 | > "${tmp:?"tmp variable not set"}/out_expected" 25 | do_curl "$token" \ 26 | "http://foobar.com/dynamic/pid" \ 27 | "http://foobar.com/dynamic/pid" \ 28 | "http://foobar.com/dynamic/pid" \ 29 | "http://foobar.com/dynamic/pid" \ 30 | "http://foobar.com/dynamic/pid" \ 31 | "http://foobar.com/dynamic/pid" \ 32 | "http://foobar.com/dynamic/pid" \ 33 | "http://foobar.com/dynamic/pid" \ 34 | "http://foobar.com/dynamic/pid" \ 35 | "http://foobar.com/dynamic/pid" \ 36 | > "$tmp/out_actual" 37 | assert_equal_files "$tmp/out_expected" "$tmp/out_actual" 38 | stop_server "$token" 39 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_05_repeated_reqs_work.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | do_curl "$token" "http://foobar.com/dynamic/pid" > "${tmp:?"tmp variable not set"}/out" 22 | for _ in $(seq 100); do 23 | do_curl "$token" "http://foobar.com/dynamic/pid" > "$tmp/out2" 24 | assert_equal_files "$tmp/out" "$tmp/out2" 25 | done 26 | stop_server "$token" 27 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_06_http_1.0.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | echo foo > "${tmp:?"tmp variable not set"}/out_expected" 22 | do_curl "$token" --data-binary "@$tmp/out_expected" --http1.0 \ 23 | "http://foobar.com/dynamic/echo_balloon" > "$tmp/out_actual" 24 | assert_equal_files "$tmp/out_expected" "$tmp/out_actual" 25 | stop_server "$token" 26 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_07_headers_work.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | do_curl "$token" -H "foo: bar" --http1.0 \ 22 | "http://foobar.com/dynamic/info" >"${tmp:?"tmp variable not set"}/out" 23 | if ! grep -q 'foo: bar' "$tmp/out"; then 24 | fail "couldn't find header in response" 25 | fi 26 | stop_server "$token" 27 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_08_survive_signals.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | htdocs=$(get_htdocs "$token") 22 | server_pid=$(get_server_pid "$token") 23 | echo FOO BAR > "$htdocs/some_file.txt" 24 | 25 | for _ in $(seq 20); do 26 | # send some signals that are usually discarded 27 | kill -CHLD "$server_pid" # ignore-unacceptable-language 28 | kill -URG "$server_pid" # ignore-unacceptable-language 29 | kill -CONT "$server_pid" # ignore-unacceptable-language 30 | kill -WINCH "$server_pid" # ignore-unacceptable-language 31 | 32 | do_curl "$token" "http://foobar.com/fileio/some_file.txt" > "${tmp:?"tmp variable not set"}/out.txt" & 33 | curl_pid=$! 34 | for _ in $(seq 20); do 35 | kill -URG "$server_pid" # ignore-unacceptable-language 36 | done 37 | wait $curl_pid 38 | cmp "$htdocs/some_file.txt" "$tmp/out.txt" 39 | done 40 | 41 | stop_server "$token" 42 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_09_curl_happy_with_trailers.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | htdocs=$(get_htdocs "$token") 22 | server_pid=$(get_server_pid "$token") 23 | backslash_r=$(echo -ne '\r') 24 | cat > "$htdocs/some_file.txt" < "${tmp:?"tmp variable not set"}/out.txt" 36 | assert_equal_files "$htdocs/some_file.txt" "${tmp}/out.txt" 37 | stop_server "$token" 38 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_10_connection_drop_in_body_ok.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | server_pid=$(get_server_pid "$token") 22 | socket=$(get_socket "$token") 23 | 24 | kill -0 "$server_pid" # ignore-unacceptable-language 25 | ( 26 | echo -e 'POST /dynamic/echo HTTP/1.1\r\nContent-Length: 400000\r\n\r\nsome_bytes' 27 | for f in $(seq 5); do 28 | echo "$f" 29 | sleep 0.1 30 | done 31 | ) | do_nc -U "$socket" 32 | sleep 0.1 33 | kill -0 "$server_pid" # ignore-unacceptable-language 34 | stop_server "$token" 35 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_11_res_body_streaming.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | # shellcheck disable=SC2034 22 | htdocs=$(get_htdocs "$token") 23 | # shellcheck disable=SC2034 24 | server_pid=$(get_server_pid "$token") 25 | # shellcheck disable=SC2034 26 | socket=$(get_socket "$token") 27 | 28 | cat > "${tmp:?"tmp variable not set"}/expected" < "$tmp/actual" 39 | assert_equal_files "$tmp/expected" "$tmp/actual" 40 | 41 | sleep 1 # need to have the next write fail 42 | stop_server "$token" 43 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_14_strict_mode_assertion.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | # shellcheck disable=SC2034 22 | htdocs=$(get_htdocs "$token") 23 | socket=$(get_socket "$token") 24 | echo -e 'GET / HTT\r\n\r\n' | do_nc -U "$socket" > "${tmp:?"tmp variable not set"}/actual" 25 | 26 | if ! grep -q 'HTTP/1.1 400 Bad Request' "$tmp/actual"; then 27 | fail "couldn't find status line in response" 28 | fi 29 | if ! grep -q 'Content-Length: 0' "$tmp/actual"; then 30 | fail "couldn't find Content-Length in response" 31 | fi 32 | if ! grep -q 'Connection: close' "$tmp/actual"; then 33 | fail "couldn't find Connection: close in response" 34 | fi 35 | 36 | linecount=$(wc "$tmp/actual") 37 | if [[ $linecount -ne 4 ]]; then 38 | fail "overlong response" 39 | fi 40 | stop_server "$token" 41 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_15_post_in_chunked_encoding.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | dd if=/dev/urandom of="${tmp:?"tmp variable not set"}/random.bytes" bs=$((64*1024)) count=1 22 | do_curl "$token" -X POST --header "Transfer-Encoding: chunked" \ 23 | --data-binary "@$tmp/random.bytes" \ 24 | "http://foobar.com/dynamic/echo" > "$tmp/random.bytes.out" 25 | cmp "$tmp/random.bytes" "$tmp/random.bytes.out" 26 | stop_server "$token" 27 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_16_tcp_client_ip.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" tcp 21 | # shellcheck disable=SC2034 22 | htdocs=$(get_htdocs "$token") 23 | echo -n '[IPv4]127.0.0.1' > "${tmp:?"tmp variable not set"}/expected_ipv4" 24 | echo -n '[IPv6]::1' > "$tmp/expected_ipv6" 25 | do_curl "$token" "http://localhost:$(get_server_port "$token")/dynamic/client-ip" > "$tmp/actual" 26 | if grep -q '\[IPv4\]127.0.0.1' "$tmp/actual"; then 27 | true 28 | elif grep -q '\[IPv6\]::1' "$tmp/actual"; then 29 | true 30 | else 31 | fail "could not find client IP in $(cat "$tmp/actual")" 32 | fi 33 | stop_server "$token" 34 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_17_serve_massive_sparse_file.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | htdocs=$(get_htdocs "$token") 22 | # create a 3GB sparse file, this is above the 2,147,479,552 mentioned in the 23 | # BUGS section of Linux's sendfile(2) man page. 24 | dd if=/dev/zero of="$htdocs/lots_of_zeroes" seek=$((3 * 1024)) bs=$((1024 * 1024)) count=1 25 | do_curl "$token" "http://foobar.com/fileio/lots_of_zeroes" | shasum > "${tmp:?"tmp variable not set"}/actual_sha" 26 | echo "bf184d91c8f82092198e4d8e1d029e576dbec3bc -" > "$tmp/expected_sha" 27 | assert_equal_files "$tmp/expected_sha" "$tmp/actual_sha" 28 | sleep 3 # wait for all the fds to be closed 29 | stop_server "$token" 30 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_18_close_with_no_keepalive.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | # shellcheck disable=SC2034 22 | htdocs=$(get_htdocs "$token") 23 | server_pid=$(get_server_pid "$token") 24 | socket=$(get_socket "$token") 25 | 26 | kill -0 "$server_pid" # ignore-unacceptable-language 27 | 28 | echo -e 'GET /dynamic/count-to-ten HTTP/1.1\r\nConnection: close\r\n\r\n' | \ 29 | do_nc -U "$socket" > "${tmp:?"tmp variable not set"}/actual" 30 | backslash_r=$(echo -ne '\r') 31 | cat > "$tmp/expected" < /dev/null & sleep 0.5; kill -9 $! # ignore-unacceptable-language 33 | sleep 0.2 34 | stop_server "$token" 35 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_22_http_1.0_keep_alive.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | do_curl "$token" -H 'connection: keep-alive' -v --http1.0 \ 22 | "http://foobar.com/dynamic/info" > "${tmp:?"tmp variable not set"}/out_actual" 2>&1 23 | grep -qi '< Connection: keep-alive' "$tmp/out_actual" 24 | grep -qi '< HTTP/1.0 200 OK' "$tmp/out_actual" 25 | stop_server "$token" 26 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_23_repeated_reqs_with_half_closure.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | token=$(create_token) 20 | start_server "$token" 21 | socket=$(get_socket "$token") 22 | echo -ne 'HTTP/1.1 200 OK\r\ncontent-length: 13\r\n\r\nHello World\r\n' > "${tmp:?"tmp variable not set"}/expected" 23 | for _ in $(seq 2000); do 24 | echo -e 'GET / HTTP/1.1\r\n\r\n' | do_nc -w10 -U "$socket" > "$tmp/actual" 25 | assert_equal_files "$tmp/expected" "$tmp/actual" 26 | done 27 | stop_server "$token" 28 | -------------------------------------------------------------------------------- /IntegrationTests/tests_01_http/test_24_http_over_stdio.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | swift build 20 | echo -ne "::: HELLO\n::: WORLD\n:::\n" > "${tmp:?"tmp variable not set"}/file" 21 | lines_in_file="$(wc -l < "$tmp/file" | tr -d '\t ')" 22 | function echo_request_close() { 23 | echo -e 'GET /fileio/file HTTP/1.1\r\nconnection: close\r\nhost: stdio\r\n\r\n' 24 | } 25 | 26 | function echo_request_keep_alive() { 27 | echo -e 'GET /fileio/file HTTP/1.1\r\nconnection: keep-alive\r\nhost: stdio\r\n\r\n' 28 | } 29 | 30 | echo_request_close | "$(swift build --show-bin-path)/NIOHTTP1Server" - "$tmp" | cat > "$tmp/output" 31 | 32 | tail -n "$lines_in_file" "$tmp/output" > "$tmp/output-just-file" 33 | assert_equal_files "$tmp/file" "$tmp/output-just-file" 34 | 35 | how_many=100 36 | { 37 | for _ in $(seq "$(( how_many - 1 ))" ); do 38 | echo_request_keep_alive 39 | done 40 | echo_request_close 41 | } | "$(swift build --show-bin-path)/NIOHTTP1Server" - "$tmp" | grep ^::: > "$tmp/multi-actual" 42 | 43 | set +o pipefail # we know that 'yes' will fail with SIGPIPE 44 | yes "$(cat "$tmp/file")" | head -n $(( lines_in_file * how_many )) > "$tmp/multi-expected" 45 | assert_equal_files "$tmp/multi-expected" "$tmp/multi-actual" 46 | -------------------------------------------------------------------------------- /IntegrationTests/tests_02_syscall_wrappers/test_01_syscall_wrapper_fast.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set -eu 17 | 18 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 19 | source defines.sh 20 | 21 | swift_binary=swift 22 | # shellcheck disable=SC2034 # Used in defines.sh 23 | here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 24 | 25 | if [[ -n "${SWIFT_EXEC-}" ]]; then 26 | swift_binary="$(dirname "$SWIFT_EXEC")/swift" 27 | elif [[ "$(uname -s)" == "Linux" ]]; then 28 | swift_binary=$(which swift) 29 | fi 30 | 31 | tmpdir=$(mktemp -d /tmp/.swift-nio-syscall-wrappers-sh-test_XXXXXX) 32 | mkdir "$tmpdir/syscallwrapper" 33 | cd "$tmpdir/syscallwrapper" 34 | swift package init --type=executable 35 | 36 | main_path="$tmpdir/syscallwrapper/Sources/main.swift" 37 | if [[ -d "$tmpdir/syscallwrapper/Sources/syscallwrapper/" ]]; then 38 | main_path="$tmpdir/syscallwrapper/Sources/syscallwrapper/main.swift" 39 | fi 40 | 41 | cat > "$main_path" < "${tmp:?"tmp variable not set"}/linked_libs" 26 | ;; 27 | Linux) 28 | ldd "$binary" > "$tmp/linked_libs" 29 | ;; 30 | *) 31 | fail "unsupported OS $(uname -s)" 32 | ;; 33 | esac 34 | echo -n > "$tmp/expected" 35 | ! grep "$library" "$tmp/linked_libs" > "$tmp/linked_checked_lib" 36 | 37 | assert_equal_files "$tmp/expected" "$tmp/linked_checked_lib" 38 | } 39 | 40 | for binary in NIOEchoServer NIOEchoClient NIOChatServer NIOChatClient NIOHTTP1Server; do 41 | check_does_not_link /Foundation "${bin_path:?"tmp variable not set"}/$binary" # Darwin (old) 42 | check_does_not_link libFoundation "$bin_path/$binary" # Linux 43 | check_does_not_link swiftFoundation "$bin_path/$binary" # Darwin (new) 44 | done 45 | -------------------------------------------------------------------------------- /IntegrationTests/tests_03_debug_binary_checks/test_02_expected_crashes_work.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2020 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 17 | source defines.sh 18 | 19 | "${bin_path:?"bin_path variable not set"}/NIOCrashTester" run-all 20 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/defines.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/run-nio-alloc-counter-tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2019 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set -eu 17 | here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 18 | 19 | tmp_dir="/tmp" 20 | 21 | while getopts "t:" opt; do 22 | case "$opt" in 23 | t) 24 | tmp_dir="$OPTARG" 25 | ;; 26 | *) 27 | exit 1 28 | ;; 29 | esac 30 | done 31 | 32 | shift $((OPTIND-1)) 33 | 34 | tests_to_run=("$here"/test_*.swift) 35 | 36 | if [[ $# -gt 0 ]]; then 37 | tests_to_run=("$@") 38 | fi 39 | 40 | "$here/../../allocation-counter-tests-framework/run-allocation-counter.sh" \ 41 | -p "$here/../../.." \ 42 | -m NIOCore -m NIOEmbedded -m NIOPosix -m NIOHTTP1 -m NIOWebSocket \ 43 | -s "$here/shared.swift" \ 44 | -t "$tmp_dir" \ 45 | "${tests_to_run[@]}" 46 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_10000000_asyncsequenceproducer.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2022 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 NIOCore 16 | 17 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 18 | private typealias SequenceProducer = NIOAsyncSequenceProducer< 19 | Int, NIOAsyncSequenceProducerBackPressureStrategies.HighLowWatermark, Delegate 20 | > 21 | 22 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 23 | private final class Delegate: NIOAsyncSequenceProducerDelegate, @unchecked Sendable { 24 | private let elements = Array(repeating: 1, count: 1000) 25 | 26 | var source: SequenceProducer.Source! 27 | 28 | func produceMore() { 29 | _ = self.source.yield(contentsOf: self.elements) 30 | } 31 | 32 | func didTerminate() {} 33 | } 34 | 35 | func run(identifier: String) { 36 | guard #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) else { 37 | return 38 | } 39 | measure(identifier: identifier) { 40 | let delegate = Delegate() 41 | let producer = SequenceProducer.makeSequence( 42 | backPressureStrategy: .init(lowWatermark: 100, highWatermark: 500), 43 | delegate: delegate 44 | ) 45 | let sequence = producer.sequence 46 | delegate.source = producer.source 47 | 48 | var counter = 0 49 | for await i in sequence { 50 | counter += i 51 | 52 | if counter == 10_000_000 { 53 | return counter 54 | } 55 | } 56 | 57 | return counter 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_1000000_asyncwriter.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2022 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 DequeModule 16 | import NIOCore 17 | 18 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 19 | private struct Delegate: NIOAsyncWriterSinkDelegate, Sendable { 20 | typealias Element = Int 21 | 22 | func didYield(contentsOf sequence: Deque) {} 23 | 24 | func didTerminate(error: Error?) {} 25 | } 26 | 27 | func run(identifier: String) { 28 | guard #available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) else { 29 | return 30 | } 31 | measure(identifier: identifier) { 32 | let delegate = Delegate() 33 | let newWriter = NIOAsyncWriter.makeWriter(isWritable: true, delegate: delegate) 34 | let writer = newWriter.writer 35 | 36 | for i in 0..<1_000_000 { 37 | try! await writer.yield(i) 38 | } 39 | 40 | return 1_000_000 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_1000_addHandlers.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020-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 NIOCore 16 | import NIOEmbedded 17 | 18 | private final class SimpleHandler: ChannelInboundHandler { 19 | typealias InboundIn = NIOAny 20 | } 21 | 22 | func run(identifier: String) { 23 | measure(identifier: identifier) { 24 | let iterations = 1000 25 | for _ in 0.. Int in 24 | var counter: Int = 0 25 | 26 | let deadline = NIODeadline.now() + .hours(1) 27 | 28 | for _ in 0..<10000 { 29 | loop.flatScheduleTask(deadline: deadline) { 30 | counter &+= 1 31 | return loop.makeSucceededFuture(counter) 32 | } 33 | } 34 | 35 | return counter 36 | }.wait() 37 | 38 | try! group.syncShutdownGracefully() 39 | return counter 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_flat_schedule_assume_isolated_10000_tasks.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-2025 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 Dispatch 16 | import NIOCore 17 | import NIOPosix 18 | 19 | func run(identifier: String) { 20 | measure(identifier: identifier) { 21 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 22 | let loop = group.next() 23 | let counter = try! loop.submit { () -> Int in 24 | var counter: Int = 0 25 | 26 | let deadline = NIODeadline.now() + .hours(1) 27 | 28 | for _ in 0..<10000 { 29 | loop.assumeIsolated().flatScheduleTask(deadline: deadline) { 30 | counter &+= 1 31 | return loop.makeSucceededFuture(counter) 32 | } 33 | } 34 | 35 | return counter 36 | }.wait() 37 | 38 | try! group.syncShutdownGracefully() 39 | return counter 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_future_erase_result.swift: -------------------------------------------------------------------------------- 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 NIOCore 16 | import NIOEmbedded 17 | 18 | func run(identifier: String) { 19 | measure(identifier: identifier) { 20 | @inline(never) 21 | func doEraseResult(loop: EventLoop) { 22 | // In an ideal implementation the only allocation is this promise. 23 | let p = loop.makePromise(of: Int.self) 24 | let f = p.futureResult.map { (r: Int) -> Void in 25 | // This closure is a value-to-no-value erase that closes over nothing. 26 | // Ideally this would not allocate. 27 | return 28 | }.map { (_: Void) -> Void in 29 | // This closure is a nothing-to-nothing map, basically a "completed" observer. This should 30 | // also not allocate, but it has a separate code path to the above. 31 | } 32 | p.succeed(0) 33 | } 34 | 35 | let el = EmbeddedEventLoop() 36 | for _ in 0..<1000 { 37 | doEraseResult(loop: el) 38 | } 39 | return 1000 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_modifying_1000_circular_buffer_elements.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-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 NIOCore 16 | 17 | func run(identifier: String) { 18 | var buffer = CircularBuffer<[Int]>(initialCapacity: 100) 19 | for _ in 0..<100 { 20 | buffer.append([]) 21 | } 22 | 23 | measure(identifier: identifier) { 24 | for idx in 0..<1000 { 25 | let index = buffer.index(buffer.startIndex, offsetBy: idx % 100) 26 | buffer.modify(index) { value in 27 | value.append(idx) 28 | } 29 | } 30 | return buffer.last!.last! 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_modifying_byte_buffer_view.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-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 | import NIOCore 15 | 16 | func run(identifier: String) { 17 | let allocator = ByteBufferAllocator() 18 | let data = Array(repeating: UInt8(0), count: 1024) 19 | 20 | measure(identifier: identifier) { 21 | var count = 0 22 | 23 | for _ in 0..<1_000 { 24 | var buffer = allocator.buffer(capacity: data.count) 25 | buffer.writeBytes(data) 26 | 27 | var view = ByteBufferView(buffer) 28 | 29 | // Unfortunately this CoWs: https://bugs.swift.org/browse/SR-11675 30 | view[0] = 42 31 | view.replaceSubrange(0..<4, with: [0x0, 0x1, 0x2, 0x3]) 32 | 33 | var modified = ByteBuffer(view) 34 | modified.setBytes([0xa, 0xb, 0xc], at: modified.readerIndex) 35 | count &+= modified.readableBytes 36 | } 37 | 38 | return count 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_schedule_10000_tasks.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-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 Dispatch 16 | import NIOPosix 17 | 18 | func run(identifier: String) { 19 | measure(identifier: identifier) { 20 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 21 | let loop = group.next() 22 | let counter = try! loop.submit { () -> Int in 23 | var counter: Int = 0 24 | 25 | for _ in 0..<10000 { 26 | loop.scheduleTask(in: .hours(1)) { 27 | counter &+= 1 28 | } 29 | } 30 | 31 | return counter 32 | }.wait() 33 | 34 | try! group.syncShutdownGracefully() 35 | return counter 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_schedule_and_run_10000_tasks.swift: -------------------------------------------------------------------------------- 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 Dispatch 16 | import NIOPosix 17 | 18 | func run(identifier: String) { 19 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 20 | let loop = group.next() 21 | let dg = DispatchGroup() 22 | 23 | measure(identifier: identifier) { 24 | var counter = 0 25 | 26 | try! loop.submit { 27 | for _ in 0..<10000 { 28 | dg.enter() 29 | 30 | loop.scheduleTask(in: .nanoseconds(0)) { 31 | counter &+= 1 32 | dg.leave() 33 | } 34 | } 35 | }.wait() 36 | dg.wait() 37 | 38 | return counter 39 | } 40 | 41 | try! group.syncShutdownGracefully() 42 | } 43 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_schedule_assume_isolated_10000_tasks.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-2025 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 Dispatch 16 | import NIOPosix 17 | 18 | func run(identifier: String) { 19 | measure(identifier: identifier) { 20 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 21 | let loop = group.next() 22 | let counter = try! loop.submit { () -> Int in 23 | var counter: Int = 0 24 | 25 | for _ in 0..<10000 { 26 | loop.assumeIsolated().scheduleTask(in: .hours(1)) { 27 | counter &+= 1 28 | } 29 | } 30 | 31 | return counter 32 | }.wait() 33 | 34 | try! group.syncShutdownGracefully() 35 | return counter 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_schedule_with_deadline_10000_tasks.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-2025 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 Dispatch 16 | import NIOCore 17 | import NIOPosix 18 | 19 | func run(identifier: String) { 20 | measure(identifier: identifier) { 21 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 22 | let loop = group.next() 23 | let counter = try! loop.submit { () -> Int in 24 | var counter: Int = 0 25 | 26 | let deadline = NIODeadline.now() + .hours(1) 27 | 28 | for _ in 0..<10000 { 29 | loop.scheduleTask(deadline: deadline) { 30 | counter &+= 1 31 | } 32 | } 33 | 34 | return counter 35 | }.wait() 36 | 37 | try! group.syncShutdownGracefully() 38 | return counter 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_schedule_with_deadline_assume_isolated_10000_tasks.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-2025 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 Dispatch 16 | import NIOCore 17 | import NIOPosix 18 | 19 | func run(identifier: String) { 20 | measure(identifier: identifier) { 21 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 22 | let loop = group.next() 23 | let counter = try! loop.submit { () -> Int in 24 | var counter: Int = 0 25 | 26 | let deadline = NIODeadline.now() + .hours(1) 27 | 28 | for _ in 0..<10000 { 29 | loop.assumeIsolated().scheduleTask(deadline: deadline) { 30 | counter &+= 1 31 | return counter 32 | } 33 | } 34 | 35 | return counter 36 | }.wait() 37 | 38 | try! group.syncShutdownGracefully() 39 | return counter 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_scheduling_10000_executions.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-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 Dispatch 16 | import NIOPosix 17 | 18 | func run(identifier: String) { 19 | measure(identifier: identifier) { 20 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 21 | let loop = group.next() 22 | let dg = DispatchGroup() 23 | 24 | try! loop.submit { 25 | for _ in 0..<10_000 { 26 | dg.enter() 27 | loop.execute { dg.leave() } 28 | } 29 | }.wait() 30 | dg.wait() 31 | try! group.syncShutdownGracefully() 32 | return 10_000 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_submit_10000_tasks.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-2025 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 Dispatch 16 | import NIOPosix 17 | 18 | func run(identifier: String) { 19 | measure(identifier: identifier) { 20 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 21 | let loop = group.next() 22 | let counter = try! loop.submit { () -> Int in 23 | var counter: Int = 0 24 | 25 | for _ in 0..<10000 { 26 | _ = loop.submit { 27 | counter &+= 1 28 | return counter 29 | } 30 | } 31 | 32 | return counter 33 | }.wait() 34 | 35 | try! group.syncShutdownGracefully() 36 | return counter 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_submit_assume_isolated_10000_tasks.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-2025 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 Dispatch 16 | import NIOPosix 17 | 18 | func run(identifier: String) { 19 | measure(identifier: identifier) { 20 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 21 | let loop = group.next() 22 | let counter = try! loop.submit { () -> Int in 23 | var counter: Int = 0 24 | 25 | for _ in 0..<10000 { 26 | _ = loop.assumeIsolated().submit { 27 | counter &+= 1 28 | return counter 29 | } 30 | } 31 | 32 | return counter 33 | }.wait() 34 | 35 | try! group.syncShutdownGracefully() 36 | return counter 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_udp_1000_reqs_1_conn.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020-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 NIOPosix 16 | 17 | func run(identifier: String) { 18 | measure(identifier: identifier) { 19 | let numberDone = try! UDPShared.doUDPRequests(group: group, number: 1000) 20 | precondition(numberDone == 1000) 21 | return numberDone 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /IntegrationTests/tests_04_performance/test_01_resources/test_udp_1_reqs_1000_conn.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020-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 NIOPosix 16 | 17 | func run(identifier: String) { 18 | measure(identifier: identifier) { 19 | var numberDone = 1 20 | for _ in 0..<1000 { 21 | let newDones = try! UDPShared.doUDPRequests(group: group, number: 1) 22 | precondition(newDones == 1) 23 | numberDone += newDones 24 | } 25 | return numberDone 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /IntegrationTests/tests_05_assertions/test_01_syscall_wrapper_fast.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set -eu 17 | 18 | # shellcheck source=IntegrationTests/tests_01_http/defines.sh 19 | source defines.sh 20 | 21 | swift_binary=swiftc 22 | here="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )" 23 | 24 | if [[ -n "${SWIFT_EXEC-}" ]]; then 25 | swift_binary="$(dirname "$SWIFT_EXEC")/swiftc" 26 | elif [[ "$(uname -s)" == "Linux" ]]; then 27 | swift_binary=$(which swiftc) 28 | fi 29 | 30 | cp "$here/../../Sources/NIOConcurrencyHelpers/"{lock,NIOLock}.swift "${tmp:?"tmp variable not set"}" 31 | cat > "$tmp/main.swift" <<"EOF" 32 | let l = NIOLock() 33 | l.lock() 34 | l.lock() 35 | EOF 36 | 37 | "$swift_binary" -o "$tmp/test" "$tmp/main.swift" "$tmp/"{lock,NIOLock}.swift 38 | if "$tmp/test"; then 39 | fail "should have crashed" 40 | else 41 | exit_code=$? 42 | 43 | # expecting irrecoverable error as process should be terminated through fatalError/precondition/assert 44 | architecture=$(uname -m) 45 | if [[ $architecture =~ ^(arm|aarch) ]]; then 46 | assert_equal $exit_code $(( 128 + 5 )) # 5 == SIGTRAP aka trace trap, expected on ARM 47 | elif [[ $architecture =~ ^(x86|i386) ]]; then 48 | assert_equal $exit_code $(( 128 + 4 )) # 4 == SIGILL aka illegal instruction, expected on x86 49 | else 50 | fail "unknown CPU architecture for which we don't know the expected signal for a crash" 51 | fi 52 | fi 53 | -------------------------------------------------------------------------------- /Sources/CNIOLLHTTP/LICENSE: -------------------------------------------------------------------------------- 1 | This software is licensed under the MIT License. 2 | 3 | Copyright Fedor Indutny, 2018. 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a 6 | copy of this software and associated documentation files (the 7 | "Software"), to deal in the Software without restriction, including 8 | without limitation the rights to use, copy, modify, merge, publish, 9 | distribute, sublicense, and/or sell copies of the Software, and to permit 10 | persons to whom the Software is furnished to do so, subject to the 11 | following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included 14 | in all copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 17 | OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 18 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN 19 | NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 20 | DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR 21 | OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE 22 | USE OR OTHER DEALINGS IN THE SOFTWARE. 23 | -------------------------------------------------------------------------------- /Sources/CNIOLLHTTP/include/CNIOLLHTTP.h: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-2022 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 | // adaptions for llhttp to make it more straightforward to use from Swift 16 | 17 | #ifndef C_NIO_LLHTTP_SWIFT 18 | #define C_NIO_LLHTTP_SWIFT 19 | 20 | #include "c_nio_llhttp.h" 21 | 22 | static inline llhttp_errno_t c_nio_llhttp_execute_swift(llhttp_t *parser, 23 | const void *data, 24 | size_t len) { 25 | return c_nio_llhttp_execute(parser, (const char *)data, len); 26 | } 27 | 28 | #endif 29 | -------------------------------------------------------------------------------- /Sources/CNIOLinux/include/liburing_nio.h: -------------------------------------------------------------------------------- 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 | #ifndef LIBURING_NIO_H 16 | #define LIBURING_NIO_H 17 | 18 | #ifdef __linux__ 19 | 20 | #ifdef SWIFTNIO_USE_IO_URING 21 | 22 | #if __has_include() 23 | #include 24 | #else 25 | #error "SWIFTNIO_USE_IO_URING specified but liburing.h not available. You need to install https://github.com/axboe/liburing." 26 | #endif 27 | 28 | // OR in the IOSQE_IO_LINK flag, couldn't access the define from Swift 29 | void CNIOLinux_io_uring_set_link_flag(struct io_uring_sqe *sqe); 30 | 31 | // No way I managed to get this even when defining _GNU_SOURCE properly. Argh. 32 | unsigned int CNIOLinux_POLLRDHUP(); 33 | 34 | #endif 35 | 36 | #endif /* __linux__ */ 37 | 38 | #endif /* LIBURING_NIO_H */ 39 | -------------------------------------------------------------------------------- /Sources/CNIOLinux/liburing_shims.c: -------------------------------------------------------------------------------- 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 | // Support functions for liburing 16 | 17 | // Check if this is needed, copied from shim.c to avoid possible problems due to: 18 | // Xcode's Archive builds with Xcode's Package support struggle with empty .c files 19 | // (https://bugs.swift.org/browse/SR-12939). 20 | void CNIOLinux_i_do_nothing_just_working_around_a_darwin_toolchain_bug2(void) {} 21 | 22 | #ifdef __linux__ 23 | 24 | #ifdef SWIFTNIO_USE_IO_URING 25 | 26 | #define _GNU_SOURCE 27 | #include 28 | #include 29 | #include 30 | 31 | void CNIOLinux_io_uring_set_link_flag(struct io_uring_sqe *sqe) 32 | { 33 | sqe->flags |= IOSQE_IO_LINK; 34 | return; 35 | } 36 | 37 | unsigned int CNIOLinux_POLLRDHUP() 38 | { 39 | return POLLRDHUP; 40 | } 41 | 42 | #endif 43 | 44 | #endif 45 | -------------------------------------------------------------------------------- /Sources/CNIOWASI/CNIOWASI.c: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2024 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 | -------------------------------------------------------------------------------- /Sources/CNIOWASI/include/CNIOWASI.h: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) YEARS 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 | #pragma once 16 | 17 | #if __wasi__ 18 | 19 | #include 20 | #include 21 | 22 | static inline void CNIOWASI_gettime(struct timespec *tv) { 23 | // ClangImporter doesn't support `CLOCK_MONOTONIC` declaration in WASILibc, thus we have to define a bridge manually 24 | clock_gettime(CLOCK_MONOTONIC, tv); 25 | } 26 | 27 | static inline int CNIOWASI_O_CREAT() { 28 | // ClangImporter doesn't support `O_CREATE` declaration in WASILibc, thus we have to define a bridge manually 29 | return O_CREAT; 30 | } 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /Sources/CNIOWindows/WSAStartup.c: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020 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 | #if defined(_WIN32) 16 | 17 | #include 18 | 19 | #include 20 | 21 | #pragma section(".CRT$XCU", read) 22 | 23 | static void __cdecl 24 | NIOWSAStartup(void) { 25 | WSADATA wsa; 26 | WORD wVersionRequested = MAKEWORD(2, 2); 27 | if (!WSAStartup(wVersionRequested, &wsa)) { 28 | _exit(EXIT_FAILURE); 29 | } 30 | } 31 | 32 | __declspec(allocate(".CRT$XCU")) 33 | static void (*pNIOWSAStartup)(void) = &NIOWSAStartup; 34 | 35 | #endif 36 | -------------------------------------------------------------------------------- /Sources/CNIOWindows/include/module.modulemap: -------------------------------------------------------------------------------- 1 | module CNIOWindows { 2 | header "CNIOWindows.h" 3 | export * 4 | } 5 | -------------------------------------------------------------------------------- /Sources/CNIOWindows/shim.c: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020 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 | #if defined(_WIN32) 16 | 17 | #include "CNIOWindows.h" 18 | 19 | #include 20 | 21 | int CNIOWindows_sendmmsg(SOCKET s, CNIOWindows_mmsghdr *msgvec, unsigned int vlen, 22 | int flags) { 23 | assert(!"sendmmsg not implemented"); 24 | abort(); 25 | } 26 | 27 | int CNIOWindows_recvmmsg(SOCKET s, CNIOWindows_mmsghdr *msgvec, 28 | unsigned int vlen, int flags, 29 | struct timespec *timeout) { 30 | assert(!"recvmmsg not implemented"); 31 | abort(); 32 | } 33 | 34 | const void *CNIOWindows_CMSG_DATA(const WSACMSGHDR *pcmsg) { 35 | return WSA_CMSG_DATA(pcmsg); 36 | } 37 | 38 | void *CNIOWindows_CMSG_DATA_MUTABLE(LPWSACMSGHDR pcmsg) { 39 | return WSA_CMSG_DATA(pcmsg); 40 | } 41 | 42 | WSACMSGHDR *CNIOWindows_CMSG_FIRSTHDR(const WSAMSG *msg) { 43 | return WSA_CMSG_FIRSTHDR(msg); 44 | } 45 | 46 | WSACMSGHDR *CNIOWindows_CMSG_NXTHDR(const WSAMSG *msg, LPWSACMSGHDR cmsg) { 47 | return WSA_CMSG_NXTHDR(msg, cmsg); 48 | } 49 | 50 | size_t CNIOWindows_CMSG_LEN(size_t length) { 51 | return WSA_CMSG_LEN(length); 52 | } 53 | 54 | size_t CNIOWindows_CMSG_SPACE(size_t length) { 55 | return WSA_CMSG_SPACE(length); 56 | } 57 | 58 | #endif 59 | -------------------------------------------------------------------------------- /Sources/NIO/Exports.swift: -------------------------------------------------------------------------------- 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 | @_exported import NIOCore 15 | @_exported import NIOEmbedded 16 | @_exported import NIOPosix 17 | -------------------------------------------------------------------------------- /Sources/NIOAsyncAwaitDemo/AsyncChannelIO.swift: -------------------------------------------------------------------------------- 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 NIOCore 16 | import NIOHTTP1 17 | 18 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 19 | struct AsyncChannelIO { 20 | let channel: Channel 21 | 22 | init(_ channel: Channel) { 23 | self.channel = channel 24 | } 25 | 26 | func start() async throws -> AsyncChannelIO { 27 | try await channel.eventLoop.submit { 28 | try channel.pipeline.syncOperations.addHandler( 29 | RequestResponseHandler() 30 | ) 31 | }.get() 32 | return self 33 | } 34 | 35 | func sendRequest(_ request: Request) async throws -> Response { 36 | let responsePromise: EventLoopPromise = channel.eventLoop.makePromise() 37 | try await self.channel.writeAndFlush((request, responsePromise)).get() 38 | return try await responsePromise.futureResult.get() 39 | } 40 | 41 | func close() async throws { 42 | try await self.channel.close() 43 | } 44 | } 45 | -------------------------------------------------------------------------------- /Sources/NIOChatClient/README.md: -------------------------------------------------------------------------------- 1 | # NIOChatClient 2 | 3 | This sample application provides a client for the `NIOChatServer`. Invoke 4 | it using one of the following syntaxes: 5 | 6 | ```bash 7 | swift run NIOChatClient # Connects to a server on ::1, port 9999. 8 | swift run NIOChatClient 9899 # Connects to a server on ::1, port 9899 9 | swift run NIOChatClient /path/to/unix/socket # Connects to a server using the given UNIX socket 10 | swift run NIOChatClient chat.example.com 9899 # Connects to a server on chat.example.com:9899 11 | ``` 12 | 13 | -------------------------------------------------------------------------------- /Sources/NIOChatServer/README.md: -------------------------------------------------------------------------------- 1 | # NIOChatServer 2 | 3 | This sample application provides a chat server that allows multile users to speak to one another. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOChatServer # Binds the server on ::1, port 9999. 7 | swift run NIOChatServer 9899 # Binds the server on ::1, port 9899 8 | swift run NIOChatServer /path/to/unix/socket # Binds the server using the given UNIX socket 9 | swift run NIOChatServer 192.168.0.5 9899 # Binds the server on 192.168.0.5:9899 10 | ``` 11 | 12 | -------------------------------------------------------------------------------- /Sources/NIOCore/DispatchQueue+WithFuture.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020 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 | #if canImport(Dispatch) 16 | import Dispatch 17 | 18 | extension DispatchQueue { 19 | /// Schedules a work item for immediate execution and immediately returns with an `EventLoopFuture` providing the 20 | /// result. For example: 21 | /// 22 | /// let futureResult = DispatchQueue.main.asyncWithFuture(eventLoop: myEventLoop) { () -> String in 23 | /// callbackMayBlock() 24 | /// } 25 | /// try let value = futureResult.wait() 26 | /// 27 | /// - Parameters: 28 | /// - eventLoop: the `EventLoop` on which to processes the IO / task specified by `callbackMayBlock`. 29 | /// - callbackMayBlock: The scheduled callback for the IO / task. 30 | /// - returns a new `EventLoopFuture` with value returned by the `block` parameter. 31 | @inlinable 32 | @preconcurrency 33 | public func asyncWithFuture( 34 | eventLoop: EventLoop, 35 | _ callbackMayBlock: @escaping @Sendable () throws -> NewValue 36 | ) -> EventLoopFuture { 37 | let promise = eventLoop.makePromise(of: NewValue.self) 38 | 39 | self.async { 40 | do { 41 | let result = try callbackMayBlock() 42 | promise.succeed(result) 43 | } catch { 44 | promise.fail(error) 45 | } 46 | } 47 | return promise.futureResult 48 | } 49 | } 50 | #endif 51 | -------------------------------------------------------------------------------- /Sources/NIOCore/EventLoop+Deprecated.swift: -------------------------------------------------------------------------------- 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 | extension EventLoop { 16 | @inlinable 17 | @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") 18 | public func makeFailedFuture( 19 | _ error: Error, 20 | file: StaticString = #fileID, 21 | line: UInt = #line 22 | ) -> EventLoopFuture { 23 | self.makeFailedFuture(error) 24 | } 25 | 26 | @preconcurrency 27 | @inlinable 28 | @available(*, deprecated, message: "Please don't pass file:line:, there's no point.") 29 | public func makeSucceededFuture( 30 | _ value: Success, 31 | file: StaticString = #fileID, 32 | line: UInt = #line 33 | ) -> EventLoopFuture { 34 | self.makeSucceededFuture(value) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /Sources/NIOCore/FileDescriptor.swift: -------------------------------------------------------------------------------- 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 | public protocol FileDescriptor { 16 | 17 | /// Will be called with the file descriptor if still open, if not it will 18 | /// throw an `IOError`. 19 | /// 20 | /// The ownership of the file descriptor must not escape the `body` as it's completely managed by the 21 | /// implementation of the `FileDescriptor` protocol. 22 | /// 23 | /// - Parameters: 24 | /// - body: The closure to execute if the `FileDescriptor` is still open. 25 | /// - Throws: If either the `FileDescriptor` was closed before or the closure throws by itself. 26 | func withUnsafeFileDescriptor(_ body: (CInt) throws -> T) throws -> T 27 | 28 | /// `true` if this `FileDescriptor` is open (which means it was not closed yet). 29 | var isOpen: Bool { get } 30 | 31 | /// Close this `FileDescriptor`. 32 | func close() throws 33 | } 34 | -------------------------------------------------------------------------------- /Sources/NIOCore/NIOCloseOnErrorHandler.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-2019 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 | /// A `ChannelInboundHandler` that closes the channel when an error is caught 16 | public final class NIOCloseOnErrorHandler: ChannelInboundHandler, Sendable { 17 | 18 | public typealias InboundIn = NIOAny 19 | 20 | /// Initialize a `NIOCloseOnErrorHandler` 21 | public init() {} 22 | 23 | public func errorCaught(context: ChannelHandlerContext, error: Error) { 24 | context.fireErrorCaught(error) 25 | context.close(promise: nil) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Sources/NIOCrashTester/CrashTestSuites.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020 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 | #if !canImport(Darwin) || os(macOS) 16 | func makeCrashTestSuites() -> [String: Any] { 17 | [ 18 | "EventLoopCrashTests": EventLoopCrashTests(), 19 | "ByteBufferCrashTests": ByteBufferCrashTests(), 20 | "SystemCrashTests": SystemCrashTests(), 21 | "HTTPCrashTests": HTTPCrashTests(), 22 | "StrictCrashTests": StrictCrashTests(), 23 | "LoopBoundTests": LoopBoundTests(), 24 | ] 25 | } 26 | #endif 27 | -------------------------------------------------------------------------------- /Sources/NIOCrashTester/CrashTests+ByteBuffer.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020-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 NIOCore 16 | 17 | struct ByteBufferCrashTests { 18 | #if !canImport(Darwin) || os(macOS) 19 | let testMovingReaderIndexPastWriterIndex = CrashTest( 20 | regex: #"Precondition failed: new readerIndex: 1, expected: range\(0, 0\)"# 21 | ) { 22 | var buffer = ByteBufferAllocator().buffer(capacity: 16) 23 | buffer.moveReaderIndex(forwardBy: 1) 24 | } 25 | 26 | let testAllocatingNegativeSize = CrashTest( 27 | regex: #"Precondition failed: ByteBuffer capacity must be positive."# 28 | ) { 29 | _ = ByteBufferAllocator().buffer(capacity: -1) 30 | } 31 | #endif 32 | } 33 | -------------------------------------------------------------------------------- /Sources/NIOCrashTester/CrashTests+Strict.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2022 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 | #if !canImport(Darwin) || os(macOS) 16 | import NIOCore 17 | import NIOPosix 18 | 19 | struct StrictCrashTests { 20 | let testEventLoopSheduleAfterShutdown = CrashTest( 21 | regex: "Fatal error: Cannot schedule tasks on an EventLoop that has already shut down." 22 | ) { 23 | setenv("SWIFTNIO_STRICT", "1", 1) 24 | let elg = MultiThreadedEventLoopGroup(numberOfThreads: 1) 25 | let loop = elg.next() 26 | try! elg.syncShutdownGracefully() 27 | loop.execute { 28 | print("Crash should happen before this line is printed.") 29 | } 30 | } 31 | } 32 | #endif 33 | -------------------------------------------------------------------------------- /Sources/NIOCrashTester/CrashTests+System.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020-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 | #if !canImport(Darwin) || os(macOS) 16 | import NIOCore 17 | import NIOPosix 18 | import Foundation 19 | 20 | private let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 21 | 22 | struct SystemCrashTests { 23 | let testEBADFIsUnacceptable = CrashTest( 24 | regex: "Precondition failed: unacceptable errno \(EBADF) Bad file descriptor in", 25 | { 26 | _ = try? NIOPipeBootstrap(group: group).takingOwnershipOfDescriptors(input: .max, output: .max - 1).wait() 27 | } 28 | ) 29 | } 30 | #endif 31 | -------------------------------------------------------------------------------- /Sources/NIOEchoClient/README.md: -------------------------------------------------------------------------------- 1 | # NIOEchoClient 2 | 3 | This sample application provides a simple echo client that will send a single line to an echo server and wait for a response. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOEchoClient # Connects to a server on ::1, port 9999. 7 | swift run NIOEchoClient 9899 # Connects to a server on ::1, port 9899 8 | swift run NIOEchoClient /path/to/unix/socket # Connects to a server using the given UNIX socket 9 | swift run NIOEchoClient echo.example.com 9899 # Connects to a server on echo.example.com:9899 10 | ``` 11 | 12 | -------------------------------------------------------------------------------- /Sources/NIOEchoServer/README.md: -------------------------------------------------------------------------------- 1 | # NIOEchoServer 2 | 3 | This sample application provides a simple echo server that sends clients back whatever data they send it. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOEchoServer # Binds the server on ::1, port 9999. 7 | swift run NIOEchoServer 9899 # Binds the server on ::1, port 9899 8 | swift run NIOEchoServer /path/to/unix/socket # Binds the server using the given UNIX socket 9 | swift run NIOEchoServer 192.168.0.5 9899 # Binds the server on 192.168.0.5:9899 10 | ``` 11 | 12 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/DirectoryEntry.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 SystemPackage 16 | 17 | /// Information about an item within a directory. 18 | public struct DirectoryEntry: Sendable, Hashable, Equatable { 19 | /// The path of the directory entry. 20 | /// 21 | /// - Precondition: The path must have at least one component. 22 | public let path: FilePath 23 | 24 | /// The name of the entry; the final component of the ``path``. 25 | /// 26 | /// If `path` is "/Users/tim/path-to-4T.key" then `name` will be "path-to-4T.key". 27 | public var name: FilePath.Component { 28 | self.path.lastComponent! 29 | } 30 | 31 | /// The type of entry. 32 | public var type: FileType 33 | 34 | /// Creates a directory entry; returns `nil` if `path` has no components. 35 | /// 36 | /// - Parameters: 37 | /// - path: The path of the directory entry which must contain at least one component. 38 | /// - type: The type of entry. 39 | public init?(path: FilePath, type: FileType) { 40 | if path.components.isEmpty { 41 | return nil 42 | } 43 | 44 | self.path = path 45 | self.type = type 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Docs.docc/Extensions/DirectoryFileHandleProtocol.md: -------------------------------------------------------------------------------- 1 | # ``_NIOFileSystem/DirectoryFileHandleProtocol`` 2 | 3 | ## Topics 4 | 5 | ### Iterating a directory 6 | 7 | - ``listContents()`` 8 | 9 | ### Opening files with managed lifecycles 10 | 11 | Open files and directories at paths relative to the directory handle. These methods manage 12 | the lifecycle of the handles by closing them when the `execute` closure returns. 13 | 14 | - ``withFileHandle(forReadingAt:options:execute:)`` 15 | - ``withFileHandle(forWritingAt:options:execute:)`` 16 | - ``withFileHandle(forReadingAndWritingAt:options:execute:)`` 17 | - ``withDirectoryHandle(atPath:options:execute:)`` 18 | 19 | ### Opening files 20 | 21 | Open files and directories at paths relative to the directory handle. These methods return 22 | the handle to the caller who is responsible for closing it. 23 | 24 | - ``openFile(forReadingAt:options:)`` 25 | - ``openFile(forWritingAt:options:)`` 26 | - ``openFile(forReadingAndWritingAt:options:)`` 27 | - ``openDirectory(atPath:options:)`` 28 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Docs.docc/Extensions/FileHandleProtocol.md: -------------------------------------------------------------------------------- 1 | # ``_NIOFileSystem/FileHandleProtocol`` 2 | 3 | ## Topics 4 | 5 | ### File Information 6 | 7 | - ``info()`` 8 | 9 | ### Permissions 10 | 11 | - ``replacePermissions(_:)`` 12 | - ``addPermissions(_:)`` 13 | - ``removePermissions(_:)`` 14 | 15 | ### Extended Attributes 16 | 17 | - ``attributeNames()`` 18 | - ``valueForAttribute(_:)`` 19 | - ``updateValueForAttribute(_:attribute:)`` 20 | - ``removeValueForAttribute(_:)`` 21 | 22 | ### Descriptor Management 23 | 24 | - ``synchronize()`` 25 | - ``withUnsafeDescriptor(_:)`` 26 | - ``detachUnsafeFileDescriptor()`` 27 | - ``close()`` 28 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Docs.docc/Extensions/FileSystemProtocol.md: -------------------------------------------------------------------------------- 1 | # ``_NIOFileSystem/FileSystemProtocol`` 2 | 3 | ## Topics 4 | 5 | ### Opening files with managed lifecycles 6 | 7 | Files and directories can be opened and have their lifecycles managed by using the 8 | following methods: 9 | 10 | - ``withFileHandle(forReadingAt:options:execute:)`` 11 | - ``withFileHandle(forWritingAt:options:execute:)`` 12 | - ``withFileHandle(forReadingAndWritingAt:options:execute:)`` 13 | - ``withDirectoryHandle(atPath:options:execute:)`` 14 | 15 | ### Opening files 16 | 17 | Files and directories can be opened using the following methods. The caller is responsible for 18 | closing it to avoid leaking resources. 19 | 20 | - ``openFile(forReadingAt:)`` 21 | - ``openFile(forWritingAt:options:)`` 22 | - ``openFile(forReadingAndWritingAt:options:)`` 23 | - ``openDirectory(atPath:options:)`` 24 | 25 | ### File information 26 | 27 | - ``info(forFileAt:infoAboutSymbolicLink:)`` 28 | 29 | ### Symbolic links 30 | 31 | - ``createSymbolicLink(at:withDestination:)`` 32 | - ``destinationOfSymbolicLink(at:)`` 33 | 34 | ### Managing files 35 | 36 | - ``copyItem(at:to:shouldProceedAfterError:shouldCopyFile:)`` 37 | - ``removeItem(at:)`` 38 | - ``moveItem(at:to:)`` 39 | - ``replaceItem(at:withItemAt:)`` 40 | - ``createDirectory(at:withIntermediateDirectories:permissions:)`` 41 | 42 | ### System directories 43 | 44 | - ``currentWorkingDirectory`` 45 | - ``temporaryDirectory`` 46 | - ``withTemporaryDirectory(prefix:options:execute:)`` 47 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Docs.docc/Extensions/ReadableFileHandleProtocol.md: -------------------------------------------------------------------------------- 1 | # ``_NIOFileSystem/ReadableFileHandleProtocol`` 2 | 3 | ## Topics 4 | 5 | ### Read the contents of a file 6 | 7 | - ``bufferedReader(startingAtAbsoluteOffset:capacity:)`` 8 | - ``readChunks(chunkLength:)`` 9 | - ``readChunks(in:chunkLength:)-2j7r7`` 10 | - ``readChunks(in:chunkLength:)-63rn`` 11 | - ``readChunks(in:chunkLength:)-3fxd`` 12 | - ``readChunks(in:chunkLength:)-9oae1`` 13 | - ``readChunks(in:chunkLength:)-7rjf6`` 14 | - ``readChunks(in:chunkLength:)-7a8x2`` 15 | - ``readToEnd(fromAbsoluteOffset:maximumSizeAllowed:)`` 16 | 17 | ### Read part of a file 18 | 19 | - ``readChunk(fromAbsoluteOffset:length:)`` 20 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Docs.docc/Extensions/WritableFileHandleProtocol.md: -------------------------------------------------------------------------------- 1 | # ``_NIOFileSystem/WritableFileHandleProtocol`` 2 | 3 | ## Topics 4 | 5 | ### Write bytes to a file 6 | 7 | - ``write(contentsOf:toAbsoluteOffset:)-57fnc`` 8 | - ``write(contentsOf:toAbsoluteOffset:)-4na03`` 9 | - ``bufferedWriter(startingAtAbsoluteOffset:capacity:)`` 10 | 11 | ### Resize a file 12 | - ``resize(to:)`` 13 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Exports.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 | // These types are used in our public API; expose them to make 16 | // life easier for users. 17 | @_exported import enum SystemPackage.CInterop 18 | @_exported import struct SystemPackage.Errno 19 | @_exported import struct SystemPackage.FileDescriptor 20 | @_exported import struct SystemPackage.FilePath 21 | @_exported import struct SystemPackage.FilePermissions 22 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Internal/Cancellation.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 | /// Executes the closure and masks cancellation. 16 | @_spi(Testing) 17 | @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) 18 | public func withoutCancellation( 19 | _ execute: @escaping () async throws -> R 20 | ) async throws -> R { 21 | // Okay as we immediately wait for the result of the task. 22 | let unsafeExecute = UnsafeTransfer(execute) 23 | let t = Task { 24 | try await unsafeExecute.wrappedValue() 25 | } 26 | return try await t.value 27 | } 28 | 29 | /// Executes `fn` and then `tearDown`, which cannot be cancelled. 30 | @_spi(Testing) 31 | @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) 32 | public func withUncancellableTearDown( 33 | _ fn: () async throws -> R, 34 | tearDown: @escaping (Result) async throws -> Void 35 | ) async throws -> R { 36 | let result: Result 37 | do { 38 | result = .success(try await fn()) 39 | } catch { 40 | result = .failure(error) 41 | } 42 | 43 | let errorOnlyResult: Result = result.map { _ in () } 44 | let tearDownResult: Result = try await withoutCancellation { 45 | do { 46 | return .success(try await tearDown(errorOnlyResult)) 47 | } catch { 48 | return .failure(error) 49 | } 50 | } 51 | 52 | try tearDownResult.get() 53 | return try result.get() 54 | } 55 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Internal/Concurrency Primitives/UnsafeTransfer.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 | @usableFromInline 16 | struct UnsafeTransfer: @unchecked Sendable { 17 | @usableFromInline 18 | var wrappedValue: Value 19 | 20 | @inlinable 21 | init(_ wrappedValue: Value) { 22 | self.wrappedValue = wrappedValue 23 | } 24 | } 25 | -------------------------------------------------------------------------------- /Sources/NIOFileSystem/Internal/Utilities.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 SystemPackage 16 | 17 | @usableFromInline 18 | internal final class Ref { 19 | @usableFromInline 20 | var value: Value 21 | @inlinable 22 | init(_ value: Value) { 23 | self.value = value 24 | } 25 | } 26 | 27 | extension String { 28 | init(randomAlphaNumericOfLength length: Int) { 29 | precondition(length > 0) 30 | 31 | let characters = (0.. 2 | 3 | 4 | 5 | NSPrivacyTracking 6 | 7 | NSPrivacyAccessedAPITypes 8 | 9 | 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | 0A2A.1 13 | 14 | NSPrivacyAccessedAPIType 15 | NSPrivacyAccessedAPICategoryFileTimestamp 16 | 17 | 18 | NSPrivacyCollectedDataTypes 19 | 20 | NSPrivacyTrackingDomains 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sources/NIOFileSystemFoundationCompat/Date+FileInfo.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 _NIOFileSystem 16 | 17 | import struct Foundation.Date 18 | 19 | extension Date { 20 | public init(timespec: FileInfo.Timespec) { 21 | let timeInterval = Double(timespec.seconds) + Double(timespec.nanoseconds) / 1_000_000_000 22 | self = Date(timeIntervalSince1970: timeInterval) 23 | } 24 | } 25 | 26 | extension FileInfo.Timespec { 27 | /// The UTC time of the timestamp. 28 | public var date: Date { 29 | Date(timespec: self) 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Sources/NIOFoundationCompat/JSONSerialization+ByteBuffer.swift: -------------------------------------------------------------------------------- 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 Foundation 16 | import NIOCore 17 | 18 | extension JSONSerialization { 19 | 20 | /// Attempts to derive a Foundation object from a ByteBuffer and return it as `T`. 21 | /// 22 | /// - Parameters: 23 | /// - buffer: The ByteBuffer being used to derive the Foundation type. 24 | /// - options: The reading option used when the parser derives the Foundation type from the ByteBuffer. 25 | /// - Returns: The Foundation value if successful or `nil` if there was an issue creating the Foundation type. 26 | @inlinable 27 | public static func jsonObject( 28 | with buffer: ByteBuffer, 29 | options: JSONSerialization.ReadingOptions = [] 30 | ) throws -> Any { 31 | try JSONSerialization.jsonObject(with: Data(buffer: buffer), options: options) 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /Sources/NIOHTTP1Client/README.md: -------------------------------------------------------------------------------- 1 | # NIOHTTP1Client 2 | 3 | This sample application provides a simple echo client that will send a basic HTTP request, containing a single line of text, to the server and wait for a response. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOHTTP1Client # Connects to a server on ::1, port 8888. 7 | swift run NIOHTTP1Client 9899 # Connects to a server on ::1, port 9899 8 | swift run NIOHTTP1Client /path/to/unix/socket # Connects to a server using the given UNIX socket 9 | swift run NIOHTTP1Client echo.example.com 9899 # Connects to a server on echo.example.com:9899 10 | ``` 11 | 12 | -------------------------------------------------------------------------------- /Sources/NIOHTTP1Server/README.md: -------------------------------------------------------------------------------- 1 | # NIOHTTP1Server 2 | 3 | This sample application provides a HTTP server that supports a number of query methods for testing purposes. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOHTTP1Server # Binds the server on ::1, port 8888. 7 | swift run NIOHTTP1Server 8988 # Binds the server on ::1, port 8988 8 | swift run NIOHTTP1Server /path/to/unix/socket # Binds the server using the given UNIX socket 9 | swift run NIOHTTP1Server 192.168.0.5 8988 # Binds the server on 192.168.0.5:8988 10 | ``` 11 | 12 | The final three syntaxes optionally accept an additional argument, a path to a directory of files to serve from the webserver. The first syntax does not, as that would conflict with the UNIX socket path syntax. 13 | 14 | So, for example, to spin up a local webserver on port 80 serving a specific directory, you can run: 15 | 16 | ```bash 17 | swift run NIOHTTP1Server localhost 80 /var/www 18 | ``` 19 | 20 | ## Paths 21 | 22 | The server has the following endpoints: 23 | 24 | - `/`: serves "Hello world!" 25 | - `/sendfile/*`: serves the file at path `*` to the client, using `sendfile`. 26 | - `/fileio/*`: serves the file at path `*` to the client by reading the file in to memory in chunks. 27 | - `/dynamic/echo`: Echoes the request body back to the client. 28 | - `/dynamic/echo_balloon`: Echoes the request body back to the client after buffering it entirely in memory first. 29 | - `/dynamic/pid`: Echoes pack the PID of the server. 30 | - `/dynamic/write-delay`: Echoes "Hello world" after a 100ms delay. 31 | - `/dynamic/info`: Sends information about the received request. 32 | - `/dynamic/trailers`: Sends the PID along with some HTTP trailers. 33 | - `/dynamic/continuous`: Sends a chunked body forever. 34 | - `/dynamic/count-to-ten`: Sends the numbers 1 through 10 in separate chunks. 35 | - `/dynamic/client-ip`: Sends what the server believes the client IP is. 36 | 37 | -------------------------------------------------------------------------------- /Sources/NIOPerformanceTester/Benchmark.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019 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 Dispatch 16 | 17 | protocol Benchmark: AnyObject { 18 | func setUp() throws 19 | func tearDown() 20 | func run() throws -> Int 21 | } 22 | 23 | func measureAndPrint(desc: String, benchmark bench: B) throws { 24 | try bench.setUp() 25 | defer { 26 | bench.tearDown() 27 | } 28 | try measureAndPrint(desc: desc) { 29 | try bench.run() 30 | } 31 | } 32 | 33 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 34 | protocol AsyncBenchmark: AnyObject, Sendable { 35 | func setUp() async throws 36 | func tearDown() 37 | func run() async throws -> Int 38 | } 39 | 40 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 41 | func measureAndPrint(desc: String, benchmark bench: B) throws { 42 | let group = DispatchGroup() 43 | group.enter() 44 | Task { 45 | do { 46 | try await bench.setUp() 47 | defer { 48 | bench.tearDown() 49 | } 50 | try await measureAndPrint(desc: desc) { 51 | try await bench.run() 52 | } 53 | } 54 | group.leave() 55 | } 56 | 57 | group.wait() 58 | } 59 | -------------------------------------------------------------------------------- /Sources/NIOPerformanceTester/ByteBufferViewContainsBenchmark.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2020-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 Foundation 16 | import NIOCore 17 | 18 | final class ByteBufferViewContainsBenchmark: Benchmark { 19 | private let iterations: Int 20 | private let bufferSize: Int 21 | private var buffer: ByteBuffer 22 | 23 | init(iterations: Int, bufferSize: Int) { 24 | self.iterations = iterations 25 | self.bufferSize = bufferSize 26 | self.buffer = ByteBufferAllocator().buffer(capacity: self.bufferSize) 27 | } 28 | 29 | func setUp() throws { 30 | self.buffer.writeBytes(Array(repeating: UInt8(ascii: "A"), count: self.bufferSize - 1)) 31 | self.buffer.writeInteger(UInt8(ascii: "B")) 32 | } 33 | 34 | func tearDown() { 35 | } 36 | 37 | func run() -> Int { 38 | var which: UInt8 = 0 39 | for _ in 1...self.iterations { 40 | if self.buffer.readableBytesView.contains(UInt8(ascii: "B")) { 41 | which = UInt8(ascii: "B") 42 | } 43 | } 44 | return Int(which) 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Sources/NIOPerformanceTester/ByteBufferViewCopyToArrayBenchmark.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2022 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 NIOCore 16 | 17 | final class ByteBufferViewCopyToArrayBenchmark: Benchmark { 18 | private let iterations: Int 19 | private let size: Int 20 | private var view: ByteBufferView 21 | 22 | init(iterations: Int, size: Int) { 23 | self.iterations = iterations 24 | self.size = size 25 | self.view = ByteBufferView() 26 | } 27 | 28 | func setUp() throws { 29 | self.view = ByteBuffer(repeating: 0xfe, count: self.size).readableBytesView 30 | } 31 | 32 | func tearDown() { 33 | } 34 | 35 | func run() -> Int { 36 | var count = 0 37 | for _ in 0.. Int { 38 | var which: UInt8 = 0 39 | for _ in 1...self.iterations { 40 | for byte in self.buffer.readableBytesView { 41 | if byte != UInt8(ascii: "A") { 42 | which = byte 43 | } 44 | } 45 | } 46 | return Int(which) 47 | } 48 | 49 | } 50 | -------------------------------------------------------------------------------- /Sources/NIOPerformanceTester/ByteToMessageDecoderDecodeManySmallsBenchmark.swift: -------------------------------------------------------------------------------- 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 | import NIOCore 15 | import NIOEmbedded 16 | 17 | final class ByteToMessageDecoderDecodeManySmallsBenchmark: Benchmark { 18 | private let iterations: Int 19 | private let buffer: ByteBuffer 20 | private let channel: EmbeddedChannel 21 | 22 | init(iterations: Int, bufferSize: Int) { 23 | self.iterations = iterations 24 | self.buffer = ByteBuffer(repeating: 0, count: bufferSize) 25 | self.channel = EmbeddedChannel(handler: ByteToMessageHandler(Decoder())) 26 | } 27 | 28 | func setUp() throws { 29 | try self.channel.connect(to: .init(ipAddress: "1.2.3.4", port: 5)).wait() 30 | } 31 | 32 | func tearDown() { 33 | precondition(try! self.channel.finish().isClean) 34 | } 35 | 36 | func run() -> Int { 37 | for _ in 1...self.iterations { 38 | try! self.channel.writeInbound(self.buffer) 39 | } 40 | return Int(self.buffer.readableBytes) 41 | } 42 | 43 | struct Decoder: ByteToMessageDecoder { 44 | typealias InboundOut = Never 45 | 46 | func decode(context: ChannelHandlerContext, buffer: inout ByteBuffer) throws -> DecodingState { 47 | if buffer.readSlice(length: 16) == nil { 48 | return .needMoreData 49 | } else { 50 | return .continue 51 | } 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Sources/NIOPerformanceTester/CircularBufferCopyToArrayBenchmark.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2022 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 NIOCore 16 | 17 | final class CircularBufferViewCopyToArrayBenchmark: Benchmark { 18 | private let iterations: Int 19 | private let size: Int 20 | private var buffer: CircularBuffer 21 | 22 | init(iterations: Int, size: Int) { 23 | self.iterations = iterations 24 | self.size = size 25 | self.buffer = CircularBuffer() 26 | } 27 | 28 | func setUp() throws { 29 | self.buffer = CircularBuffer(repeating: UInt8(0xfe), count: self.size) 30 | } 31 | 32 | func tearDown() { 33 | } 34 | 35 | func run() -> Int { 36 | var count = 0 37 | for _ in 0.. 22 | private var buffer: ByteBuffer 23 | 24 | init(iterations: Int, bufferSize: Int) { 25 | self.iterations = iterations 26 | self.bufferSize = bufferSize 27 | self.circularBuffer = CircularBuffer(initialCapacity: self.bufferSize) 28 | self.buffer = ByteBufferAllocator().buffer(capacity: self.bufferSize) 29 | } 30 | 31 | func setUp() throws { 32 | for i in 0.. Int { 41 | for _ in 1...self.iterations { 42 | self.buffer.writeBytes(self.circularBuffer) 43 | self.buffer.setBytes(self.circularBuffer, at: 0) 44 | self.buffer.clear() 45 | } 46 | return 1 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /Sources/NIOPerformanceTester/DeadlineNowBenchmark.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2022 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 NIOCore 16 | 17 | final class DeadlineNowBenchmark: Benchmark { 18 | private let iterations: Int 19 | 20 | init(iterations: Int) { 21 | self.iterations = iterations 22 | } 23 | 24 | func setUp() throws { 25 | } 26 | 27 | func tearDown() { 28 | } 29 | 30 | func run() -> Int { 31 | var counter: UInt64 = 0 32 | for _ in 0..: Equatable { 29 | 30 | /// Signals that the IO operation could not be completed as otherwise we would need to block. 31 | case wouldBlock(T) 32 | 33 | /// Signals that the IO operation was completed. 34 | case processed(T) 35 | } 36 | -------------------------------------------------------------------------------- /Sources/NIOPosix/PrivacyInfo.xcprivacy: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | NSPrivacyTracking 6 | 7 | NSPrivacyAccessedAPITypes 8 | 9 | 10 | NSPrivacyAccessedAPITypeReasons 11 | 12 | 0A2A.1 13 | 14 | NSPrivacyAccessedAPIType 15 | NSPrivacyAccessedAPICategoryFileTimestamp 16 | 17 | 18 | NSPrivacyCollectedDataTypes 19 | 20 | NSPrivacyTrackingDomains 21 | 22 | 23 | 24 | -------------------------------------------------------------------------------- /Sources/NIOPosix/Selectable.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-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 NIOCore 16 | 17 | /// Represents a selectable resource which can be registered to a `Selector` to 18 | /// be notified once there are some events ready for it. 19 | /// 20 | /// - warning: 21 | /// `Selectable`s are not thread-safe, only to be used on the appropriate 22 | /// `EventLoop`. 23 | protocol Selectable { 24 | func withUnsafeHandle(_: (NIOBSDSocket.Handle) throws -> T) throws -> T 25 | } 26 | -------------------------------------------------------------------------------- /Sources/NIOPosix/UnsafeTransfer.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2021-2022 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 | /// ``UnsafeTransfer`` can be used to make non-`Sendable` values `Sendable`. 16 | /// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler. 17 | /// It can be used similar to `@unsafe Sendable` but for values instead of types. 18 | @usableFromInline 19 | struct UnsafeTransfer { 20 | @usableFromInline 21 | var wrappedValue: Wrapped 22 | 23 | @inlinable 24 | init(_ wrappedValue: Wrapped) { 25 | self.wrappedValue = wrappedValue 26 | } 27 | } 28 | 29 | extension UnsafeTransfer: @unchecked Sendable {} 30 | 31 | extension UnsafeTransfer: Equatable where Wrapped: Equatable {} 32 | extension UnsafeTransfer: Hashable where Wrapped: Hashable {} 33 | -------------------------------------------------------------------------------- /Sources/NIOPosix/Utilities.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-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 | /// A utility function that runs the body code only in debug builds, without 16 | /// emitting compiler warnings. 17 | /// 18 | /// This is currently the only way to do this in Swift: see 19 | /// https://forums.swift.org/t/support-debug-only-code/11037 for a discussion. 20 | @inlinable 21 | internal func debugOnly(_ body: () -> Void) { 22 | assert( 23 | { 24 | body() 25 | return true 26 | }() 27 | ) 28 | } 29 | 30 | /// Allows to "box" another value. 31 | final class Box { 32 | let value: T 33 | init(_ value: T) { self.value = value } 34 | } 35 | -------------------------------------------------------------------------------- /Sources/NIOPosix/VsockChannelEvents.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 | import NIOCore 15 | 16 | public enum VsockChannelEvents { 17 | /// Fired as an outbound event when NIO would like to ask itself to bind the socket. 18 | /// 19 | /// This flow for connect is required because we cannot extend `enum SocketAddress` without 20 | /// breaking public API. 21 | public struct BindToAddress: Hashable, Sendable { 22 | public var address: VsockAddress 23 | 24 | public init(_ address: VsockAddress) { 25 | self.address = address 26 | } 27 | } 28 | 29 | /// Fired as an outbound event when NIO would like to ask itself to connect the socket. 30 | /// 31 | /// This flow for connect is required because we cannot extend `enum SocketAddress` without 32 | /// breaking public API. 33 | public struct ConnectToAddress: Hashable, Sendable { 34 | public var address: VsockAddress 35 | 36 | public init(_ address: VsockAddress) { 37 | self.address = address 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Sources/NIOTCPEchoClient/README.md: -------------------------------------------------------------------------------- 1 | # NIOTCPEchoClient 2 | 3 | This sample application provides a simple TCP echo client that will send multiple messages to an 4 | echo server and wait for a response of all of them. Before running this client, make sure to start 5 | the `NIOTCPEchoServer`. 6 | 7 | To run this client execute the following from the root of the repository: 8 | 9 | ```bash 10 | swift run NIOTCPEchoClient 11 | ``` 12 | -------------------------------------------------------------------------------- /Sources/NIOTCPEchoServer/README.md: -------------------------------------------------------------------------------- 1 | # NIOTCPEchoServer 2 | 3 | This sample application provides a simple TCP server that sends clients back whatever they send it. 4 | 5 | To run this server execute the following from the root of the repository: 6 | 7 | ```bash 8 | swift run NIOTCPEchoServer 9 | ``` 10 | 11 | You can then use the `NIOTCPClient` to send requests to the server. 12 | -------------------------------------------------------------------------------- /Sources/NIOTLS/TLSEvents.swift: -------------------------------------------------------------------------------- 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 | import NIOCore 16 | 17 | /// Common user events sent by all TLS implementations. 18 | public enum TLSUserEvent: Equatable, Sendable { 19 | /// The TLS handshake has completed. If ALPN or NPN were used, 20 | /// the negotiated protocol is provided as `negotiatedProtocol`. 21 | case handshakeCompleted(negotiatedProtocol: String?) 22 | 23 | /// The TLS connection has been successfully and cleanly shut down. 24 | /// No further application data can be sent or received at this time. 25 | case shutdownCompleted 26 | } 27 | -------------------------------------------------------------------------------- /Sources/NIOUDPEchoClient/README.md: -------------------------------------------------------------------------------- 1 | # NIOUDPEchoClient 2 | 3 | This sample application provides a simple UDP echo client that will send a single line to a UDP echo server and wait for a response. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOUDPEchoClient # Connects to a server on ::1, server UDP port 9999 and listening port 8888. 7 | swift run NIOUDPEchoClient 9899 9888 # Connects to a server on ::1, server UDP port 9899 and listening port 9888 8 | swift run NIOUDPEchoClient echo.example.com 9899 9888 # Connects to a server on echo.example.com:9899 and listens on UDP port 9888 9 | ``` 10 | 11 | -------------------------------------------------------------------------------- /Sources/NIOUDPEchoServer/README.md: -------------------------------------------------------------------------------- 1 | # NIOUDPEchoServer 2 | 3 | This sample application provides a simple UDP echo server that sends clients back whatever data they send it. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOUDPEchoServer # Binds the server on ::1, port 9999. 7 | swift run NIOUDPEchoServer 9899 # Binds the server on ::1, port 9899 8 | swift run NIOUDPEchoServer /path/to/unix/socket # Binds the server using the given UNIX socket 9 | swift run NIOUDPEchoServer 192.168.0.5 9899 # Binds the server on 192.168.0.5:9899 10 | ``` 11 | 12 | -------------------------------------------------------------------------------- /Sources/NIOWebSocketClient/README.md: -------------------------------------------------------------------------------- 1 | # NIOWebSocketClient 2 | 3 | This sample application provides a simple WebSocket client. First it performs an upgrade from a HTTP connection. Once upgraded, it sends a 'ping' frame, with a body, to the server. It then checks that the body matches in the returning 'pong' frame. It also prints out any text frame received from the server. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOWebSocketClient # Connects to a server on ::1, port 8888. 7 | swift run NIOWebSocketClient 9899 # Connects to a server on ::1, port 9899 8 | swift run NIOWebSocketClient /path/to/unix/socket # Connects to a server using the given UNIX socket 9 | swift run NIOWebSocketClient echo.example.com 9899 # Connects to a server on echo.example.com:9899 10 | ``` 11 | 12 | -------------------------------------------------------------------------------- /Sources/NIOWebSocketServer/README.md: -------------------------------------------------------------------------------- 1 | # NIOWebSocketServer 2 | 3 | This sample application provides a simple WebSocket server which replies to a limited number of WebSocket message types. Initially, it sends clients back a test page response to a valid HTTP1 GET request. A 405 error will be reported for any other type of request. Once upgraded to WebSocket responses it will respond to a number of WebSocket message opcodes. Invoke it using one of the following syntaxes: 4 | 5 | ```bash 6 | swift run NIOWebSocketServer # Binds the server on 'localhost', port 8888. 7 | swift run NIOWebSocketServer 9899 # Binds the server on 'localhost', port 9899 8 | swift run NIOWebSocketServer /path/to/unix/socket # Binds the server using the given UNIX socket 9 | swift run NIOWebSocketServer 192.168.0.5 9899 # Binds the server on 192.168.0.5:9899 10 | ``` 11 | 12 | ## Message Type Opcodes 13 | 14 | The WebSocket server responds to the following message type opcodes: 15 | 16 | - `connectionClose`: closes the connection. 17 | - `ping`: replies with a 'pong' message containing frame data matching the received message. 18 | - `text`: prints the received string out on the server console. 19 | 20 | All other message types are ignored. 21 | -------------------------------------------------------------------------------- /Sources/_NIOConcurrency/Empty.swift: -------------------------------------------------------------------------------- 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 | // NOTE: All the helper methods that where located here, have been moved to NIOCore. This module 16 | // only exists to not break adopters code for now. Please remove all your dependencies on 17 | // `_NIOConcurrency`. We want to remove this module soon. 18 | 19 | import NIOCore 20 | -------------------------------------------------------------------------------- /Sources/_NIOFileSystemExported/Exports.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2024 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 | @_exported import _NIOFileSystem 16 | -------------------------------------------------------------------------------- /Tests/NIOCoreTests/AsyncChannel/AsyncChannelOutboundWriterTests.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 | 17 | @testable import NIOCore 18 | 19 | @available(macOS 10.15, iOS 13, tvOS 13, watchOS 6, *) 20 | final class AsyncChannelOutboundWriterTests: XCTestCase { 21 | func testTestingWriter() async throws { 22 | let (writer, sink) = NIOAsyncChannelOutboundWriter.makeTestingWriter() 23 | 24 | try await withThrowingTaskGroup(of: [Int].self) { group in 25 | group.addTask { 26 | var elements = [Int]() 27 | for try await element in sink { 28 | elements.append(element) 29 | } 30 | return elements 31 | } 32 | 33 | for element in 0...10 { 34 | try await writer.write(element) 35 | } 36 | writer.finish() 37 | 38 | let result = try await group.next() 39 | XCTAssertEqual(result, [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]) 40 | } 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/NIOCoreTests/IOErrorTest.swift: -------------------------------------------------------------------------------- 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 | // 16 | import XCTest 17 | 18 | @testable import NIOCore 19 | 20 | class IOErrorTest: XCTestCase { 21 | func testMemoryLayoutBelowThreshold() { 22 | XCTAssert(MemoryLayout.size <= 24) 23 | } 24 | 25 | @available(*, deprecated, message: "deprecated because it tests deprecated functionality") 26 | func testDeprecatedAPIStillFunctional() { 27 | XCTAssertNoThrow(IOError(errnoCode: 1, function: "anyFunc")) 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Tests/NIOCoreTests/TypeAssistedChannelHandlerTests.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2017-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 NIOCore 16 | import XCTest 17 | 18 | class TypeAssistedChannelHandlerTest: XCTestCase { 19 | func testCanDefineBothInboundAndOutbound() throws { 20 | class TestClass: ChannelDuplexHandler { 21 | public typealias OutboundIn = ByteBuffer 22 | public typealias OutboundOut = ByteBuffer 23 | public typealias InboundIn = ByteBuffer 24 | public typealias InboundOut = ByteBuffer 25 | } 26 | 27 | // This test really just confirms that compilation works: no need to run any code. 28 | XCTAssert(true) 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /Tests/NIOFileSystemIntegrationTests/FileSystemTests+SPI.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 SystemPackage 16 | import XCTest 17 | @_spi(Testing) import _NIOFileSystem 18 | 19 | @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) 20 | extension FileSystemTests { 21 | func testRemoveOneItemIgnoresNonExistentFile() async throws { 22 | let fs = FileSystem.shared 23 | let path = try await fs.temporaryFilePath() 24 | let removed = try await fs.removeOneItem(at: path) 25 | XCTAssertEqual(removed, 0) 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Tests/NIOFileSystemIntegrationTests/Test Data/Foo.symlink: -------------------------------------------------------------------------------- 1 | Foo -------------------------------------------------------------------------------- /Tests/NIOFileSystemIntegrationTests/Test Data/Foo/README.txt: -------------------------------------------------------------------------------- 1 | This file exists so that the containing directory is not empty. 2 | -------------------------------------------------------------------------------- /Tests/NIOFileSystemIntegrationTests/Test Data/README.md: -------------------------------------------------------------------------------- 1 | # Test Data 2 | 3 | This directory contains known files and directories for integration testing. This avoids having to 4 | rely on APIs for creating files and directories in order to test APIs which read files and 5 | directories. 6 | -------------------------------------------------------------------------------- /Tests/NIOFileSystemIntegrationTests/Test Data/README.md.symlink: -------------------------------------------------------------------------------- 1 | README.md -------------------------------------------------------------------------------- /Tests/NIOFileSystemTests/FileChunksTests.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2023 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 NIOCore 16 | import XCTest 17 | import _NIOFileSystem 18 | 19 | @available(macOS 10.15, iOS 13.0, watchOS 6.0, tvOS 13.0, *) 20 | final class FileChunksTests: XCTestCase { 21 | func testFileChunksWrapsAsyncStream() async throws { 22 | let stream = AsyncThrowingStream { 23 | $0.yield(ByteBuffer(bytes: [0, 1, 2])) 24 | $0.yield(ByteBuffer(bytes: [3, 4, 5])) 25 | $0.yield(ByteBuffer(bytes: [6, 7, 8])) 26 | $0.finish() 27 | } 28 | 29 | let fileChunks = FileChunks(wrapping: stream) 30 | var iterator = fileChunks.makeAsyncIterator() 31 | let chunk0 = try await iterator.next() 32 | XCTAssertEqual(chunk0, ByteBuffer(bytes: [0, 1, 2])) 33 | let chunk1 = try await iterator.next() 34 | XCTAssertEqual(chunk1, ByteBuffer(bytes: [3, 4, 5])) 35 | let chunk2 = try await iterator.next() 36 | XCTAssertEqual(chunk2, ByteBuffer(bytes: [6, 7, 8])) 37 | let end = try await iterator.next() 38 | XCTAssertNil(end) 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Tests/NIOFoundationCompatTests/ByteBufferView+MutableDataProtocolTest.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2019-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 Foundation 16 | import NIOCore 17 | import NIOFoundationCompat 18 | import XCTest 19 | 20 | class ByteBufferViewDataProtocolTests: XCTestCase { 21 | 22 | func testResetBytes() { 23 | var view = ByteBufferView() 24 | view.resetBytes(in: view.indices) 25 | XCTAssertTrue(view.elementsEqual([])) 26 | 27 | view.replaceSubrange(view.indices, with: [1, 2, 3, 4, 5]) 28 | 29 | view.resetBytes(in: 0..<2) 30 | XCTAssertTrue(view.elementsEqual([0, 0, 3, 4, 5])) 31 | 32 | view.resetBytes(in: 2...4) 33 | XCTAssertTrue(view.elementsEqual([0, 0, 0, 0, 0])) 34 | } 35 | 36 | func testCreateDataFromBuffer() { 37 | let testString = "some sample bytes" 38 | let buffer = ByteBuffer(ByteBufferView(testString.utf8)) 39 | let data = Data(buffer: buffer) 40 | XCTAssertEqual(Array(data), Array(testString.utf8)) 41 | } 42 | } 43 | -------------------------------------------------------------------------------- /Tests/NIOHTTP1Tests/TestUtils.swift: -------------------------------------------------------------------------------- 1 | ../NIOPosixTests/TestUtils.swift -------------------------------------------------------------------------------- /Tests/NIOHTTP1Tests/UnsafeTransfer.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2021-2022 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 | /// ``UnsafeTransfer`` can be used to make non-`Sendable` values `Sendable`. 16 | /// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler. 17 | /// It can be used similar to `@unsafe Sendable` but for values instead of types. 18 | @usableFromInline 19 | struct UnsafeTransfer { 20 | @usableFromInline 21 | var wrappedValue: Wrapped 22 | 23 | @inlinable 24 | init(_ wrappedValue: Wrapped) { 25 | self.wrappedValue = wrappedValue 26 | } 27 | } 28 | 29 | extension UnsafeTransfer: @unchecked Sendable {} 30 | 31 | extension UnsafeTransfer: Equatable where Wrapped: Equatable {} 32 | extension UnsafeTransfer: Hashable where Wrapped: Hashable {} 33 | 34 | /// ``UnsafeMutableTransferBox`` can be used to make non-`Sendable` values `Sendable` and mutable. 35 | /// It can be used to capture local mutable values in a `@Sendable` closure and mutate them from within the closure. 36 | /// As the name implies, the usage of this is unsafe because it disables the sendable checking of the compiler and does not add any synchronisation. 37 | @usableFromInline 38 | final class UnsafeMutableTransferBox { 39 | @usableFromInline 40 | var wrappedValue: Wrapped 41 | 42 | @inlinable 43 | init(_ wrappedValue: Wrapped) { 44 | self.wrappedValue = wrappedValue 45 | } 46 | } 47 | 48 | extension UnsafeMutableTransferBox: @unchecked Sendable {} 49 | -------------------------------------------------------------------------------- /Tests/NIOPosixTests/CoWValue.swift: -------------------------------------------------------------------------------- 1 | //===----------------------------------------------------------------------===// 2 | // 3 | // This source file is part of the SwiftNIO open source project 4 | // 5 | // Copyright (c) 2024 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 | /// A Copy on Write (CoW) type that can be used in tests to assert in-place mutation 16 | struct CoWValue: @unchecked Sendable { 17 | private final class UniquenessIndicator {} 18 | 19 | /// This reference is "copied" if not uniquely referenced 20 | private var uniquenessIndicator = UniquenessIndicator() 21 | 22 | /// mutates `self` and returns a boolean whether it was mutated in place or not 23 | /// - Returns: true if mutation happened in-place, false if Copy on Write (CoW) was triggered 24 | mutating func mutateInPlace() -> Bool { 25 | guard isKnownUniquelyReferenced(&self.uniquenessIndicator) else { 26 | self.uniquenessIndicator = UniquenessIndicator() 27 | return false 28 | } 29 | return true 30 | } 31 | } 32 | -------------------------------------------------------------------------------- /Tests/NIOTests/NIOTests.swift: -------------------------------------------------------------------------------- 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 NIO 16 | import XCTest 17 | 18 | /// This test suite is focused just on confirming that the umbrella NIO module behaves as expected. 19 | final class NIOTests: XCTestCase { 20 | func testCanUseTheVariousNIOTypes() { 21 | let group = MultiThreadedEventLoopGroup(numberOfThreads: 1) 22 | defer { 23 | try! group.syncShutdownGracefully() 24 | } 25 | 26 | let channel = EmbeddedChannel() 27 | XCTAssertNoThrow(try channel.finish()) 28 | 29 | let buffer = ByteBuffer() 30 | XCTAssertEqual(buffer.readableBytes, 0) 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /Tests/NIOWebSocketTests/NIOWebSocketClientUpgraderTests.swift: -------------------------------------------------------------------------------- 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 NIOWebSocket 16 | import XCTest 17 | 18 | /// a mock random number generator which will return the given `numbers` in order 19 | private struct TestRandomNumberGenerator: RandomNumberGenerator { 20 | var numbers: [UInt64] 21 | var nextRandomNumberIndex: Int 22 | init(numbers: [UInt64], nextRandomNumberIndex: Int = 0) { 23 | self.numbers = numbers 24 | self.nextRandomNumberIndex = nextRandomNumberIndex 25 | } 26 | mutating func next() -> UInt64 { 27 | defer { nextRandomNumberIndex += 1 } 28 | return numbers[nextRandomNumberIndex % numbers.count] 29 | } 30 | } 31 | 32 | final class NIOWebSocketClientUpgraderTests: XCTestCase { 33 | func testRandomRequestKey() { 34 | var generator = TestRandomNumberGenerator(numbers: [10, 11]) 35 | let requestKey = NIOWebSocketClientUpgrader.randomRequestKey(using: &generator) 36 | XCTAssertEqual(requestKey, "AAAAAAAAAAoAAAAAAAAACw==") 37 | } 38 | func testRandomRequestKeyWithSystemRandomNumberGenerator() { 39 | XCTAssertEqual( 40 | NIOWebSocketClientUpgrader.randomRequestKey().count, 41 | 24, 42 | "request key must be exactly 16 bytes long and this corresponds to 24 characters in base64" 43 | ) 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /dev/boxed-existentials.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -q -s 2 | /*===----------------------------------------------------------------------===* 3 | * 4 | * This source file is part of the SwiftNIO open source project 5 | * 6 | * Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | * Licensed under Apache License v2.0 8 | * 9 | * See LICENSE.txt for license information 10 | * See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | * 12 | * SPDX-License-Identifier: Apache-2.0 13 | * 14 | *===----------------------------------------------------------------------===*/ 15 | 16 | /* 17 | * example invocation: 18 | * sudo dev/boxed-existentials.d -c .build/release/NIOHTTP1Server 19 | */ 20 | 21 | pid$target::__swift_allocate_boxed_opaque_existential*:entry { 22 | ustack(); 23 | } 24 | -------------------------------------------------------------------------------- /dev/git.commit.template: -------------------------------------------------------------------------------- 1 | One line description of your change 2 | 3 | Motivation: 4 | 5 | Explain here the context, and why you're making that change. 6 | What is the problem you're trying to solve. 7 | 8 | Modifications: 9 | 10 | Describe the modifications you've done. 11 | 12 | Result: 13 | 14 | After your change, what will change. 15 | -------------------------------------------------------------------------------- /dev/malloc-aggregation.d: -------------------------------------------------------------------------------- 1 | #!/usr/sbin/dtrace -q -s 2 | /*===----------------------------------------------------------------------===* 3 | * 4 | * This source file is part of the SwiftNIO open source project 5 | * 6 | * Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | * Licensed under Apache License v2.0 8 | * 9 | * See LICENSE.txt for license information 10 | * See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | * 12 | * SPDX-License-Identifier: Apache-2.0 13 | * 14 | *===----------------------------------------------------------------------===*/ 15 | 16 | /* 17 | * example invocation: 18 | * sudo dev/malloc-aggregation.d -c .build/release/NIOHTTP1Server 19 | */ 20 | 21 | ::BEGIN { 22 | printf("\n\n"); 23 | printf("=====\n"); 24 | printf("This will collect stack shots of allocations and print it when "); 25 | printf("you exit dtrace.\n"); 26 | printf("So go ahead, run your tests and then press Ctrl+C in this window "); 27 | printf("to see the aggregated result\n"); 28 | printf("=====\n"); 29 | } 30 | 31 | pid$target::aligned_alloc:entry, 32 | pid$target::calloc:entry, 33 | pid$target::malloc:entry, 34 | pid$target::posix_memalign:entry, 35 | pid$target::realloc:entry, 36 | pid$target::reallocf:entry, 37 | pid$target::valloc:entry, 38 | pid$target::malloc_type_aligned_alloc:entry, 39 | pid$target::malloc_type_calloc:entry, 40 | pid$target::malloc_type_malloc:entry, 41 | pid$target::malloc_type_posix_memalign:entry, 42 | pid$target::malloc_type_realloc:entry, 43 | pid$target::malloc_type_valloc:entry, 44 | pid$target::malloc_zone_calloc:entry, 45 | pid$target::malloc_zone_malloc:entry, 46 | pid$target::malloc_zone_memalign:entry, 47 | pid$target::malloc_zone_realloc:entry, 48 | pid$target::malloc_zone_valloc:entry { 49 | @malloc_calls[ustack()] = count(); 50 | } 51 | 52 | ::END { 53 | printa(@malloc_calls); 54 | } 55 | -------------------------------------------------------------------------------- /docs/migration-guide-NIO1-to-NIO2.md: -------------------------------------------------------------------------------- 1 | # NIO 1 to NIO 2 migration guide 2 | 3 | Please take a look at the [migration guide included with SwiftNIO 2.29.0](https://github.com/apple/swift-nio/blob/2.29.0/docs/migration-guide-NIO1-to-NIO2.md), the last version with Swift 5.0 support. 4 | 5 | [SwiftNIO 2.29.0](https://github.com/apple/swift-nio/releases/tag/2.29.0) includes the `_NIO1APIShims` module which can help to ease the migration. 6 | -------------------------------------------------------------------------------- /docs/optimization-tips.md: -------------------------------------------------------------------------------- 1 | Swift NIO Optimization Tips 2 | =========================== 3 | 4 | The following document is a list of tips and advice for writing high performance 5 | code using Swift NIO. 6 | 7 | General Optimization Tips 8 | ------------------------- 9 | 10 | Although not specific to NIO, the [Swift GitHub repository][swift-repo] has a 11 | list of tips and tricks for [writing high performance Swift code][swift-optimization-tips] 12 | and is a great place to start. 13 | 14 | Wrapping types in `NIOAny` 15 | -------------------------- 16 | 17 | Anything passing through a NIO pipeline that is not special-cased by `NIOAny` 18 | (i.e. is not one of `ByteBuffer`, `FileRegion`, `IOData` or 19 | `AddressedEnvelope`) needs to have careful attention paid to its 20 | size. If the type isn't one of the aforementioned special cases then it must be 21 | no greater than 24 bytes in size to avoid a heap-allocation each time it is 22 | added to a `NIOAny`. The size of a type can be checked using 23 | [`MemoryLayout.size`][docs-memory-layout]. 24 | 25 | If the type being wrapped is a value type then it can be narrowed by placing it 26 | in a copy-on-write box. Alternatively, if the type is an `enum` with associated 27 | data, then it is possible for the associated data to be boxed by the compiler by 28 | making it an `indirect case`. 29 | 30 | 31 | [swift-repo]: https://github.com/apple/swift 32 | [swift-optimization-tips]: https://github.com/apple/swift/blob/main/docs/OptimizationTips.rst 33 | [docs-memory-layout]: https://developer.apple.com/documentation/swift/memorylayout 34 | -------------------------------------------------------------------------------- /docs/workarounds.md: -------------------------------------------------------------------------------- 1 | # Workarounds 2 | 3 | The following list of PRs and commits were applied in order to work around bugs 4 | or cases where the Swift compiler was unable to sufficiently optimize the code: 5 | 6 | - https://github.com/apple/swift-nio/pull/1374 7 | - https://github.com/apple/swift-nio-ssl/pull/176 8 | - https://github.com/apple/swift-nio/pull/1325 9 | - https://github.com/apple/swift-nio/pull/1299 10 | - https://github.com/apple/swift-nio/pull/1252 11 | - https://github.com/apple/swift-nio/pull/494 12 | - https://github.com/apple/swift-nio/pull/420 13 | - https://github.com/apple/swift-nio/commit/abc963cfe1e1d4856c41421c9d53ea778102e9e8 14 | - https://github.com/apple/swift-nio/pull/1814 15 | - https://github.com/apple/swift-nio/pull/1956 16 | - https://github.com/apple/swift-nio/pull/1961 17 | - https://github.com/apple/swift-nio/pull/2046 18 | -------------------------------------------------------------------------------- /scripts/check-cxx-interop-compatibility.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2024 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set -euo pipefail 17 | 18 | log() { printf -- "** %s\n" "$*" >&2; } 19 | error() { printf -- "** ERROR: %s\n" "$*" >&2; } 20 | fatal() { error "$@"; exit 1; } 21 | 22 | log "Checking for Cxx interoperability compatibility..." 23 | 24 | source_dir=$(pwd) 25 | working_dir=$(mktemp -d) 26 | project_name=$(basename "$working_dir") 27 | source_file=Sources/$project_name/$(echo "$project_name" | tr . _).swift 28 | library_products=$( swift package dump-package | jq -r '.products[] | select(.type.library != null) | .name') 29 | package_name=$(swift package dump-package | jq -r '.name') 30 | 31 | cd "$working_dir" 32 | swift package init 33 | 34 | { 35 | echo "let swiftSettings: [SwiftSetting] = [.interoperabilityMode(.Cxx)]" 36 | echo "for target in package.targets { target.swiftSettings = (target.swiftSettings ?? []) + swiftSettings }" 37 | } >> Package.swift 38 | 39 | echo "package.dependencies.append(.package(path: \"$source_dir\"))" >> Package.swift 40 | 41 | for product in $library_products; do 42 | echo "package.targets.first!.dependencies.append(.product(name: \"$product\", package: \"$package_name\"))" >> Package.swift 43 | echo "import $product" >> "$source_file" 44 | done 45 | 46 | swift build 47 | 48 | log "✅ Passed the Cxx interoperability tests." 49 | -------------------------------------------------------------------------------- /scripts/check_benchmark_thresholds.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2025 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set -uo pipefail 17 | 18 | log() { printf -- "** %s\n" "$*" >&2; } 19 | error() { printf -- "** ERROR: %s\n" "$*" >&2; } 20 | fatal() { error "$@"; exit 1; } 21 | 22 | # Parameter environment variables 23 | if [ -z "$SWIFT_VERSION" ]; then 24 | fatal "SWIFT_VERSION must be specified." 25 | fi 26 | 27 | benchmark_package_path="${BENCHMARK_PACKAGE_PATH:-"."}" 28 | swift_version="${SWIFT_VERSION:-""}" 29 | 30 | # Any parameters to the script are passed along to SwiftPM 31 | swift_package_arguments=("$@") 32 | 33 | #"swift package --package-path ${{ inputs.benchmark_package_path }} ${{ inputs.swift_package_arguments }} benchmark baseline check --check-absolute-path ${{ inputs.benchmark_package_path }}/Thresholds/${SWIFT_VERSION}/" 34 | swift package --package-path "$benchmark_package_path" "${swift_package_arguments[@]}" benchmark thresholds check --format metricP90AbsoluteThresholds --path "${benchmark_package_path}/Thresholds/${swift_version}/" 35 | rc="$?" 36 | 37 | # Benchmarks are unchanged, nothing to recalculate 38 | if [[ "$rc" == 0 ]]; then 39 | exit 0 40 | fi 41 | 42 | log "Recalculating thresholds..." 43 | 44 | swift package --package-path "$benchmark_package_path" "${swift_package_arguments[@]}" benchmark thresholds update --format metricP90AbsoluteThresholds --path "${benchmark_package_path}/Thresholds/${swift_version}/" 45 | echo "=== BEGIN DIFF ===" # use echo, not log for clean output to be scraped 46 | git diff --exit-code HEAD 47 | -------------------------------------------------------------------------------- /scripts/cmake-build.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2025 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set -uo pipefail 17 | 18 | log() { printf -- "** %s\n" "$*" >&2; } 19 | error() { printf -- "** ERROR: %s\n" "$*" >&2; } 20 | fatal() { error "$@"; exit 1; } 21 | 22 | target_dir="${TARGET_DIRECTORY:=""}" 23 | 24 | if [ -z "$target_dir" ]; then 25 | fatal "Target directory must be specified." 26 | fi 27 | 28 | CURL_BIN="${CURL_BIN:-$(which curl)}" || fatal "CURL_BIN unset and no curl on PATH" 29 | TAR_BIN="${TAR_BIN:-$(which tar)}" || fatal "TAR_BIN unset and no tar on PATH" 30 | CMAKE_BIN="${CMAKE_BIN:-$(which cmake)}" || fatal "CMAKE_BIN unset and no cmake on PATH" 31 | NINJA_BIN="${NINJA_BIN:-$(which ninja)}" || fatal "NINJA_BIN unset and no ninja on PATH" 32 | ASSEMBLY_COMPILER_BIN="${ASSEMBLY_COMPILER_BIN:-$(which clang)}" || fatal "ASSEMBLY_COMPILER_BIN unset and no clang on PATH" 33 | 34 | log "Building Ninja build files for target" 35 | build_dir="${target_dir}/build" 36 | mkdir -p "$build_dir" 37 | cd "${build_dir}" || fatal "Could not 'cd' to ${build_dir}" 38 | ASM="$ASSEMBLY_COMPILER_BIN" "$CMAKE_BIN" build -G Ninja -S .. 39 | 40 | log "Building target" 41 | "$NINJA_BIN" 42 | -------------------------------------------------------------------------------- /scripts/install_swift_prerequisites.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2025 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set -uo pipefail 17 | 18 | log() { printf -- "** %s\n" "$*" >&2; } 19 | error() { printf -- "** ERROR: %s\n" "$*" >&2; } 20 | fatal() { error "$@"; exit 1; } 21 | 22 | if command -v apt-get >/dev/null; then 23 | PACKAGE_MANAGER_BIN="apt" 24 | apt-get update > /dev/null 25 | elif command -v yum >/dev/null; then 26 | PACKAGE_MANAGER_BIN="yum" 27 | else 28 | fatal "Cannot find either 'apt' or 'yum'" 29 | fi 30 | 31 | log "Installing standard Swift pre-requisites" # pre-reqs list taken from swift.org 32 | DEBIAN_FRONTEND=noninteractive "$PACKAGE_MANAGER_BIN" install -y\ 33 | binutils\ 34 | git\ 35 | gnupg2\ 36 | libc6-dev\ 37 | libcurl4-openssl-dev\ 38 | libedit2\ 39 | libgcc-11-dev\ 40 | libpython3-dev\ 41 | libsqlite3-0\ 42 | libstdc++-11-dev\ 43 | libxml2-dev\ 44 | libz3-dev\ 45 | pkg-config\ 46 | python3-lldb-13\ 47 | tzdata\ 48 | unzip\ 49 | zlib1g-dev\ 50 | > /dev/null 51 | -------------------------------------------------------------------------------- /scripts/integration_tests.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | ##===----------------------------------------------------------------------===## 3 | ## 4 | ## This source file is part of the SwiftNIO open source project 5 | ## 6 | ## Copyright (c) 2017-2018 Apple Inc. and the SwiftNIO project authors 7 | ## Licensed under Apache License v2.0 8 | ## 9 | ## See LICENSE.txt for license information 10 | ## See CONTRIBUTORS.txt for the list of SwiftNIO project authors 11 | ## 12 | ## SPDX-License-Identifier: Apache-2.0 13 | ## 14 | ##===----------------------------------------------------------------------===## 15 | 16 | set +ex 17 | 18 | mkdir -p .build # for the junit.xml file 19 | ./IntegrationTests/run-tests.sh --junit-xml .build/junit-sh-tests.xml -i "$@" 20 | --------------------------------------------------------------------------------