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
}
}