Skip to content

Commit ef20269

Browse files
authored
Cleanup (#705)
1 parent d459719 commit ef20269

File tree

3 files changed

+58
-29
lines changed

3 files changed

+58
-29
lines changed

Diff for: CODE_OF_CONDUCT.md

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
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+
<!-- Copyright (c) 2021 Apple Inc and the Swift Project authors. All Rights Reserved. -->

Diff for: Package.swift

+3-3
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ let package = Package(
1111
.package(url: "https://github.com/apple/swift-nio", from: "2.40.0"),
1212
.package(url: "https://github.com/apple/swift-nio-ssl", from: "2.20.0"),
1313
.package(url: "https://github.com/apple/swift-log", from: "1.4.0"),
14-
.package(url: "https://github.com/nicklockwood/SwiftFormat", exact: "0.49.11"),
15-
.package(url: "https://github.com/apple/swift-standard-library-preview.git", exact: "0.0.3"),
16-
.package(url: "https://github.com/apple/swift-collections.git", .upToNextMajor(from: "1.0.2")),
14+
.package(url: "https://github.com/apple/swift-standard-library-preview.git", from: "0.0.3"),
15+
.package(url: "https://github.com/apple/swift-collections.git", "1.0.2" ..< "2.0.0"),
16+
.package(url: "https://github.com/nicklockwood/SwiftFormat", from: "0.49.11"),
1717
],
1818
targets: [
1919
.executableTarget(

Diff for: README.md

+50-26
Original file line numberDiff line numberDiff line change
@@ -2,45 +2,69 @@
22

33
A Swift project that provides an implementation of the IMAP4rev1 protocol, built upon SwiftNIO.
44

5-
### Introduction and Usage
5+
This project implements:
6+
* Parsing IMAPv4 wire-format to type-safe Swift data structures
7+
* Encoding these Swift data structures to the IMAPv4 wire format
8+
* Extensive support for common IMAP extensions
9+
* Integration with SwiftNIO
610

7-
`swift-nio-imap` implements the IMAP4rev1 protocol described in RFC 3501 and related RFCs. It is intended as a building block to build mail clients and/or servers. It is built upon SwiftNIO v2.x.
11+
For a list of IMAP extensions, see [EXTENSIONS.md](EXTENSIONS.md).
812

9-
To use the framework use `import NIOIMAP`. NIOIMAP supports a variety of IMAP extensions, check `EXTENSIONS.md` for full details.
13+
*Note:* This is still a prototype and not quite production ready, yet.
1014

11-
### Commands
15+
### Introduction and Usage
1216

13-
Commands are what an IMAP client sends to a server.
17+
`swift-nio-imap` implements the IMAP4rev1 protocol described in RFC 3501 and related RFCs. It is intended as a building block to build mail clients and/or servers. It is built upon SwiftNIO v2.x.
1418

15-
A command consists of a `Tag` and a `Command`.
19+
To use the framework use `import NIOIMAP`. NIOIMAP supports a variety of IMAP extensions, check `EXTENSIONS.md` for full details.
1620

17-
#### Examples
18-
`Command("tag1", .noop)` => `tag1 NOOP`
19-
`Command("tag2", .capability)` => `tag1 CAPABILITY`
20-
`Command("tag3", .login("[email protected]", "password"))` => `tag3 LOGIN "[email protected]" "password"`
21+
### Example Exchange
2122

22-
To send a command we recommend using a `MessageToByteHandler` with `CommandEncoder` as the encoder:
23+
As a quick example, here’s part of the the exchange listed in RFC 3501 section 8, where lines starting with S: and C: are from the server and client respectively:
2324

24-
```
25-
ClientBootstrap(group: context.eventLoop).channelInitializer { channel in
26-
channel.addHandler(MessageToByteHandler(CommandEncoder()))
27-
}
25+
```text
26+
S: * OK IMAP4rev1 Service Ready
27+
C: a001 login mrc secret
28+
S: a001 OK LOGIN completed
29+
C: a002 select inbox
30+
S: * 18 EXISTS
31+
S: * FLAGS (\Answered \Flagged \Deleted \Seen \Draft)
32+
S: * 2 RECENT
33+
S: * OK [UNSEEN 17] Message 17 is the first unseen message
34+
S: * OK [UIDVALIDITY 3857529045] UIDs valid
35+
S: a002 OK [READ-WRITE] SELECT completed```
2836
```
2937

30-
Alternatively, you can write a command manually to a `ByteBuffer` manually like this:
38+
The first 3 lines would correspond to the following in SwiftNIO IMAP:
39+
```swift
40+
Response.untagged(.conditionalState(.ok(ResponseText(text: "IMAP4rev1 Service Ready"))))
41+
CommandStreamPart.tagged(TaggedCommand(tag: "a001", command: .login(username: "mrc", password: "secret")))
42+
Response.tagged(.init(tag: "a001", state: .ok(ResponseText(text: "LOGIN completed"))))
3143
```
32-
let command = ...
33-
var buffer = ...
34-
let writtenSize = buffer.writeCommand(command)
44+
45+
Next, up is the SELECT command and its responses, which are more interesting:
46+
```swift
47+
CommandStreamPart.tagged(TaggedCommand(tag: "a002", command: .select(MailboxName("box1"), [])))
48+
Response.untagged(.mailboxData(.exists(18)))
49+
Response.untagged(.mailboxData(.flags([.answered, .flagged, .deleted, .seen, .draft])))
50+
Response.untagged(.mailboxData(.recent(2)))
51+
Response.untagged(.conditionalState(.ok(ResponseText(code: .unseen(17), text: "Message 17 is the first unseen message"))))
52+
Response.untagged(.conditionalState(.ok(ResponseText(code: .uidValidity(3857529045), text: "UIDs valid"))))
53+
Response.tagged(.init(tag: "a002", state: .ok(ResponseText(code: .readWrite, text: "SELECT completed"))))
3554
```
3655

37-
### Sample applications
38-
#### Proxy
39-
We provide a simple proxy that can be placed between some mail client and server. The mail server *must* support TLS.
56+
There’s more going on here than this example shows. But this gives a general idea of how the types look and feel.
4057

41-
`swift run Proxy <local_address> <local_port> <server_address> <server_port>`
58+
### Integration with SwiftNIO
4259

43-
#### CLI
44-
The CLI allows you (the user) to connect to a mail server and enter commands. The mail server *must* support TLS. The CLI will always attempt to connect to the server on port 993.
60+
SwiftNIO IMAP provides a pair of ChannelHandler objects that can be integrated into a SwiftNIO ChannelPipeline. This allows sending IMAP commands using NIO Channels.
4561

46-
`swift run CLI`
62+
The two handlers SwiftNIO IMAP provides are IMAPClientHandler and IMAPServerHandler. Each of these can be inserted into the ChannelPipeline. They can then be used to encode and decode messages. For example:
63+
```swift
64+
let group = MultiThreadedEventLoopGroup(numberOfThreads: 1)
65+
let channel = try await ClientBootstrap(group).channelInitializer { channel in
66+
channel.pipeline.addHandler(IMAPClientHandler())
67+
}.connect(host: example.com, port: 143).get()
68+
69+
try await channel.writeAndFlush(CommandStreamPart.tagged(TaggedCommand(tag: "a001", command: .login(username: "mrc", password: "secret"))), promise: nil)
70+
```

0 commit comments

Comments
 (0)