RFC 3030 – SMTP BINARYMIME và CHUNKING
Tại sao RFC này tồn tại
SMTP truyền thống sử dụng lệnh DATA để truyền nội dung tin nhắn. Phần thân tin nhắn được gửi dưới dạng luồng văn bản, kết thúc bằng một dòng chỉ chứa dấu chấm (.\r\n). Thiết kế này có hai vấn đề:
- Overhead dot-stuffing: Bất kỳ dòng nào trong tin nhắn bắt đầu bằng dấu chấm phải được thoát bằng cách thêm một dấu chấm phụ. Máy chủ phải quét từng dòng để loại bỏ ký tự thoát. Điều này làm tăng overhead xử lý và có thể gây ra lỗi.
-
Không hỗ trợ nhị phân: Lệnh
DATAgiả định văn bản ASCII 7 bit có kết thúc dòng CRLF. Nội dung nhị phân (như tệp đính kèm) phải được mã hóa Base64, làm tăng kích thước dữ liệu khoảng 33%.
RFC 3030 định nghĩa hai tiện ích mở rộng liên quan giải quyết các vấn đề này. CHUNKING giới thiệu lệnh BDAT, truyền dữ liệu theo các khối có kích thước xác định rõ — không cần dot-stuffing. BINARYMIME xây dựng trên CHUNKING để cho phép nội dung nhị phân thô mà không cần mã hóa.
Cách hoạt động
CHUNKING (lệnh BDAT)
- Máy chủ quảng cáo
CHUNKINGtrong phản hồi EHLO của nó. - Thay vì
DATA, máy khách sử dụngBDAT <size>để gửi một khối chính xác<size>octet. - Máy chủ đọc chính xác số byte đó, sau đó gửi phản hồi.
- Máy khách có thể gửi nhiều khối
BDAT. Khối cuối cùng bao gồm từ khóaLAST:BDAT <size> LAST. - Không cần dot-stuffing vì kích thước là rõ ràng.
BINARYMIME
- Máy chủ quảng cáo cả
CHUNKINGvàBINARYMIMEtrong phản hồi EHLO của nó. - Máy khách khai báo
BODY=BINARYMIMEtrên lệnhMAIL FROM. - Dữ liệu tin nhắn được gửi thông qua
BDATvà có thể chứa nội dung nhị phân thô — không mã hóa Base64, không yêu cầu kết thúc dòng CRLF.
Ví dụ SMTP
Gửi tin nhắn sử dụng BDAT thay vì DATA:
Với BINARYMIME cho nội dung nhị phân thô:
Chi tiết kỹ thuật chính
BDAT so với DATA
| Khía cạnh | DATA | BDAT (CHUNKING) |
|---|---|---|
| Kết thúc |
.\r\n (dấu chấm trên một dòng riêng) |
Số byte rõ ràng + từ khóa LAST |
| Dot-stuffing | Bắt buộc | Không cần |
| Nội dung nhị phân | Phải mã hóa Base64 | Nhị phân thô với BINARYMIME |
| Truyền phát | Máy chủ quét tìm ký tự kết thúc | Máy chủ đọc số byte chính xác |
| Nhiều khối | Không áp dụng | Có, trạng thái trung gian sau mỗi khối |
Kích thước khối
Không có kích thước khối bắt buộc. Máy khách thường chọn kích thước khối dựa trên bộ nhớ khả dụng và điều kiện mạng. Các chiến lược phổ biến bao gồm gửi toàn bộ tin nhắn dưới dạng một BDAT ... LAST duy nhất, hoặc chia thành các khối có kích thước vài trăm kilobyte. Các khối nhỏ hơn cho phép phát hiện lỗi trung gian; các khối lớn hơn giảm overhead giao thức.
Phục hồi lỗi
Nếu máy chủ từ chối một khối BDAT (ví dụ: tin nhắn quá lớn), máy khách có thể phát hành BDAT 0 LAST để hủy giao dịch một cách sạch sẽ. Điều này sạch sẽ hơn mô hình DATA, nơi máy khách phải gửi toàn bộ tin nhắn và ký tự kết thúc dot ngay cả khi biết máy chủ sẽ từ chối nó.
Chuyển tiếp BINARYMIME
Một máy chủ nhận tin nhắn BINARYMIME không được chuyển tiếp nó tới máy chủ không hỗ trợ BINARYMIME. Nếu bước tiếp theo không quảng cáo BINARYMIME, máy chủ chuyển tiếp phải chuyển đổi các phần nội dung nhị phân thành mã hóa Base64 trước khi chuyển tiếp. Đây là yêu cầu khả năng tương tác quan trọng.
Những sai lầm phổ biến
-
Sử dụng BDAT mà không kiểm tra CHUNKING. Không phải tất cả máy chủ đều hỗ trợ CHUNKING. Luôn xác minh phản hồi EHLO trước khi sử dụng
BDAT. Nếu CHUNKING không được quảng cáo, quay lạiDATA. - Gửi BODY=BINARYMIME khi bước tiếp theo không hỗ trợ nó. Nếu bạn là máy chủ chuyển tiếp và MTA hạ lưu không quảng cáo BINARYMIME, bạn phải mã hóa lại các phần nhị phân thành Base64 trước khi chuyển tiếp. Gửi nhị phân thô tới máy chủ không hiểu nó làm hỏng tin nhắn.
-
Sai số lượng byte. Kích thước trong
BDATphải khớp chính xác với số octet theo sau. Gửi quá ít hoặc quá nhiều byte làm mất đồng bộ hóa giao thức và làm hỏng phiên. -
Quên từ khóa LAST. Khối
BDATcuối cùng phải bao gồmLAST. Nếu không, máy chủ chờ thêm các khối và phiên bị treo. -
Trộn BDAT và DATA. Máy khách phải sử dụng
DATAhoặcBDATcho một tin nhắn nhất định, không bao giờ cả hai. Chuyển đổi trong khi giao dịch diễn ra là lỗi giao thức. -
Không xử lý lỗi khối trung gian. Nếu khối
BDATkhông phải khối cuối cùng trả về lỗi, máy khách nên gửiBDAT 0 LASTđể đặt lại giao dịch thay vì tiếp tục gửi dữ liệu.
Tác động khả năng giao hàng
- Giảm băng thông cho tệp đính kèm nhị phân. BINARYMIME loại bỏ overhead 33% của mã hóa Base64. Đối với tệp đính kèm 10 MB, đó là tiết kiệm khoảng 3,3 MB dữ liệu truyền. Điều này quan trọng ở quy mô lớn.
- Xử lý nhanh hơn cho các tin nhắn lớn. BDAT với kích thước rõ ràng cho phép máy chủ cấp phát bộ nhớ trước và bỏ qua quét từng dòng. Điều này giảm overhead CPU ở cả hai bên.
- Xử lý lỗi sạch sẽ hơn. Phản hồi khối trung gian cho phép máy khách phát hiện sự cố sớm mà không cần truyền toàn bộ tin nhắn. Điều này tiết kiệm băng thông và thời gian kết nối khi tin nhắn sẽ bị từ chối.
- Hỗ trợ rộng rãi từ các nhà cung cấp lớn. Google, Microsoft và hầu hết các nền tảng thư lớn hỗ trợ CHUNKING. Sử dụng nó khi có sẵn là thực hành tốt nhất để giao hàng hiệu quả.
- Loại bỏ lỗi dot-stuffing. BDAT loại bỏ toàn bộ lớp các lỗi tiềm ẩn liên quan đến xử lý dot-stuffing và kết thúc dòng. Tin nhắn tới chính xác như đã gửi, byte-for-byte.