269 lines
8.2 KiB
C#
269 lines
8.2 KiB
C#
using System;
|
|
using System.Collections;
|
|
using System.Collections.Generic;
|
|
using System.Globalization;
|
|
using System.IO;
|
|
using System.Text;
|
|
|
|
namespace ln.http
|
|
{
|
|
public class HeaderContainer : IEnumerable<Header>
|
|
{
|
|
private Dictionary<string, Header> _headers = new Dictionary<string, Header>();
|
|
|
|
public HeaderContainer()
|
|
{
|
|
}
|
|
public HeaderContainer(IEnumerable<Header> headers)
|
|
{
|
|
foreach (var header in headers)
|
|
Add(new Header(header));
|
|
}
|
|
|
|
public HeaderContainer(Stream stream)
|
|
{
|
|
Read(stream);
|
|
}
|
|
|
|
public string this[string headerName]
|
|
{
|
|
get => Get(headerName);
|
|
set => Set(headerName, value);
|
|
}
|
|
|
|
public bool TryGetHeader(string headerName, out Header header) =>
|
|
_headers.TryGetValue(headerName.ToLower(), out header);
|
|
|
|
public bool TryGetValue(string headerName, out string headerValue)
|
|
{
|
|
if (_headers.TryGetValue(headerName.ToLower(), out Header header))
|
|
{
|
|
headerValue = header.Value;
|
|
return true;
|
|
}
|
|
|
|
headerValue = null;
|
|
return false;
|
|
}
|
|
|
|
public bool Contains(string headerName) => _headers.ContainsKey(headerName.ToLower());
|
|
|
|
public void Add(string headerName, string headerValue)
|
|
{
|
|
string lowerHeaderName = headerName.ToLower();
|
|
if (_headers.TryGetValue(lowerHeaderName, out Header header))
|
|
header.Value += " " + headerValue;
|
|
else
|
|
_headers.Add(lowerHeaderName, new Header(headerName, headerValue));
|
|
}
|
|
|
|
public void Add(Header header) => Add(header.Name, header.Value);
|
|
|
|
public void Remove(string headerName) => _headers.Remove(headerName.ToLower());
|
|
public void Clear() => _headers.Clear();
|
|
|
|
public void Set(string headerName, String headerValue)
|
|
{
|
|
string lowerHeaderName = headerName.ToLower();
|
|
if (!_headers.TryGetValue(lowerHeaderName, out Header header))
|
|
{
|
|
header = new Header(headerName, "");
|
|
_headers.Add(lowerHeaderName, header);
|
|
}
|
|
|
|
header.Value = headerValue;
|
|
}
|
|
|
|
public string Get(string headerName) => Get(headerName, null);
|
|
public string Get(string headerName, string defaultValue)
|
|
{
|
|
if (TryGetHeader(headerName, out Header header))
|
|
return header.Value;
|
|
return defaultValue;
|
|
}
|
|
|
|
public int GetInteger(string headerName)
|
|
{
|
|
return int.Parse(Get(headerName));
|
|
}
|
|
|
|
public int GetInteger(string headerName, int defaultValue)
|
|
{
|
|
if (TryGetValue(headerName, out string headerValue))
|
|
return int.Parse(headerValue);
|
|
return defaultValue;
|
|
}
|
|
|
|
public bool TryGetInteger(string headerName, out int value)
|
|
{
|
|
value = 0;
|
|
return TryGetValue(headerName, out string headerValue) && int.TryParse(headerValue, out value);
|
|
}
|
|
|
|
public float GetFloat(string headerName)
|
|
{
|
|
return float.Parse(Get(headerName));
|
|
}
|
|
|
|
public float GetFloat(string headerName, float defaultValue)
|
|
{
|
|
if (TryGetValue(headerName, out string headerValue))
|
|
return float.Parse(headerValue);
|
|
return defaultValue;
|
|
}
|
|
|
|
public bool TryGetFloat(string headerName, out float value)
|
|
{
|
|
value = 0;
|
|
return TryGetValue(headerName, out string headerValue) && float.TryParse(headerValue, out value);
|
|
}
|
|
|
|
|
|
public double GetDouble(string headerName)
|
|
{
|
|
return double.Parse(Get(headerName));
|
|
}
|
|
|
|
public double GetDouble(string headerName, double defaultValue)
|
|
{
|
|
if (TryGetValue(headerName, out string headerValue))
|
|
return double.Parse(headerValue);
|
|
return defaultValue;
|
|
}
|
|
|
|
public bool TryGetDouble(string headerName, out double value)
|
|
{
|
|
value = 0;
|
|
return TryGetValue(headerName, out string headerValue) && double.TryParse(headerValue, out value);
|
|
}
|
|
|
|
public IEnumerator<Header> GetEnumerator() => _headers.Values.GetEnumerator();
|
|
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
|
|
|
|
public override string ToString()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
foreach (var header in _headers)
|
|
sb.AppendFormat("{0}: {1}\r\n", header.Value.Name, header.Value.Value);
|
|
return sb.ToString();
|
|
}
|
|
|
|
public void Read(Stream stream)
|
|
{
|
|
string headerName = null;
|
|
string headerLine;
|
|
while (!String.Empty.Equals(headerLine = HttpConnection.ReadLine(stream)))
|
|
{
|
|
int colon = headerLine.IndexOf(':', StringComparison.InvariantCulture);
|
|
if (char.IsWhiteSpace(headerLine[0]))
|
|
{
|
|
if (headerName is string)
|
|
Add(headerName, " " + headerLine.Substring(1).Trim());
|
|
else
|
|
throw new FormatException("expected header name");
|
|
}
|
|
else if (colon > 0)
|
|
{
|
|
headerName = headerLine.Substring(0, colon).Trim();
|
|
Add(headerName, headerLine.Substring(colon + 1).Trim());
|
|
}
|
|
}
|
|
}
|
|
|
|
public void CopyTo(Stream stream)
|
|
{
|
|
foreach (var header in _headers.Values)
|
|
{
|
|
byte[] bytes = Encoding.ASCII.GetBytes($"{header.Name}: {header.Value}\r\n");
|
|
stream.Write(bytes, 0, bytes.Length);
|
|
}
|
|
stream.Write(new byte[] { 0x0d, 0x0a }, 0, 2);
|
|
}
|
|
|
|
}
|
|
|
|
public class Header
|
|
{
|
|
private string _name;
|
|
private Dictionary<string, string> _parameters;
|
|
|
|
public string Name
|
|
{
|
|
get => _name;
|
|
set
|
|
{
|
|
_name = value;
|
|
UpperName = value.ToUpper();
|
|
}
|
|
}
|
|
|
|
public string UpperName { get; private set; }
|
|
public string Value { get; set; }
|
|
|
|
|
|
public Header(string headerName)
|
|
{
|
|
Name = headerName;
|
|
Value = String.Empty;
|
|
}
|
|
|
|
public Header(string headerName, string headerValue)
|
|
{
|
|
Name = headerName;
|
|
Value = headerValue;
|
|
}
|
|
|
|
public Header(Header src)
|
|
{
|
|
Name = src.Name;
|
|
Value = src.Value;
|
|
}
|
|
|
|
public bool TryGetParameter(string parameterName, out string parameterValue)
|
|
{
|
|
if (_parameters is null)
|
|
ParseParameters();
|
|
|
|
return _parameters.TryGetValue(parameterName, out parameterValue);
|
|
}
|
|
public bool ContainsParameter(string parameterName)
|
|
{
|
|
if (_parameters is null)
|
|
ParseParameters();
|
|
|
|
return _parameters.ContainsKey(parameterName);
|
|
}
|
|
|
|
public Header ParseParameters()
|
|
{
|
|
_parameters = new Dictionary<string, string>();
|
|
|
|
int idxSemicolon = Value.IndexOf(';');
|
|
if (idxSemicolon != -1)
|
|
{
|
|
string[] ptoks = Value.Split(';');
|
|
|
|
foreach (string ptok in ptoks)
|
|
{
|
|
int idxEqual = ptok.IndexOf('=');
|
|
string pn, pv;
|
|
if (idxEqual != -1)
|
|
{
|
|
pn = ptok.Substring(0, idxEqual).Trim();
|
|
pv = ptok.Substring(idxEqual + 1);
|
|
}
|
|
else
|
|
{
|
|
pn = ptok.Trim();
|
|
pv = "";
|
|
}
|
|
|
|
_parameters.Add(pn, pv);
|
|
}
|
|
}
|
|
return this;
|
|
}
|
|
|
|
public override string ToString() => String.Format("{0}: {1}", Name, Value);
|
|
}
|
|
} |