3 ms·
> No prefixed length means two terrible things, an EOF signal of some kind but especially a way to quote such EOF in case it is present in the data part itself.
by u801e 6y ago
> No prefixed length means two terrible things, an EOF signal of some kind but especially a way to quote such EOF in case it is present in the data part itself.
For SMTP and NNTP messages, a CRLF.CRLF terminator is used to indicate the end of the message. If the message itself contains a line that started with a ., then the client would prefix that line with another . (dot-stuffing). The receiver on the other end would remove the extra dots from the line before storing the message. So, quoting part of the EOF is one viable solution and doesn't result in too much overhead in those cases.
- antirez 6y agoUnfortunately that's a lot of overhead: you want to read an email as a whole blob of data, not splitting it by lines (that is effectively processing every byte) just to tell if there is a ".." prefix.
- u801e 6y agoWhat I do in perl is to set the line terminator to CRLF.CRLF, read from the socket into a buffer, and then try to read a line (where a line is now defined as something that ends in CRLF.CRLF) from the buffer and check whether it ends in the terminator. Once I've read the data including the line terminator into the buffer, I run a s|\r\n\.{2}|\r\n.|g on the buffer and then write it to disk. Though it does consume more memory since I have to store the message in a buffer, it doesn't involve splitting the string line by line. It just processes the entire email message at once. With a size prefix, I would still have to read into a buffer and check its size to see whether I've read enough data. Though checking the length of a string or size of a file involves less work compared to checking for a line terminator and removing the dot-stuffing, if the amount of data we're dealing with is not large, then there probably isn't really that much difference in the amount of work done for those checks.