/// <summary> /// Parses a the value for the header Content-Type to /// a <see cref="ContentType"/> object. /// </summary> /// <param name="headerValue">The value to be parsed</param> /// <returns>A <see cref="ContentType"/> object</returns> /// <exception cref="ArgumentNullException">If <paramref name="headerValue"/> is <see langword="null"/></exception> public static ContentType ParseContentType(string headerValue) { if (headerValue == null) { throw new ArgumentNullException("headerValue"); } // We create an empty Content-Type which we will fill in when we see the values ContentType contentType = new ContentType(); // Now decode the parameters List <KeyValuePair <string, string> > parameters = Rfc2231Decoder.Decode(headerValue); bool setMediaType = false; foreach (KeyValuePair <string, string> keyValuePair in parameters) { string key = keyValuePair.Key.ToUpperInvariant().Trim(); string value = keyValuePair.Value.Trim().RemoveQuotesIfAny(); switch (key) { case "": // This is the MediaType - it has no key since it is the first one mentioned in the // headerValue and has no = in it. if (!setMediaType) { // Check for illegal content-type string v = value.ToUpperInvariant(); if (v.Equals("TEXT") || v.Equals("TEXT/")) { value = "text/plain"; } contentType.MediaType = cleanMediaType(value); //Have now set the media type, ignore any later entries without a key (see #21) setMediaType = true; } else { //DefaultLogger.Log.LogDebug("Multiple values without a key in the Content Type header. Only the first will get used as the media type"); } break; case "BOUNDARY": contentType.Boundary = value; break; case "CHARSET": contentType.CharSet = value; break; case "NAME": contentType.Name = EncodedWord.Decode(value); break; default: // This is to shut up the code help that is saying that contentType.Parameters // can be null - which it cant! if (contentType.Parameters == null) { throw new Exception( "The ContentType parameters property is null. This will never be thrown."); } // We add the unknown value to our parameters list // "Known" unknown values are: // - title // - report-type contentType.Parameters.Add(key, value); break; } } return(contentType); }
/// <summary> /// Parses a the value for the header Content-Disposition to a <see cref="ContentDisposition"/> object. /// </summary> /// <param name="headerValue">The value to be parsed</param> /// <returns>A <see cref="ContentDisposition"/> object</returns> /// <exception cref="ArgumentNullException">If <paramref name="headerValue"/> is <see langword="null"/></exception> public static ContentDisposition ParseContentDisposition(string headerValue) { if (headerValue == null) { throw new ArgumentNullException("headerValue"); } // See http://www.ietf.org/rfc/rfc2183.txt for RFC definition // Create empty ContentDisposition - we will fill in details as we read them ContentDisposition contentDisposition = new ContentDisposition(); // Now decode the parameters List <KeyValuePair <string, string> > parameters = Rfc2231Decoder.Decode(headerValue); foreach (KeyValuePair <string, string> keyValuePair in parameters) { string key = keyValuePair.Key.ToUpperInvariant().Trim(); string value = keyValuePair.Value.Trim().RemoveQuotesIfAny(); switch (key) { case "": // This is the DispisitionType - it has no key since it is the first one // and has no = in it. contentDisposition.DispositionType = value; break; // The correct name of the parameter is filename, but some emails also contains the parameter // name, which also holds the name of the file. Therefore we use both names for the same field. case "NAME": case "FILENAME": // The filename might be in qoutes, and it might be encoded-word encoded contentDisposition.FileName = EncodedWord.Decode(value); break; case "CREATION-DATE": // Notice that we need to create a new DateTime because of a failure in .NET 2.0. // The failure is: you cannot give contentDisposition a DateTime with a Kind of UTC // It will set the CreationDate correctly, but when trying to read it out it will throw an exception. // It is the same with ModificationDate and ReadDate. // This is fixed in 4.0 - maybe in 3.0 too. // Therefore we create a new DateTime which have a DateTimeKind set to unspecified DateTime creationDate = new DateTime(Rfc2822DateTime.StringToDate(value).Ticks); contentDisposition.CreationDate = creationDate; break; case "MODIFICATION-DATE": DateTime midificationDate = new DateTime(Rfc2822DateTime.StringToDate(value).Ticks); contentDisposition.ModificationDate = midificationDate; break; case "READ-DATE": DateTime readDate = new DateTime(Rfc2822DateTime.StringToDate(value).Ticks); contentDisposition.ReadDate = readDate; break; case "SIZE": contentDisposition.Size = SizeParser.Parse(value); break; case "CHARSET": // ignoring invalid parameter in Content-Disposition break; default: if (key.StartsWith("X-")) { contentDisposition.Parameters.Add(key, value); break; } throw new ArgumentException( "Unknown parameter in Content-Disposition. Ask developer to fix! Parameter: " + key); } } return(contentDisposition); }