//------------------------------------------------------------------------------ // 此代码版权(除特别声明或在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://touchsocket.net/ // 交流QQ群:234762506 // 感谢您的下载和使用 //------------------------------------------------------------------------------ using System; 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(); private static readonly byte[] m_rnrnCode = Encoding.UTF8.GetBytes("\r\n\r\n"); private readonly InternalHttpHeader m_headers; /// /// 构造函数 /// public HttpBase() { this.ReadTimeout = 1000 * 30; this.m_headers = new InternalHttpHeader(); } /// /// 能否写入。 /// public abstract bool CanWrite { get; } /// /// 客户端 /// public abstract ITcpClientBase Client { get; } /// /// 内容填充完成 /// public bool? ContentComplated { get; protected set; } = null; /// /// 内容长度 /// public long ContentLength { get { var contentLength = this.m_headers.Get(HttpHeaders.ContentLength); if (contentLength.IsNullOrEmpty()) { return 0; } if (long.TryParse(contentLength, out var value)) { return value; } return 0; } set { this.m_headers.Add(HttpHeaders.ContentLength, value.ToString()); } } /// /// 保持连接。 /// /// 一般的,当是http1.1时,如果没有显式的Connection: close,即返回true。当是http1.0时,如果没有显式的Connection: Keep-Alive,即返回false。 /// /// public bool KeepAlive { get { var keepalive = this.Headers.Get(HttpHeaders.Connection); if (this.ProtocolVersion == "1.0") { if (keepalive.IsNullOrEmpty()) { return false; } else { return keepalive.Equals("keep-alive", StringComparison.OrdinalIgnoreCase); } } else { if (keepalive.IsNullOrEmpty()) { return true; } else { return keepalive.Equals("keep-alive", StringComparison.OrdinalIgnoreCase); } } } set { if (this.ProtocolVersion == "1.0") { if (value) { this.m_headers.Add(HttpHeaders.Connection, "Keep-Alive"); } else { this.m_headers.Add(HttpHeaders.Connection, "close"); } } else { if (!value) { this.m_headers.Add(HttpHeaders.Connection, "close"); } } } } /// /// 内容类型 /// public string ContentType { get { return this.m_headers.Get(HttpHeaders.ContentType); } set { this.m_headers.Add(HttpHeaders.ContentType, value); } } /// /// 允许编码 /// public string AcceptEncoding { get { return this.m_headers.Get(HttpHeaders.AcceptEncoding); } set { this.m_headers.Add(HttpHeaders.AcceptEncoding, value); } } /// /// 可接受MIME类型 /// public string Accept { get { return this.m_headers.Get(HttpHeaders.Accept); } set { this.m_headers.Add(HttpHeaders.Accept, value); } } /// /// 传递标识 /// public object Flag { get; set; } /// /// 请求头集合 /// public IHttpHeader Headers { get { return this.m_headers; } } /// /// 协议名称,默认HTTP /// public Protocol Protocols { get; set; } = Protocol.Http; /// /// HTTP协议版本,默认1.1 /// public string ProtocolVersion { get; set; } = "1.1"; /// /// 请求行 /// public string RequestLine { get; private set; } /// /// /// /// /// /// public bool ParsingHeader(ByteBlock byteBlock, int length) { var index = byteBlock.Buffer.IndexOfFirst(byteBlock.Pos, length, m_rnrnCode); if (index > 0) { var headerLength = index - byteBlock.Pos; this.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) { var data = Encoding.UTF8.GetString(buffer, offset, length); var rows = Regex.Split(data, "\r\n"); //Request URL & Method & Version this.RequestLine = rows[0]; //Request Headers this.GetRequestHeaders(rows); this.LoadHeaderProterties(); } /// /// 设置一次性内容 /// /// /// public abstract void SetContent(byte[] content); /// /// 获取一次性内容。 /// /// 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 this.Input(buffer, offset, length); } /// /// /// /// protected override void Dispose(bool disposing) { if (!this.DisposedValue && this.CanRead) { this.TryGetContent(out _); } base.Dispose(disposing); } /// /// 读取信息 /// protected abstract void LoadHeaderProterties(); private void GetRequestHeaders(string[] rows) { this.m_headers.Clear(); if (rows == null || rows.Length <= 0) { return; } foreach (var item in rows) { var kv = item.SplitFirst(':'); if (kv.Length == 2) { var key = kv[0].ToLower(); this.m_headers.Add(key, kv[1]); } } } /// /// 重置Http状态。 /// public virtual void Reset() { base.ResetBlock(); this.m_headers.Clear(); this.ContentComplated = null; this.RequestLine = default; } } }