public void TestSetParameter() { var builder = new MediaTypeBuilder(); builder.SetParameter("a", "b"); { string stringTemp = builder.ToMediaType().GetParameter("a"); Assert.AreEqual( "b", stringTemp); } builder.SetParameter("a", String.Empty); Assert.AreEqual(String.Empty, builder.ToMediaType().GetParameter("a")); try { builder.SetParameter(null, String.Empty); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetParameter(String.Empty, null); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetParameter(String.Empty, "a"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetParameter("a\u00e0", "a"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } }
public void TestMediaTypeBuilder() { MediaTypeBuilder builder; try { Assert.AreEqual(null, new MediaTypeBuilder(null)); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } builder = new MediaTypeBuilder("text", "plain"); try { builder.SetTopLevelType(null); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetParameter(null, "v"); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetParameter(null, null); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetParameter(String.Empty, "v"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetParameter("v", null); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetTopLevelType(String.Empty); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetTopLevelType("e="); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { builder.SetTopLevelType("e/e"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().SetSubType(null); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().RemoveParameter(null); Assert.Fail("Should have failed"); } catch (ArgumentNullException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().RemoveParameter(String.Empty); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().RemoveParameter("v"); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().SetSubType(String.Empty); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().SetSubType("x;y"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().SetSubType("x/y"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().SetParameter("x", String.Empty); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().SetParameter("x;y", "v"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } try { new MediaTypeBuilder().SetParameter("x/y", "v"); Assert.Fail("Should have failed"); } catch (ArgumentException) { new Object(); } catch (Exception ex) { Assert.Fail(ex.ToString()); throw new InvalidOperationException(String.Empty, ex); } }
private void Generate(IWriter output, int depth) { var haveMimeVersion = false; var haveContentEncoding = false; var haveContentType = false; var haveContentDisp = false; var haveMsgId = false; var haveFrom = false; var haveDate = false; var haveHeaders = new bool[11]; byte[] bodyToWrite = this.body; var builder = new MediaTypeBuilder(this.ContentType); string contentDisp = (this.ContentDisposition == null) ? null : this.ContentDisposition.ToString(); var transferEnc = 0; var isMultipart = false; string boundary = String.Empty; if (builder.IsMultipart) { boundary = GenerateBoundary(depth); builder.SetParameter("boundary", boundary); isMultipart = true; } if (!isMultipart) { if (builder.TopLevelType.Equals("message")) { if (builder.SubType.Equals("delivery-status") || builder.SubType.Equals("global-delivery-status")) { bodyToWrite = DowngradeDeliveryStatus(bodyToWrite); } bool msgCanBeUnencoded = CanBeUnencoded(bodyToWrite, depth > 0); if ((builder.SubType.Equals("rfc822") || builder.SubType.Equals( "news")) && !msgCanBeUnencoded) { builder.SetSubType("global"); } else if (builder.SubType.Equals("disposition-notification") && !msgCanBeUnencoded) { builder.SetSubType("global-disposition-notification"); } else if (builder.SubType.Equals("delivery-status") && !msgCanBeUnencoded) { builder.SetSubType("global-delivery-status"); } else if (!msgCanBeUnencoded && !builder.SubType.Equals("global") && !builder.SubType.Equals("global-disposition-notification") && !builder.SubType.Equals("global-delivery-status") && !builder.SubType.Equals("global-headers")) { #if DEBUG throw new MessageDataException("Message body can't be encoded: " + builder.ToString() + ", " + this.ContentType); #else { throw new MessageDataException("Message body can't be encoded"); } #endif } } } string topLevel = builder.TopLevelType; transferEnc = topLevel.Equals("message") || topLevel.Equals("multipart") ? (topLevel.Equals("multipart") || ( !builder.SubType.Equals("global") && !builder.SubType.Equals("global-headers") && !builder.SubType.Equals("global-disposition-notification") && !builder.SubType.Equals("global-delivery-status"))) ? EncodingSevenBit : TransferEncodingToUse( bodyToWrite, depth > 0) : TransferEncodingToUse(bodyToWrite, depth > 0); string encodingString = "7bit"; if (transferEnc == EncodingBase64) { encodingString = "base64"; } else if (transferEnc == EncodingQuotedPrintable) { encodingString = "quoted-printable"; } // Write the header fields for (int i = 0; i < this.headers.Count; i += 2) { string name = this.headers[i]; string value = this.headers[i + 1]; if (name.Equals("content-type")) { if (haveContentType) { // Already outputted, continue continue; } haveContentType = true; value = builder.ToString(); } if (name.Equals("content-disposition")) { if (haveContentDisp || contentDisp == null) { // Already outputted, continue continue; } haveContentDisp = true; value = contentDisp; } else if (name.Equals("content-transfer-encoding")) { if (haveContentEncoding) { // Already outputted, continue continue; } haveContentEncoding = true; value = encodingString; } else if (name.Equals("date")) { if (haveDate) { continue; } haveDate = true; } else if (name.Equals("from")) { if (haveFrom) { // Already outputted, continue continue; } haveFrom = true; } if ( depth > 0 && ( name.Length < 8 || !name.Substring( 0, 8).Equals("content-"))) { // don't generate header fields not starting with "Content-" // in body parts continue; } if (name.Equals("mime-version")) { haveMimeVersion = true; } else if (name.Equals("message-id")) { if (haveMsgId) { // Already outputted, continue continue; } haveMsgId = true; } else { if (ValueHeaderIndices.ContainsKey(name)) { int headerIndex = ValueHeaderIndices[name]; if (headerIndex < 9) { if (haveHeaders[headerIndex]) { // Already outputted, continue continue; } haveHeaders[headerIndex] = true; if (!this.IsValidAddressingField(name)) { value = GenerateAddressList( ParseAddresses(this.GetMultipleHeaders(name))); if (value.Length == 0) { // No addresses, synthesize a field value = this.SynthesizeField(name); } } } if (headerIndex == 9 || headerIndex == 10) { // Resent-From/Resent-Sender, can appear // more than once value = GenerateAddressList(ParseAddresses(value)); if (value.Length == 0) { // No addresses, synthesize a field value = this.SynthesizeField(name); } } } } string rawField = Capitalize(name) + ":" + (StartsWithWhitespace(value) ? String.Empty : " ") + value; if (CanOutputRaw(rawField)) { AppendAscii(output, rawField); if (rawField.IndexOf(": ", StringComparison.Ordinal) < 0) { throw new MessageDataException("No colon+space: " + rawField); } } else if (HasTextToEscape(value)) { string downgraded = HeaderFieldParsers.GetParser(name).DowngradeFieldValue(value); if ( HasTextToEscapeIgnoreEncodedWords( downgraded, 0, downgraded.Length)) { if (name.Equals("message-id") || name.Equals("resent-message-id") || name.Equals( "in-reply-to") || name.Equals("references") || name.Equals( "original-recipient") || name.Equals("final-recipient")) { // Header field still contains invalid characters (such // as non-ASCII characters in 7-bit messages), convert // to a downgraded field name = "downgraded-" + name; downgraded = Rfc2047.EncodeString(ParserUtility.TrimSpaceAndTab(value)); } else { #if DEBUG throw new MessageDataException("Header field still has non-Ascii or controls: " + name + " " + value); #else throw new MessageDataException( "Header field still has non-Ascii or controls"); #endif } } bool haveDquote = downgraded.IndexOf('"') >= 0; var encoder = new WordWrapEncoder(!haveDquote); encoder.AddString(Capitalize(name) + ": " + downgraded); string newValue = encoder.ToString(); AppendAscii(output, newValue); } else { bool haveDquote = value.IndexOf('"') >= 0; var encoder = new WordWrapEncoder(!haveDquote); encoder.AddString(Capitalize(name) + ": " + value); string newValue = encoder.ToString(); AppendAscii(output, newValue); } AppendAscii(output, "\r\n"); } if (!haveFrom && depth == 0) { // Output a synthetic From field if it doesn't // exist and this isn't a body part AppendAscii(output, "From: [email protected]\r\n"); } if (!haveDate && depth == 0) { AppendAscii(output, "Date: "); AppendAscii( output, GetDateString(DateTimeUtilities.GetCurrentLocalTime())); AppendAscii(output, "\r\n"); } if (!haveMsgId && depth == 0) { AppendAscii(output, "Message-ID:\r\n "); AppendAscii(output, this.GenerateMessageID()); AppendAscii(output, "\r\n"); } if (!haveMimeVersion && depth == 0) { AppendAscii(output, "MIME-Version: 1.0\r\n"); } if (!haveContentType) { AppendAscii(output, "Content-Type: " + builder + "\r\n"); } if (!haveContentEncoding) { AppendAscii( output, "Content-Transfer-Encoding: " + encodingString + "\r\n"); } ICharacterEncoder bodyEncoder = null; switch (transferEnc) { case EncodingBase64: bodyEncoder = new Base64Encoder(true, builder.IsText, false); break; case EncodingQuotedPrintable: bodyEncoder = new QuotedPrintableEncoder( builder.IsText ? 2 : 0, false); break; default: bodyEncoder = new IdentityEncoder(); break; } // Write the body AppendAscii(output, "\r\n"); if (!isMultipart) { var index = 0; while (true) { int c = (index >= bodyToWrite.Length) ? -1 : ((int)bodyToWrite[index++]) & 0xff; int count = bodyEncoder.Encode(c, output); if (count == -2) { throw new MessageDataException("encoding error"); } if (count == -1) { break; } } } else { foreach (Message part in this.Parts) { AppendAscii(output, "\r\n--" + boundary + "\r\n"); part.Generate(output, depth + 1); } AppendAscii(output, "\r\n--" + boundary + "--"); } }