处理来自 outlook 7 位编码的电子邮件会导致输出中出现有趣的字符
Processing email from outlook 7bit encoding causes funny characters in output
我正在进行一个项目,我正在构建自己的 SMTP 服务器。 (请不要问为什么或向我提供像 Postfix 这样的东西,我有我的理由)。
除了 Outlook 之外,它大部分工作正常,我从 Outlook 编码的数据编码似乎有一些问题。
我不断收到如下内容:
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" =
xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
而不是:
<html xmlns:v="urn:schemas-microsoft-com:vml" =
xmlns:o="urn:schemas-microsoft-com:office:office" =
xmlns:w="urn:schemas-microsoft-com:office:word" =
请注意,有效内容中没有 3D。
我有一个函数可以侦听 SMTP 数据的套接字,如下所示:
if (stream.CanRead)
{
byte[] serverData = new byte[1024];
StringBuilder stringBuilder = new StringBuilder();
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = stream.Read(serverData, 0, serverData.Length);
Encoding encoding = Encoding.GetEncoding("UTF-7", new FallbackEncoding(), new FallbackDecoding());
stringBuilder.AppendFormat("{0}", encoding.GetString(serverData, 0, numberOfBytesRead));
} while (stream.DataAvailable);
return stringBuilder.ToString();
在我的 FallbackDecoding 函数中,我有以下代码
class FallbackDecoding : DecoderFallback
{
public override int MaxCharCount
{
get
{
return 1;
}
}
public override DecoderFallbackBuffer CreateFallbackBuffer()
{
return new Buffer();
}
private class Buffer : DecoderFallbackBuffer
{
private int _fallbackIndex;
private string _fallbackString;
public override int Remaining
{
get
{
return _fallbackString.Length - _fallbackIndex;
}
}
public override bool Fallback(byte[] bytesUnknown, int index)
{
byte unknownChar = bytesUnknown[index];
_fallbackString = Encoding.ASCII.GetString(new[] { (byte)(unknownChar & 127) });
_fallbackIndex = 0;
return true;
}
public override char GetNextChar()
{
if (Remaining > 0)
{
return _fallbackString[_fallbackIndex++];
}
else
{
return '[=13=]';
}
}
public override bool MovePrevious()
{
if (_fallbackIndex > 0)
{
_fallbackIndex--;
return true;
}
return false;
}
}
由于某种原因,解码器回退 class 在函数 public override bool Fallback
中抛出异常。它抛出一个异常,因为 bytesunknown
在数组中只有 1 个项目,但是 index
参数是 128 所以它抛出一个索引超出范围异常但我不知道为什么。
我试过将 ASCII 更改为 UTF-7,因为 Outlook 以 7 位发送数据,但似乎没有任何区别。
由于我收到的电子邮件中的 HTML,当我传递电子邮件时,格式错误,有时我会在电子邮件中收到垃圾。
更新
完整的电子邮件 headers 按要求
Message-ID: <000d01d0dc52[=14=]c0d469027d3b0$@chrisboard.co.uk>
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_NextPart_000_000E_01D0DC5A.6DD24AD0"
X-Mailer: Microsoft Outlook 15.0
Thread-Index: AdDcUeHbbPyOUTipQ462DEYroR+DWg==
Content-Language: en-gb
This is a multipart message in MIME format.
------=_NextPart_000_000E_01D0DC5A.6DD24AD0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
This is the content of the message
------=_NextPart_000_000E_01D0DC5A.6DD24AD0
Content-Type: text/html;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" =
xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" =
xmlns=3D"http://www.w3.o
带长行和 =
的可打印引用和 ASCII 文本
html 附件使用 quoted-printable encoding 编码。 Quoted-printable 使用以 =
开头的特殊 3 字节序列。引用的可打印代码将 =
编码为 =3D
。它是唯一必须编码的可打印 ascii 字符 (33-126)。
行尾的 BTW =
也是 quoted-printable
编码的产物。它 "breaks" 排长队。
我正在进行一个项目,我正在构建自己的 SMTP 服务器。 (请不要问为什么或向我提供像 Postfix 这样的东西,我有我的理由)。
除了 Outlook 之外,它大部分工作正常,我从 Outlook 编码的数据编码似乎有一些问题。
我不断收到如下内容:
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" =
xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
而不是:
<html xmlns:v="urn:schemas-microsoft-com:vml" =
xmlns:o="urn:schemas-microsoft-com:office:office" =
xmlns:w="urn:schemas-microsoft-com:office:word" =
请注意,有效内容中没有 3D。
我有一个函数可以侦听 SMTP 数据的套接字,如下所示:
if (stream.CanRead)
{
byte[] serverData = new byte[1024];
StringBuilder stringBuilder = new StringBuilder();
int numberOfBytesRead = 0;
do
{
numberOfBytesRead = stream.Read(serverData, 0, serverData.Length);
Encoding encoding = Encoding.GetEncoding("UTF-7", new FallbackEncoding(), new FallbackDecoding());
stringBuilder.AppendFormat("{0}", encoding.GetString(serverData, 0, numberOfBytesRead));
} while (stream.DataAvailable);
return stringBuilder.ToString();
在我的 FallbackDecoding 函数中,我有以下代码
class FallbackDecoding : DecoderFallback
{
public override int MaxCharCount
{
get
{
return 1;
}
}
public override DecoderFallbackBuffer CreateFallbackBuffer()
{
return new Buffer();
}
private class Buffer : DecoderFallbackBuffer
{
private int _fallbackIndex;
private string _fallbackString;
public override int Remaining
{
get
{
return _fallbackString.Length - _fallbackIndex;
}
}
public override bool Fallback(byte[] bytesUnknown, int index)
{
byte unknownChar = bytesUnknown[index];
_fallbackString = Encoding.ASCII.GetString(new[] { (byte)(unknownChar & 127) });
_fallbackIndex = 0;
return true;
}
public override char GetNextChar()
{
if (Remaining > 0)
{
return _fallbackString[_fallbackIndex++];
}
else
{
return '[=13=]';
}
}
public override bool MovePrevious()
{
if (_fallbackIndex > 0)
{
_fallbackIndex--;
return true;
}
return false;
}
}
由于某种原因,解码器回退 class 在函数 public override bool Fallback
中抛出异常。它抛出一个异常,因为 bytesunknown
在数组中只有 1 个项目,但是 index
参数是 128 所以它抛出一个索引超出范围异常但我不知道为什么。
我试过将 ASCII 更改为 UTF-7,因为 Outlook 以 7 位发送数据,但似乎没有任何区别。
由于我收到的电子邮件中的 HTML,当我传递电子邮件时,格式错误,有时我会在电子邮件中收到垃圾。
更新
完整的电子邮件 headers 按要求
Message-ID: <000d01d0dc52[=14=]c0d469027d3b0$@chrisboard.co.uk>
MIME-Version: 1.0
Content-Type: multipart/alternative;
boundary="----=_NextPart_000_000E_01D0DC5A.6DD24AD0"
X-Mailer: Microsoft Outlook 15.0
Thread-Index: AdDcUeHbbPyOUTipQ462DEYroR+DWg==
Content-Language: en-gb
This is a multipart message in MIME format.
------=_NextPart_000_000E_01D0DC5A.6DD24AD0
Content-Type: text/plain;
charset="us-ascii"
Content-Transfer-Encoding: 7bit
This is the content of the message
------=_NextPart_000_000E_01D0DC5A.6DD24AD0
Content-Type: text/html;
charset="us-ascii"
Content-Transfer-Encoding: quoted-printable
<html xmlns:v=3D"urn:schemas-microsoft-com:vml" =
xmlns:o=3D"urn:schemas-microsoft-com:office:office" =
xmlns:w=3D"urn:schemas-microsoft-com:office:word" =
xmlns:m=3D"http://schemas.microsoft.com/office/2004/12/omml" =
xmlns=3D"http://www.w3.o
带长行和 =
的可打印引用和 ASCII 文本
html 附件使用 quoted-printable encoding 编码。 Quoted-printable 使用以 =
开头的特殊 3 字节序列。引用的可打印代码将 =
编码为 =3D
。它是唯一必须编码的可打印 ascii 字符 (33-126)。
BTW =
也是 quoted-printable
编码的产物。它 "breaks" 排长队。