├── .editorconfig ├── .github ├── ISSUE_TEMPLATE.md ├── PULL_REQUEST_TEMPLATE.md └── workflows │ ├── main.yml │ └── pull_request.yml ├── .gitignore ├── .licenseignore ├── .swift-format ├── .swiftformatignore ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── LICENSE.txt ├── NIOSMTP ├── .gitignore ├── NIOSMTP.xcodeproj │ └── project.pbxproj ├── NIOSMTP │ ├── AppDelegate.swift │ ├── Assets.xcassets │ │ ├── AppIcon.appiconset │ │ │ └── Contents.json │ │ └── Contents.json │ ├── Base.lproj │ │ ├── LaunchScreen.storyboard │ │ └── Main.storyboard │ ├── Configuration.swift │ ├── DataModel.swift │ ├── Info.plist │ ├── PrintEverythingHandler.swift │ ├── SMTPRequestEncoder.swift │ ├── SMTPResponseDecoder.swift │ ├── SendEmailHandler.swift │ └── ViewController.swift ├── README.md └── build.sh ├── README.md ├── TLSify ├── .gitignore ├── Package.swift ├── README.md └── Sources │ ├── TLSify │ └── main.swift │ └── TLSifyLib │ ├── CloseOnErrorHandler.swift │ ├── GlueHandler.swift │ └── TLSProxy.swift ├── UniversalBootstrapDemo ├── .gitignore ├── Package.swift ├── README.md └── Sources │ └── UniversalBootstrapDemo │ ├── EventLoopGroupManager.swift │ ├── ExampleHTTPLibrary.swift │ └── main.swift ├── backpressure-file-io-channel ├── .gitignore ├── Package.swift ├── README.md ├── Sources │ ├── BackpressureChannelToFileIO │ │ ├── FileIOChannelWriteCoordinator.swift │ │ └── SaveEverythingHTTPServer.swift │ └── BackpressureChannelToFileIODemo │ │ └── main.swift └── Tests │ └── BackpressureChannelToFileIOTests │ ├── IntegrationTest.swift │ └── StateMachineTest.swift ├── connect-proxy ├── .gitignore ├── Package.swift └── Sources │ └── ConnectProxy │ ├── ConnectHandler.swift │ ├── ConnectProxyError.swift │ ├── GlueHandler.swift │ └── main.swift ├── dev ├── build_all.sh └── git.commit.template ├── http-responsiveness-server ├── Package.swift └── Sources │ └── HTTPResponsivenessServer │ └── main.swift ├── http2-client ├── .gitignore ├── Package.swift ├── Sources │ └── http2-client │ │ ├── Types.swift │ │ └── main.swift └── scripts │ └── test_top_sites.sh ├── http2-server ├── .gitignore ├── Package.swift ├── README.md └── Sources │ └── http2-server │ ├── HardcodedPrivateKeyAndCerts.swift │ └── main.swift ├── json-rpc ├── .gitignore ├── Package.swift ├── README.md ├── Sources │ ├── ClientExample │ │ └── main.swift │ ├── JsonRpc │ │ ├── Client.swift │ │ ├── Codec.swift │ │ ├── Model.swift │ │ ├── Server.swift │ │ └── Utils.swift │ ├── LightsdDemo │ │ └── main.swift │ └── ServerExample │ │ └── main.swift └── Tests │ ├── JsonRpcTests │ ├── JsonRpcTests.swift │ └── XCTestManifests.swift │ └── LinuxMain.swift └── nio-launchd ├── .gitignore ├── Package.swift ├── README.md └── Sources └── nio-launchd ├── Client.swift ├── Server.swift └── main.swift /.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 -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE.md: -------------------------------------------------------------------------------- 1 | ### Expected behavior 2 | _[what you expected to happen]_ 3 | 4 | ### Actual behavior 5 | _[what actually happened]_ 6 | 7 | ### Steps to reproduce 8 | 9 | 1. ... 10 | 2. ... 11 | 12 | ### If possible, minimal yet complete reproducer code (or URL to code) 13 | 14 | _[anything to help us reproducing the issue]_ 15 | 16 | ### version/commit hashes from all involved dependencies 17 | 18 | _[tag/commit hash]_ 19 | 20 | ### Swift & OS version (output of `swift --version && uname -a`) 21 | -------------------------------------------------------------------------------- /.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/workflows/main.yml: -------------------------------------------------------------------------------- 1 | name: Main 2 | 3 | on: 4 | push: 5 | branches: [main] 6 | schedule: 7 | - cron: "0 8,20 * * *" 8 | 9 | jobs: 10 | soundness: 11 | name: Soundness 12 | uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main 13 | with: 14 | license_header_check_project_name: "SwiftNIO" 15 | docs_check_enabled: false 16 | api_breakage_check_enabled: false 17 | 18 | construct-build-test-matrix: 19 | name: Construct build matrix 20 | runs-on: ubuntu-latest 21 | outputs: 22 | build-test-matrix: '${{ steps.generate-matrix.outputs.build-test-matrix }}' 23 | steps: 24 | - name: Checkout repository 25 | uses: actions/checkout@v4 26 | with: 27 | persist-credentials: false 28 | - id: generate-matrix 29 | run: echo "build-test-matrix=$(curl -s https://raw.githubusercontent.com/apple/swift-nio/main/scripts/generate_matrix.sh | bash)" >> "$GITHUB_OUTPUT" 30 | env: 31 | MATRIX_LINUX_COMMAND: STRICT_CONCURRENCY=true SWIFT_PACKAGE_DIRECTORIES='TLSify UniversalBootstrapDemo http-responsiveness-server connect-proxy http2-client http2-server json-rpc nio-launchd' dev/build_all.sh && SWIFT_PACKAGE_DIRECTORIES='backpressure-file-io-channel' dev/build_all.sh 32 | 33 | build-tests: 34 | name: Builds 35 | needs: construct-build-test-matrix 36 | uses: apple/swift-nio/.github/workflows/swift_test_matrix.yml@main 37 | with: 38 | name: "Builds" 39 | matrix_string: '${{ needs.construct-build-test-matrix.outputs.build-test-matrix }}' 40 | -------------------------------------------------------------------------------- /.github/workflows/pull_request.yml: -------------------------------------------------------------------------------- 1 | name: PR 2 | 3 | on: 4 | pull_request: 5 | types: [opened, reopened, synchronize] 6 | 7 | jobs: 8 | soundness: 9 | name: Soundness 10 | uses: swiftlang/github-workflows/.github/workflows/soundness.yml@main 11 | with: 12 | license_header_check_project_name: "SwiftNIO" 13 | docs_check_enabled: false 14 | api_breakage_check_enabled: false 15 | 16 | construct-build-test-matrix: 17 | name: Construct build matrix 18 | runs-on: ubuntu-latest 19 | outputs: 20 | build-test-matrix: '${{ steps.generate-matrix.outputs.build-test-matrix }}' 21 | steps: 22 | - name: Checkout repository 23 | uses: actions/checkout@v4 24 | with: 25 | persist-credentials: false 26 | - id: generate-matrix 27 | run: echo "build-test-matrix=$(curl -s https://raw.githubusercontent.com/apple/swift-nio/main/scripts/generate_matrix.sh | bash)" >> "$GITHUB_OUTPUT" 28 | env: 29 | MATRIX_LINUX_COMMAND: STRICT_CONCURRENCY=true SWIFT_PACKAGE_DIRECTORIES='TLSify UniversalBootstrapDemo http-responsiveness-server connect-proxy http2-client http2-server json-rpc nio-launchd' dev/build_all.sh && SWIFT_PACKAGE_DIRECTORIES='backpressure-file-io-channel' dev/build_all.sh 30 | 31 | build-tests: 32 | name: Build tests 33 | needs: construct-build-test-matrix 34 | uses: apple/swift-nio/.github/workflows/swift_test_matrix.yml@main 35 | with: 36 | name: "Build tests" 37 | matrix_string: '${{ needs.construct-build-test-matrix.outputs.build-test-matrix }}' 38 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .build/ 2 | .swiftpm/ 3 | .DS_Store 4 | Package.resolved 5 | NIOSMTP/NIOSMTP.xcodeproj/xcshareddata 6 | -------------------------------------------------------------------------------- /.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 | NIOSMTP/NIOSMTP.xcodeproj/project.pbxproj 35 | NIOSMTP/NIOSMTP/Base.lproj/LaunchScreen.storyboard 36 | NIOSMTP/NIOSMTP/Base.lproj/Main.storyboard 37 | NIOSMTP/build.sh 38 | dev/git.commit.template 39 | .swiftformatignore 40 | -------------------------------------------------------------------------------- /.swift-format: -------------------------------------------------------------------------------- 1 | { 2 | "version" : 1, 3 | "indentation" : { 4 | "spaces" : 4 5 | }, 6 | "tabWidth" : 4, 7 | "fileScopedDeclarationPrivacy" : { 8 | "accessLevel" : "private" 9 | }, 10 | "spacesAroundRangeFormationOperators" : false, 11 | "indentConditionalCompilationBlocks" : false, 12 | "indentSwitchCaseLabels" : false, 13 | "lineBreakAroundMultilineExpressionChainComponents" : false, 14 | "lineBreakBeforeControlFlowKeywords" : false, 15 | "lineBreakBeforeEachArgument" : true, 16 | "lineBreakBeforeEachGenericRequirement" : true, 17 | "lineLength" : 120, 18 | "maximumBlankLines" : 1, 19 | "respectsExistingLineBreaks" : true, 20 | "prioritizeKeepingFunctionOutputTogether" : true, 21 | "rules" : { 22 | "AllPublicDeclarationsHaveDocumentation" : false, 23 | "AlwaysUseLiteralForEmptyCollectionInit" : false, 24 | "AlwaysUseLowerCamelCase" : false, 25 | "AmbiguousTrailingClosureOverload" : true, 26 | "BeginDocumentationCommentWithOneLineSummary" : false, 27 | "DoNotUseSemicolons" : true, 28 | "DontRepeatTypeInStaticProperties" : true, 29 | "FileScopedDeclarationPrivacy" : true, 30 | "FullyIndirectEnum" : true, 31 | "GroupNumericLiterals" : true, 32 | "IdentifiersMustBeASCII" : true, 33 | "NeverForceUnwrap" : false, 34 | "NeverUseForceTry" : false, 35 | "NeverUseImplicitlyUnwrappedOptionals" : false, 36 | "NoAccessLevelOnExtensionDeclaration" : true, 37 | "NoAssignmentInExpressions" : true, 38 | "NoBlockComments" : true, 39 | "NoCasesWithOnlyFallthrough" : true, 40 | "NoEmptyTrailingClosureParentheses" : true, 41 | "NoLabelsInCasePatterns" : true, 42 | "NoLeadingUnderscores" : false, 43 | "NoParensAroundConditions" : true, 44 | "NoVoidReturnOnFunctionSignature" : true, 45 | "OmitExplicitReturns" : true, 46 | "OneCasePerLine" : true, 47 | "OneVariableDeclarationPerLine" : true, 48 | "OnlyOneTrailingClosureArgument" : true, 49 | "OrderedImports" : true, 50 | "ReplaceForEachWithForLoop" : true, 51 | "ReturnVoidInsteadOfEmptyTuple" : true, 52 | "UseEarlyExits" : false, 53 | "UseExplicitNilCheckInConditions" : false, 54 | "UseLetInEveryBoundCaseVariable" : false, 55 | "UseShorthandTypeNames" : true, 56 | "UseSingleLinePropertyGetter" : false, 57 | "UseSynthesizedInitializer" : false, 58 | "UseTripleSlashForDocumentationComments" : true, 59 | "UseWhereClausesInForLoops" : false, 60 | "ValidateDocumentationComments" : false 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /.swiftformatignore: -------------------------------------------------------------------------------- 1 | **Package.swift 2 | json-rpc/Tests/JsonRpcTests/XCTestManifests.swift 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 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Legal 2 | 3 | By submitting a pull request, you represent that you have the right to license 4 | your contribution to Apple and the community, and agree by submitting the patch 5 | that your contributions are licensed under the Apache 2.0 license (see 6 | `LICENSE.txt`). 7 | 8 | 9 | ## How to submit a bug report 10 | 11 | Please ensure to specify the following: 12 | 13 | * all relevant commit hashes 14 | * Contextual information (e.g. what you were trying to achieve and which example 15 | you tried to use) 16 | * Simplest possible steps to reproduce 17 | * More complex the steps are, lower the priority will be. 18 | * A pull request with failing test case is preferred, but it's just fine to paste the test case into the issue description. 19 | * Anything that might be relevant in your opinion, such as: 20 | * Swift version or the output of `swift --version` 21 | * OS version and the output of `uname -a` 22 | * Network configuration 23 | 24 | 25 | ### Example 26 | 27 | ``` 28 | - swift-nio commit hash: 22ec043dc9d24bb011b47ece4f9ee97ee5be2757 29 | - swift-nio-examples commit hash: 49d0fd7c1036993dfd538a34cf042d4d24a9792d 30 | 31 | Context: 32 | When running NIOSMTP with an illegal email address, the app crashes. 33 | 34 | Steps to reproduce: 35 | 1. ... 36 | 2. ... 37 | 3. ... 38 | 4. ... 39 | 40 | $ swift --version 41 | Swift version 4.2.0 (swift-4.2.0-RELEASE) 42 | Target: x86_64-unknown-linux-gnu 43 | 44 | Operating system: Ubuntu Linux 18.04 64-bit 45 | 46 | $ uname -a 47 | Linux beefy.machine 4.4.0-101-generic #124-Ubuntu SMP Fri Sep 10 18:29:59 UTC 2018 x86_64 x86_64 x86_64 GNU/Linux 48 | 49 | My system has IPv6 disabled. 50 | ``` 51 | 52 | ## Writing a Patch 53 | 54 | A good patch is: 55 | 56 | 1. Concise, and contains as few changes as needed to achieve the end result. 57 | 2. Tested, ensuring that any tests provided failed before the patch and pass after it. 58 | 3. Documented, adding API documentation as needed to cover new functions and properties. 59 | 4. Accompanied by a great commit message, using our commit message template. 60 | 61 | ### Commit Message Template 62 | 63 | We require that your commit messages match our template. The easiest way to do that is to get git to help you by explicitly using the template. To do that, `cd` to the root of our repository and run: 64 | 65 | git config commit.template dev/git.commit.template 66 | 67 | ## How to contribute your work 68 | 69 | Please open a pull request at https://github.com/apple/swift-nio-examples and wait for the code review. If you don't receive any within a few days, please kindly 70 | remind the core SwiftNIO team. 71 | -------------------------------------------------------------------------------- /NIOSMTP/.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Xcode 4 | build/ 5 | *.pbxuser 6 | !default.pbxuser 7 | *.mode1v3 8 | !default.mode1v3 9 | *.mode2v3 10 | !default.mode2v3 11 | *.perspectivev3 12 | !default.perspectivev3 13 | *.xcworkspace 14 | !default.xcworkspace 15 | xcuserdata 16 | profile 17 | *.moved-aside 18 | DerivedData 19 | .idea/ 20 | 21 | # CocoaPods 22 | Pods 23 | Podfile.lock 24 | -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/AppDelegate.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 UIKit 16 | 17 | @UIApplicationMain 18 | class AppDelegate: UIResponder, UIApplicationDelegate { 19 | 20 | var window: UIWindow? 21 | 22 | func application( 23 | _ application: UIApplication, 24 | didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]? 25 | ) -> Bool { 26 | 27 | true 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/Assets.xcassets/AppIcon.appiconset/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "images" : [ 3 | { 4 | "idiom" : "iphone", 5 | "size" : "20x20", 6 | "scale" : "2x" 7 | }, 8 | { 9 | "idiom" : "iphone", 10 | "size" : "20x20", 11 | "scale" : "3x" 12 | }, 13 | { 14 | "idiom" : "iphone", 15 | "size" : "29x29", 16 | "scale" : "2x" 17 | }, 18 | { 19 | "idiom" : "iphone", 20 | "size" : "29x29", 21 | "scale" : "3x" 22 | }, 23 | { 24 | "idiom" : "iphone", 25 | "size" : "40x40", 26 | "scale" : "2x" 27 | }, 28 | { 29 | "idiom" : "iphone", 30 | "size" : "40x40", 31 | "scale" : "3x" 32 | }, 33 | { 34 | "idiom" : "iphone", 35 | "size" : "60x60", 36 | "scale" : "2x" 37 | }, 38 | { 39 | "idiom" : "iphone", 40 | "size" : "60x60", 41 | "scale" : "3x" 42 | }, 43 | { 44 | "idiom" : "ipad", 45 | "size" : "20x20", 46 | "scale" : "1x" 47 | }, 48 | { 49 | "idiom" : "ipad", 50 | "size" : "20x20", 51 | "scale" : "2x" 52 | }, 53 | { 54 | "idiom" : "ipad", 55 | "size" : "29x29", 56 | "scale" : "1x" 57 | }, 58 | { 59 | "idiom" : "ipad", 60 | "size" : "29x29", 61 | "scale" : "2x" 62 | }, 63 | { 64 | "idiom" : "ipad", 65 | "size" : "40x40", 66 | "scale" : "1x" 67 | }, 68 | { 69 | "idiom" : "ipad", 70 | "size" : "40x40", 71 | "scale" : "2x" 72 | }, 73 | { 74 | "idiom" : "ipad", 75 | "size" : "76x76", 76 | "scale" : "1x" 77 | }, 78 | { 79 | "idiom" : "ipad", 80 | "size" : "76x76", 81 | "scale" : "2x" 82 | }, 83 | { 84 | "idiom" : "ipad", 85 | "size" : "83.5x83.5", 86 | "scale" : "2x" 87 | }, 88 | { 89 | "idiom" : "ios-marketing", 90 | "size" : "1024x1024", 91 | "scale" : "1x" 92 | } 93 | ], 94 | "info" : { 95 | "version" : 1, 96 | "author" : "xcode" 97 | } 98 | } -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/Assets.xcassets/Contents.json: -------------------------------------------------------------------------------- 1 | { 2 | "info" : { 3 | "version" : 1, 4 | "author" : "xcode" 5 | } 6 | } -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/Base.lproj/LaunchScreen.storyboard: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/Configuration.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 NIOTransportServices 16 | 17 | struct Configuration { 18 | static let shared: Configuration = { 19 | // If you don't want to use your real SMTP server, do try out https://mailtrap.io they offer you an 20 | // SMTP server that can be used for testing for free. 21 | let serverConfig = ServerConfiguration( 22 | hostname: "you.need.to.configure.your.providers.smtp.server", 23 | port: 25, 24 | username: "put your username here", 25 | password: "and your password goes here", 26 | tlsConfiguration: .startTLS 27 | ) 28 | 29 | precondition( 30 | serverConfig.hostname != "you.need.to.configure.your.providers.smtp.server", 31 | "You need to configure an SMTP server in code." 32 | ) 33 | 34 | return Configuration(serverConfig: serverConfig) 35 | }() 36 | 37 | var serverConfig: ServerConfiguration 38 | } 39 | -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/DataModel.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 | enum SMTPRequest { 16 | case sayHello(serverName: String) 17 | case startTLS 18 | case beginAuthentication 19 | case authUser(String) 20 | case authPassword(String) 21 | case mailFrom(String) 22 | case recipient(String) 23 | case data 24 | case transferData(Email) 25 | case quit 26 | } 27 | 28 | enum SMTPResponse { 29 | case ok(Int, String) 30 | case error(String) 31 | } 32 | 33 | struct ServerConfiguration { 34 | enum TLSConfiguration { 35 | /// Use StartTLS, this should be the default and is secure. 36 | case startTLS 37 | 38 | /// Directly open a TLS connection. This secure however not widely supported. 39 | case regularTLS 40 | 41 | /// This should never be used. It will literally _SEND YOUR PASSWORD IN PLAINTEXT OVER THE INTERNET_. 42 | case insecureNoTLS 43 | } 44 | var hostname: String 45 | var port: Int 46 | var username: String 47 | var password: String 48 | var tlsConfiguration: TLSConfiguration 49 | } 50 | 51 | struct Email { 52 | var senderName: String? 53 | var senderEmail: String 54 | 55 | var recipientName: String? 56 | var recipientEmail: String 57 | 58 | var subject: String 59 | 60 | var body: String 61 | } 62 | -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | $(DEVELOPMENT_LANGUAGE) 7 | CFBundleExecutable 8 | $(EXECUTABLE_NAME) 9 | CFBundleIdentifier 10 | $(PRODUCT_BUNDLE_IDENTIFIER) 11 | CFBundleInfoDictionaryVersion 12 | 6.0 13 | CFBundleName 14 | $(PRODUCT_NAME) 15 | CFBundlePackageType 16 | APPL 17 | CFBundleShortVersionString 18 | 1.0 19 | CFBundleVersion 20 | 1 21 | LSRequiresIPhoneOS 22 | 23 | UILaunchStoryboardName 24 | LaunchScreen 25 | UIMainStoryboardFile 26 | Main 27 | UIRequiredDeviceCapabilities 28 | 29 | armv7 30 | 31 | UISupportedInterfaceOrientations 32 | 33 | UIInterfaceOrientationPortrait 34 | UIInterfaceOrientationLandscapeLeft 35 | UIInterfaceOrientationLandscapeRight 36 | 37 | UISupportedInterfaceOrientations~ipad 38 | 39 | UIInterfaceOrientationPortrait 40 | UIInterfaceOrientationPortraitUpsideDown 41 | UIInterfaceOrientationLandscapeLeft 42 | UIInterfaceOrientationLandscapeRight 43 | 44 | 45 | 46 | -------------------------------------------------------------------------------- /NIOSMTP/NIOSMTP/PrintEverythingHandler.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 Foundation 16 | import NIOCore 17 | import NIOTransportServices 18 | 19 | final class PrintEverythingHandler: ChannelDuplexHandler { 20 | typealias InboundIn = ByteBuffer 21 | typealias InboundOut = ByteBuffer 22 | typealias OutboundIn = ByteBuffer 23 | typealias OutboundOut = ByteBuffer 24 | 25 | private let handler: (String) -> Void 26 | 27 | init(handler: @escaping (String) -> Void) { 28 | self.handler = handler 29 | } 30 | 31 | func channelRead(context: ChannelHandlerContext, data: NIOAny) { 32 | let buffer = self.unwrapInboundIn(data) 33 | self.handler("☁️ \(String(decoding: buffer.readableBytesView, as: UTF8.self))") 34 | context.fireChannelRead(data) 35 | } 36 | 37 | func write(context: ChannelHandlerContext, data: NIOAny, promise: EventLoopPromise?) { 38 | let buffer = self.unwrapOutboundIn(data) 39 | if buffer.readableBytesView.starts( 40 | with: Data(Configuration.shared.serverConfig.password.utf8).base64EncodedData() 41 | ) { 42 | self.handler("📱