//------------------------------------------------------------------------------
// 此代码版权(除特别声明或在XREF结尾的命名空间的代码)归作者本人若汝棋茗所有
// 源代码使用协议遵循本仓库的开源协议及附加协议,若本仓库没有设置,则按MIT开源协议授权
// CSDN博客:https://blog.csdn.net/qq_40374647
// 哔哩哔哩视频:https://space.bilibili.com/94253567
// Gitee源代码仓库:https://gitee.com/RRQM_Home
// Github源代码仓库:https://github.com/RRQM
// API首页:https://www.yuque.com/rrqm/touchsocket/index
// 交流QQ群:234762506
// 感谢您的下载和使用
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using TouchSocket.Core;
using TouchSocket.Sockets;
namespace TouchSocket.Http
{
///
/// Http基础头部
///
public abstract class HttpBase : BlockReader, IRequestInfo
{
///
/// 服务器版本
///
public static readonly string ServerVersion = Assembly.GetExecutingAssembly().GetName().Version.ToString();
///
/// 内容长度
///
protected long m_contentLength;
private static readonly byte[] m_rnrnCode = Encoding.UTF8.GetBytes("\r\n\r\n");
private IgnoreCaseNameValueCollection m_headers;
///
/// 构造函数
///
public HttpBase()
{
ReadTimeout = 1000 * 30;
}
///
/// 能否写入。
///
public abstract bool CanWrite { get; }
///
/// 客户端
///
public abstract ITcpClientBase Client { get; }
///
/// 内容填充完成
///
public bool? ContentComplated { get; protected set; } = null;
///
/// int类型,内容长度
///
public int ContentLen
{
get => (int)m_contentLength;
set => m_contentLength = value;
}
///
/// 内容长度
///
public long ContentLength
{
get => m_contentLength;
set => m_contentLength = value;
}
///
/// 内容类型
///
public string ContentType { get; set; }
///
/// 传递标识
///
public object Flag { get; set; }
///
/// 请求头集合
///
public IgnoreCaseNameValueCollection Headers
{
get
{
m_headers ??= new IgnoreCaseNameValueCollection();
return m_headers;
}
}
///
/// 协议名称,默认HTTP
///
public string Protocols { get; set; } = "HTTP";
///
/// HTTP协议版本,默认1.1
///
public string ProtocolVersion { get; set; } = "1.1";
///
/// 请求行
///
public string RequestLine { get; private set; }
///
/// 获取头值
///
///
///
public string GetHeader(string fieldName)
{
return GetHeaderByKey(fieldName);
}
///
/// 获取头集合的值
///
///
///
public string GetHeader(HttpHeaders header)
{
var fieldName = header.GetDescription();
if (fieldName == null) return null;
return Headers.Get(fieldName);
}
///
///
///
///
///
///
public bool ParsingHeader(ByteBlock byteBlock, int length)
{
int index = byteBlock.Buffer.IndexOfFirst(byteBlock.Pos, length, m_rnrnCode);
if (index > 0)
{
int headerLength = index - byteBlock.Pos;
ReadHeaders(byteBlock.Buffer, byteBlock.Pos, headerLength);
byteBlock.Pos += headerLength;
return true;
}
else
{
return false;
}
}
///
/// 从Request中持续读取数据。
///
///
///
///
///
public override int Read(byte[] buffer, int offset, int count)
{
return base.Read(buffer, offset, count);
}
///
/// 从内存中读取
///
///
///
///
public void ReadHeaders(byte[] buffer, int offset, int length)
{
string data = Encoding.UTF8.GetString(buffer, offset, length);
string[] rows = Regex.Split(data, "\r\n");
//Request URL & Method & Version
RequestLine = rows[0];
//Request Headers
GetRequestHeaders(rows);
long.TryParse(GetHeader(HttpHeaders.ContentLength), out m_contentLength);
LoadHeaderProterties();
}
///
/// 设置一次性内容
///
///
///
public abstract void SetContent(byte[] content);
///
/// 设置请求头
///
///
///
public HttpBase SetHeaderByKey(string fieldName, string value)
{
if (string.IsNullOrEmpty(fieldName)) return this;
Headers.Add(fieldName, value);
return this;
}
///
/// 获取一次性内容。
///
///
public abstract bool TryGetContent(out byte[] content);
///
/// 持续写入内容。
///
///
///
///
public abstract void WriteContent(byte[] buffer, int offset, int count);
internal bool InternalInput(byte[] buffer, int offset, int length)
{
return Input(buffer, offset, length);
}
///
///
///
///
protected override void Dispose(bool disposing)
{
if (!DisposedValue && CanRead)
{
TryGetContent(out _);
}
base.Dispose(disposing);
}
///
/// 读取信息
///
protected abstract void LoadHeaderProterties();
private string GetHeaderByKey(string fieldName)
{
if (string.IsNullOrEmpty(fieldName)) return null;
return Headers.Get(fieldName);
}
private void GetRequestHeaders(IEnumerable rows)
{
if (rows == null || rows.Count() <= 0)
{
return;
}
foreach (var item in rows)
{
string[] kv = item.SplitFirst(':');
if (kv.Length == 2)
{
string key = kv[0].ToLower();
Headers.Add(key, kv[1]);
}
}
ContentType = GetHeader(HttpHeaders.ContentType);
}
}
}