tesses.http/Tesses.Http/HttpExtensions.cs

152 lines
5.0 KiB
C#
Raw Normal View History

2022-08-22 17:30:32 +00:00
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Collections.Generic;
using System.Threading;
using System.Text;
namespace Tesses.Http
{
public static class Extensions
{
private static Lazy<Dictionary<int, string>> _statusCodeMap = new Lazy<Dictionary<int, string>>(() => new Dictionary<int, string>()
{
[202] = "Accepted",
[502] = "Bad Gateway",
[400] = "Bad Request",
[409] = "Conflict",
[100] = "Continue",
[201] = "Created",
[417] = "Expectation Failed",
[403] = "Forbidden",
[302] = "Found",
[504] = "Gateway Timeout",
[410] = "Gone",
[505] = "HTTP Version Not Supported",
[500] = "Internal Server Error",
[411] = "Length Required",
[405] = "Method Not Allowed",
[301] = "Moved Permanently",
[300] = "Multiple Choices",
[204] = "No Content",
[203] = "Non Authoritative Information",
[406] = "Not Acceptable",
[404] = "Not Found",
[501] = "Not Implemented",
[304] = "Not Modified",
[200] = "OK",
[206] = "Partial Content",
[402] = "Payment Required",
[412] = "Precondition Failed",
[407] = "Proxy Authentication Required",
[302] = "Redirect",
[307] = "Redirect Keep Verb",
[303] = "Redirect Method",
[416] = "Requested Range Not Satisfiable",
[413] = "Request Entry Too Large",
[408] = "Request Timeout",
[414] = "Request Uri Too Long",
[205] = "Reset Content",
[503] = "Service Unavailable",
[101] = "Switching Protocols",
[307] = "Temporary Redirect",
[401] = "Unauthorized",
[415] = "Unsupported Media Type",
[306] = "Unused",
[426] = "Upgrade Required",
[305] = "Use Proxy",
[429] = "Too Many Requests"
});
public static byte[] AsArray(this Stream strm,bool begin=true)
{
if(strm.Position != 0 && begin)
strm.Position=0;
byte[] data=new byte[strm.Length-strm.Position];
strm.Read(data,0,data.Length);
return data;
}
public static string AsString(this byte[] data)
{
return Encoding.UTF8.GetString(data);
}
public static string GetReasonPhrase(this StatusLine line)
{
string res;
if(_statusCodeMap.Value.TryGetValue(line.StatusCode,out res))
{
return res;
}
return "";
}
/// <summary>
/// StringBuilder ends with
/// </summary>
/// <param name="sb">string builder</param>
/// <param name="test">text to check</param>
/// <param name="comparison">comparison type</param>
/// <returns>true if sb ends with test, false if it does not</returns>
internal static bool EndsWith(this StringBuilder sb, string test,
StringComparison comparison)
{
if (sb.Length < test.Length)
return false;
string end = sb.ToString(sb.Length - test.Length, test.Length);
return end.Equals(test, comparison);
}
internal static string ReadHttpHeaders(this Stream strm)
{
StringBuilder s = new StringBuilder();
var decoder = Encoding.UTF8.GetDecoder();
var nextChar = new char[1];
while (!s.EndsWith("\r\n\r\n",StringComparison.Ordinal))
{
int data = strm.ReadByte();
if(data == -1)
{
break;
}
int charCount=decoder.GetChars(new byte[] { (byte)data }, 0, 1, nextChar, 0);
if (charCount == 0) continue;
s.Append(nextChar);
}
return s.ToString();
}
public static void Add<T1,T2>(this Dictionary<T1,List<T2>> headers,T1 key,T2 value)
{
if(!headers.ContainsKey(key))
{
headers.Add(key,new List<T2>());
}
headers[key].Add(value);
}
public static bool TryGetFirst<T1,T2>(this Dictionary<T1,List<T2>> headers,T1 key,out T2 value)
{
value=default(T2);
if(headers ==null) return false;
if(headers.ContainsKey(key) && headers[key] !=null && headers[key].Count > 0)
{
value=headers[key][0];
return true;
}
return false;
}
public static bool TryGetFirst<T>(this Dictionary<T,List<string>> headers,T key,out long value)
{
value=0;
string v;
return (headers.TryGetFirst(key,out v) && long.TryParse(v,out value));
}
}
}