// /** // * File: Header.cs // * Author: haraldwolff // * // * This file and it's content is copyrighted by the Author and / or copyright holder. // * Any use wihtout proper permission is illegal and may lead to legal actions. // * // * // **/ using System; using System.Collections.Generic; using System.IO; using System.Text; using System.Linq; using System.Net.Sockets; namespace ln.http.message { public class Header { public string Name { get; } string rawvalue; public string RawValue { get => rawvalue; set => SetValue(value); } string comments; public string Comments => comments; string value; public string Value { get => value; set => SetValue(value); } Dictionary parameters; public Header(string headerLine) { int colon = headerLine.IndexOf(':'); if (colon == -1) throw new FormatException("expected to find :"); Name = headerLine.Substring(0, colon).ToUpper(); SetValue(headerLine.Substring(colon + 1)); } public Header(string name, string value) { Name = name.ToUpper(); SetValue(value); } public void SetValue(string newValue) { rawvalue = newValue; value = ParseValue(new StringReader(newValue.Trim()),out comments); // at least MIME Content-* header follow the parameter syntax... if (Name.StartsWith("CONTENT-", StringComparison.InvariantCulture)) { ParseParameters(); } } public bool ContainsParameter(string parameterName) => parameters.ContainsKey(parameterName.ToUpper()); public string GetParameter(string parameterName) => parameters[parameterName.ToUpper()]; public string GetParameter(string parameterName,string defaultValue) => parameters[parameterName.ToUpper()]; string ParseComment(TextReader reader) { StringBuilder commentBuilder = new StringBuilder(); ParseComment(reader, commentBuilder); return commentBuilder.ToString(); } void ParseComment(TextReader reader,StringBuilder commentBuilder) { int ch; while (((ch = reader.Read()) != -1) && (ch != ')')) commentBuilder.Append((char)ch); } public virtual string ParseValue(TextReader reader,out string parsedComments) { StringBuilder stringBuilder = new StringBuilder(); StringBuilder commentBuilder = new StringBuilder(); int ch; while (((ch = reader.Read())!=-1)) { if (ch == '(') { commentBuilder.Append(ParseComment(reader)); } else { stringBuilder.Append((char)ch); } } parsedComments = commentBuilder.ToString().Trim(); return stringBuilder.ToString().Trim(); } public void ParseParameters() { if (parameters != null) return; parameters = new Dictionary(); int semicolon = value.IndexOf(';'); if (semicolon > 0) { TokenReader tokenReader = new TokenReader(new StringReader(value.Substring(semicolon))); while (tokenReader.Peek() != -1) { if (tokenReader.Read() != ';') throw new FormatException(); string pName = tokenReader.ReadToken().ToUpper(); if (tokenReader.Read() != '=') throw new FormatException("expected ="); string pValue = (tokenReader.Peek() == '"') ? tokenReader.ReadQuotedString() : tokenReader.ReadToken(); parameters.Add(pName, pValue); } value = value.Substring(0, semicolon).Trim(); } } //void parseValue(string v) //{ // rawValue = v; // TokenReader tokenReader = new TokenReader(parseComments(new StringReader(v))); // StringBuilder stringBuilder = new StringBuilder(); // int ch; // while (((ch = tokenReader.Read()) != -1) && (ch != ';')) // stringBuilder.Append((char)ch); // Value = stringBuilder.ToString(); // while (tokenReader.Peek() != -1) // { // string pName = tokenReader.ReadToken(); // if (tokenReader.Read() != '=') // throw new FormatException("expected ="); // string pValue = (tokenReader.Peek() == '"') ? tokenReader.ReadQuotedString() : tokenReader.ReadToken(); // parameters.Add(pName, pValue); // } //} public override int GetHashCode() => Name.GetHashCode(); public override bool Equals(object obj) => (obj is Header you) && Name.Equals(you.Name); } }