#if NETCORE using Microsoft.AspNetCore.Http; using System; using System.Collections.Generic; using System.IO; using System.Text; namespace Apewer.Web { /// 用于网站的服务程序。 public class AspNetCoreProvider : ApiProvider { private HttpContext context; private HttpRequest request; private HttpResponse response; /// 创建服务程序实例。 /// public AspNetCoreProvider(HttpContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); this.context = context; request = context.Request; response = context.Response; } #region Implement /// 调用前的检查,返回错误信息。 public override string PreInvoke() { return null; } /// 读取请求前的检查,返回错误信息。 public override string PreRead() { return null; } /// 写入响应前的检查,返回错误信息。 public override string PreWrite() { return null; } /// 结束本次请求和响应。 public override void End() { } /// 释放非托管资源。 public override void Dispose() { } #endregion #region Request /// 获取 HTTP 方法。 public override Network.HttpMethod GetMethod() => ApiUtility.Method(request.Method); /// 获取客户端的 IP 地址。 public override string GetClientIP() => request.HttpContext.Connection.RemoteIpAddress.ToString(); /// 获取请求的 URL。 public override Uri GetUrl() { var https = request.IsHttps; var port = context.Connection.LocalPort; var query = request.QueryString == null ? null : request.QueryString.Value; var sb = new StringBuilder(); sb.Append(https ? "https://" : "http://"); sb.Append(request.Host.Host ?? ""); if ((https && port != 443) || (!https && port != 80)) { sb.Append(":"); sb.Append(port); } sb.Append(request.Path); if (!string.IsNullOrEmpty(query)) { if (!query.StartsWith("?")) sb.Append("?"); sb.Append(query); } var url = sb.ToString(); var uri = new Uri(url); return uri; } /// 获取请求的 Referrer。 public override string GetReferrer() => null; /// 获取请求的头。 public override StringPairs GetHeaders() { var headers = request.Headers; var sp = new StringPairs(); if (headers == null) return sp; foreach (var key in headers.Keys) { if (string.IsNullOrEmpty(key)) continue; try { var value = headers[key]; if (string.IsNullOrEmpty(value)) continue; sp.Add(key, value); } catch { } } return sp; } /// 获取请求的内容类型。 public override string GetContentType() => request.ContentType; /// 获取请求的内容长度。 public override long GetContentLength() => request.ContentLength ?? -1L; /// 获取请求的内容。 public override Stream RequestBody() => request.Body; #endregion #region Response /// 设置 HTTP 状态。 public override void SetStatus(string status) => response.StatusCode = Convert.ToInt32(status); /// 设置响应的头。 public override string SetHeader(string name, string value) { try { response.Headers.Add(name, value); } catch (Exception ex) { return ex.Message; } return null; } /// 设置响应的缓存秒数,设置为 0 即不允许缓存。 public override void SetCache(int seconds) { if (seconds > 0) { SetHeader("Cache-Control", $"public, max-age={seconds}, s-maxage={seconds}"); } else { SetHeader("Cache-Control", "no-cache, no-store, must-revalidate"); SetHeader("Pragma", "no-cache"); } } /// 设置响应的缓存秒数。 public override void SetContentType(string value) => response.ContentType = value; /// 设置响应的内容长度。 public override void SetContentLength(long value) => response.ContentLength = value; /// 设置响应重定向。 public override void SetRedirect(string location) => SetRedirect(location, false); /// 获取 Response 流。 public override Stream ResponseBody() => response.Body; #endregion #region This /// 将客户端重新定向到新 URL。 /// 默认响应 302 状态。可指定 permanent = true 以响应 301 状态。 public void SetRedirect(string location, bool permanent = false) { try { response.Redirect(location, permanent); } catch { } } private static void Async(Stream source, Stream destination, Func progress = null, int buffer = 4096, Action after = null) { if (source == null || !source.CanRead || destination == null || !destination.CanWrite) { after?.Invoke(); return; } Async(source, destination, progress, buffer, after, 0L); } private static void Async(Stream source, Stream destination, Func progress, int buffer, Action after, long total) { // 缓冲区。 var limit = buffer < 1 ? 1 : buffer; var temp = new byte[limit]; // 读取一次。 try { source.BeginRead(temp, 0, limit, (ar1) => { var count = source.EndRead(ar1); if (count > 0) { destination.BeginWrite(temp, 0, count, (ar2) => { destination.EndWrite(ar2); total += count; if (progress != null) { var @continue = progress.Invoke(total); if (!@continue) { after?.Invoke(); return; } } Async(source, destination, progress, buffer, after, total); }, null); } else after?.Invoke(); }, null); } catch { } } /// 解析 URL 的查询字符串,获取所有已解码的参数。 public static StringPairs ParseQuery(HttpRequest request) { if (request == null) return new StringPairs(); var sp = new StringPairs(); if (request.Query == null) return sp; var keys = request.Query.Keys; sp.Capacity = keys.Count; foreach (var key in keys) { sp.Add(key, request.Query[key]); } sp.Capacity = sp.Count; return sp; } #endregion } } #endif