using Apewer.Network; using System; using System.Collections.Generic; using System.IO; using System.Net; namespace Apewer.Web { /// 用于网站的服务程序。 public class HttpListenerProvider : ApiProvider { private HttpListenerContext context; private HttpListenerRequest request; private HttpListenerResponse response; /// HttpContext public override HttpListenerContext Context { get => context; } /// 创建服务程序实例。 /// public HttpListenerProvider(HttpListenerContext context) { if (context == null) throw new ArgumentNullException(nameof(context)); this.context = context; request = context.Request; response = context.Response; } #region Implement /// 写入响应前的检查,返回错误信息。 public override string PreWrite() { if (response == null) return null; // 从 Response 头中移除 Server 和 X-Powered-By 属性。 var keys = new List(response.Headers.AllKeys); if (keys.Contains("Server")) response.Headers.Remove("Server"); if (keys.Contains("X-Powered-By")) response.Headers.Remove("X-Powered-By"); return null; } /// 向发送缓冲区的数据,之后停止并关闭响应流。 public override void End() => End(true); #endregion #region Request /// 获取 HTTP 方法。 public override Network.HttpMethod GetMethod() => ApiUtility.Method(request.HttpMethod); /// 获取客户端的 IP 地址。 public override string GetClientIP() => request.UserHostAddress; /// 获取请求的 URL。 public override Uri GetUrl() => request.Url; /// 获取请求的 Referrer。 public override string GetReferrer() => request.UrlReferrer == null ? null : request.UrlReferrer.OriginalString; /// 获取请求的头。 public override HttpHeaders GetHeaders() => new HttpHeaders(request.Headers); /// 获取请求的内容类型。 public override string GetContentType() => request.ContentType; /// 获取请求的内容长度。 public override long GetContentLength() => request.ContentLength64; /// 获取请求的内容。 public override Stream RequestBody() => request.InputStream; #endregion #region Response /// 设置 HTTP 状态。 public override void SetStatus(int status, int subStatus = 0) => response.StatusCode = status; /// 设置响应的头。 public override string SetHeader(string name, string value) { if (response == null || string.IsNullOrEmpty(name) || string.IsNullOrEmpty(value)) return "参数无效。"; try { response.AddHeader(name, value); return null; } catch (Exception ex) { return ex.Message; } } /// 设置响应的缓存秒数,设置为 0 即不允许缓存。 public override void SetCache(int seconds) { if (seconds > 0) { SetHeader("Cache-Control", $"public, max-age={seconds}, s-maxage={seconds}"); return; } 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.ContentLength64 = value; /// 设置响应重定向。 /// 响应 302 状态。 public override void SetRedirect(string location) { try { response.Redirect(location); } catch { } } /// 获取 Response 流。 public override Stream ResponseBody() => response.OutputStream; #endregion #region This /// 停止并关闭响应流。可指定向发送缓冲区的数据。 public void End(bool flush) { if (response == null) return; try { if (flush) response.OutputStream.Flush(); } catch { } try { response.Close(); } catch { } } /// 获取 Cookies。 public StringPairs GetCookies() { var sp = new StringPairs(); if (request != null && request.Cookies != null) { for (var i = 0; i < request.Cookies.Count; i++) { try { var cookie = request.Cookies[i]; var key = cookie.Name; var value = cookie.Value ?? ""; sp.Add(new KeyValuePair(key, value)); } catch { } } } return sp; } /// 设置响应的 Cookie。 public string SetCookie(string key, string value) { if (response == null) return null; var k = key.ToTrim(); var v = value.ToTrim(); if (k.IsEmpty()) return "参数 Key 无效。"; try { var cookie = new Cookie(k, v); var now = DateTime.Now; cookie.Expires = v.IsEmpty() ? now.AddDays(-1) : now.AddYears(1); response.SetCookie(cookie); return null; } catch (Exception ex) { return ex.Message; } } #endregion } }