//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在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); } } }