Documentation
¶
Overview ¶
Package compress provides message body compression as a mailbox plugin.
The CompressionPlugin implements mailbox.SendHook and compresses the message body during send. Decompression is handled client-side via the Decompress function or automatically by crypto.Open when used with encryption.
Register this plugin before the encryption plugin for compress-then-encrypt:
svc, _ := mailbox.New(mailbox.Config{},
mailbox.WithStore(store),
mailbox.WithPlugins(
compress.NewPlugin(compress.Gzip),
crypto.NewEncryptionPlugin(keys),
),
)
Reading compressed messages:
msg, _ := mb.Get(ctx, msgID) body, _ := compress.Open(msg)
Index ¶
Examples ¶
Constants ¶
This section is empty.
Variables ¶
var ErrUnsupportedEncoding = errors.New("compress: unsupported content encoding")
ErrUnsupportedEncoding is returned for unknown compression encodings.
Functions ¶
func Decompress ¶
Decompress decompresses data using the specified encoding. Returns the data unchanged if encoding is empty.
func IsCompressed ¶
func IsCompressed(msg MessageReader) bool
IsCompressed returns true if the message has a Content-Encoding header.
Example ¶
ExampleIsCompressed demonstrates checking if a message is compressed.
package main
import (
"context"
"fmt"
"github.com/rbaliyan/mailbox"
"github.com/rbaliyan/mailbox/compress"
"github.com/rbaliyan/mailbox/store"
"github.com/rbaliyan/mailbox/store/memory"
)
func main() {
ctx := context.Background()
svc, _ := mailbox.New(mailbox.Config{},
mailbox.WithStore(memory.New()),
mailbox.WithPlugins(compress.NewPlugin(compress.Gzip)),
)
svc.Connect(ctx)
defer svc.Close(ctx)
svc.Client("alice").SendMessage(ctx, mailbox.SendRequest{
RecipientIDs: []string{"bob"},
Subject: "test",
Body: "body",
})
inbox, _ := svc.Client("bob").Folder(ctx, store.FolderInbox, store.ListOptions{})
fmt.Println("compressed:", compress.IsCompressed(inbox.All()[0]))
}
Output: compressed: true
func Open ¶
func Open(msg MessageReader) ([]byte, error)
Open decompresses a message body based on the Content-Encoding header. Returns the raw body if the message is not compressed.
Example ¶
ExampleOpen demonstrates decompressing a message retrieved from a mailbox.
package main
import (
"context"
"fmt"
"github.com/rbaliyan/mailbox"
"github.com/rbaliyan/mailbox/compress"
"github.com/rbaliyan/mailbox/store"
"github.com/rbaliyan/mailbox/store/memory"
)
func main() {
ctx := context.Background()
svc, _ := mailbox.New(mailbox.Config{},
mailbox.WithStore(memory.New()),
mailbox.WithPlugins(compress.NewPlugin(compress.Gzip)),
)
svc.Connect(ctx)
defer svc.Close(ctx)
// Send a compressed message.
svc.Client("system").SendMessage(ctx, mailbox.SendRequest{
RecipientIDs: []string{"bob"},
Subject: "System notification",
Body: "<h1>Alert</h1><p>Disk usage at 90%.</p>",
Headers: map[string]string{"Content-Type": "text/html"},
})
// Read and decompress.
bob := svc.Client("bob")
inbox, _ := bob.Folder(ctx, store.FolderInbox, store.ListOptions{})
msg := inbox.All()[0]
fmt.Println("compressed:", compress.IsCompressed(msg))
fmt.Println("subject:", msg.GetSubject())
body, _ := compress.Open(msg)
fmt.Println("body:", string(body))
}
Output: compressed: true subject: System notification body: <h1>Alert</h1><p>Disk usage at 90%.</p>
Example (Uncompressed) ¶
ExampleOpen_uncompressed demonstrates that Open works transparently on plain messages.
package main
import (
"context"
"fmt"
"github.com/rbaliyan/mailbox"
"github.com/rbaliyan/mailbox/compress"
"github.com/rbaliyan/mailbox/store"
"github.com/rbaliyan/mailbox/store/memory"
)
func main() {
ctx := context.Background()
// No compression plugin.
svc, _ := mailbox.New(mailbox.Config{}, mailbox.WithStore(memory.New()))
svc.Connect(ctx)
defer svc.Close(ctx)
svc.Client("alice").SendMessage(ctx, mailbox.SendRequest{
RecipientIDs: []string{"bob"},
Subject: "Plain text",
Body: "No compression here.",
})
bob := svc.Client("bob")
inbox, _ := bob.Folder(ctx, store.FolderInbox, store.ListOptions{})
msg := inbox.All()[0]
fmt.Println("compressed:", compress.IsCompressed(msg))
body, _ := compress.Open(msg)
fmt.Println("body:", string(body))
}
Output: compressed: false body: No compression here.
Types ¶
type Compressor ¶
type Compressor interface {
// Algorithm returns the Content-Encoding value (e.g., "gzip", "zstd").
Algorithm() string
// Compress compresses data.
Compress(data []byte) ([]byte, error)
// Decompress decompresses data.
Decompress(data []byte) ([]byte, error)
}
Compressor compresses and decompresses data.
var ( // Gzip is a gzip compressor using default compression level. Gzip Compressor = &gzipCompressor{level: gzip.DefaultCompression} // GzipBest is a gzip compressor using best compression. GzipBest Compressor = &gzipCompressor{level: gzip.BestCompression} )
Pre-built compressors.
type MessageReader ¶
MessageReader is the minimal interface for reading compressed messages.
type Plugin ¶
type Plugin struct {
// contains filtered or unexported fields
}
Plugin compresses message bodies before send. Implements mailbox.SendHook.
func NewPlugin ¶
func NewPlugin(c Compressor) *Plugin
NewPlugin creates a compression plugin with the given compressor.
Example (Basic) ¶
ExampleNewPlugin_basic demonstrates basic compression and decompression.
package main
import (
"context"
"fmt"
"github.com/rbaliyan/mailbox"
"github.com/rbaliyan/mailbox/compress"
"github.com/rbaliyan/mailbox/store"
"github.com/rbaliyan/mailbox/store/memory"
)
func main() {
ctx := context.Background()
svc, _ := mailbox.New(mailbox.Config{},
mailbox.WithStore(memory.New()),
mailbox.WithPlugins(compress.NewPlugin(compress.Gzip)),
)
svc.Connect(ctx)
defer svc.Close(ctx)
svc.Client("alice").SendMessage(ctx, mailbox.SendRequest{
RecipientIDs: []string{"bob"},
Subject: "Compressed",
Body: "This body is gzip compressed before storage.",
})
bob := svc.Client("bob")
inbox, _ := bob.Folder(ctx, store.FolderInbox, store.ListOptions{})
msg := inbox.All()[0]
fmt.Println("encoding:", msg.GetHeaders()["Content-Encoding"])
plaintext, _ := compress.Open(msg)
fmt.Println("body:", string(plaintext))
}
Output: encoding: gzip body: This body is gzip compressed before storage.
Example (BestCompression) ¶
ExampleNewPlugin_bestCompression demonstrates using best compression level.
package main
import (
"context"
"fmt"
"github.com/rbaliyan/mailbox"
"github.com/rbaliyan/mailbox/compress"
"github.com/rbaliyan/mailbox/store"
"github.com/rbaliyan/mailbox/store/memory"
)
func main() {
ctx := context.Background()
svc, _ := mailbox.New(mailbox.Config{},
mailbox.WithStore(memory.New()),
mailbox.WithPlugins(compress.NewPlugin(compress.GzipBest)),
)
svc.Connect(ctx)
defer svc.Close(ctx)
svc.Client("alice").SendMessage(ctx, mailbox.SendRequest{
RecipientIDs: []string{"bob"},
Subject: "Best compression",
Body: "Repetitive data benefits from best compression: aaaaaaaaaaaaaaaaaaaaaaaaaaa",
})
bob := svc.Client("bob")
inbox, _ := bob.Folder(ctx, store.FolderInbox, store.ListOptions{})
plaintext, _ := compress.Open(inbox.All()[0])
fmt.Println("body:", string(plaintext))
}
Output: body: Repetitive data benefits from best compression: aaaaaaaaaaaaaaaaaaaaaaaaaaa
func (*Plugin) BeforeSend ¶
BeforeSend compresses the message body and sets the Content-Encoding header.