namespace 小型IIS服务器
{/// <summary>
/// 管理用户向服务器发送的请求报文数据
/// 报文行
/// 报文头
/// 空白行
/// 报文体
/// </summary>
public class HttpRequest
{
/*
* 00 有参构造函数 传入用户请求报文数据 实例化为用请求报文创建的相关属性
* 01 解析用户请求报文数据 创建相应的属性存储用户请求报文数据 报文数据可以分为几个部分 分别存储
* 02 将用户请求报文分解 给相应创建的属性赋值
*/
#region 0.0 构造函数
private string requestMsg;
public HttpRequest() { }
public HttpRequest(string requestMsg)
{
this.requestMsg = requestMsg;
//调用解析请求报文方法,分解请求报文,并给相关属性赋值
InitAttr(this.requestMsg);
}
#endregion
#region 1.0 请求报文由多个部分组成 创建相应的属性来存储
private string httpMethod;/// <summary>
/// Http请求方法(get,post)
/// </summary>
public string HttpMethod
{
get { return httpMethod; }
set { httpMethod = value; }
}
private string rawUrl;
/// <summary>/// 请求报文的虚拟路径 /index.html
/// </summary>
public string RawUrl
{
get { return rawUrl; }
set { rawUrl = value; }
}
private string httpVerb;
/// <summary>/// Http协议 HTTP/1.1
/// </summary>
public string HttpVerb
{
get { return httpVerb; }
set { httpVerb = value; }
}
private string urlExtention;
/// <summary>
/// 请求报文URL的后缀名 (例如:.html,.js,.css,.aspx.....)
/// </summary>
public string UrlExtention
{
get { return urlExtention; }
set { urlExtention = value; }
}
#endregion
#region 2.0 将请求报文中相应的部分 解析成相应的属性部分 并赋值
/// <summary>
/// 将请求报文中相应的部分 解析成相应的属性部分 并赋值
/// </summary>
/// <param name="requestMsg"></param>
private void InitAttr(string requestMsg)
{
//如果请求报文为空,则不处理
if (string.IsNullOrEmpty(requestMsg))
{
return;
}
//01 将请求报文文本数据以 \r\n分隔 用数组存储
string[] requestArr = requestMsg.Split(new string[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries);
//02 提取数组中的数据 根据 空格 分隔
if (requestArr.Length > 0)
{
string requestLine = requestArr[0]; // GET /index.html HTTP/1.1 \r\n
string[] lineArr = requestLine.Split(' ');
if (lineArr.Length == 3)
{
httpMethod = lineArr[0];
rawUrl = lineArr[1];
httpVerb = lineArr[2];
this.urlExtention = System.IO.Path.GetExtension(RawUrl);
}
}
}
#endregion
}
}
//2.0
namespace 小型IIS服务器
{
/// <summary>
/// 管理服务器响应报文 将响应报文组成
/// 响应报文行
/// 响应报文头
/// 空白行
/// 响应报文体
/// </summary>
public class HttpResponse
{
/*
* 00 构造函数 在有参构造函数中传入 【处理用户请求报文的对象(HttpRequeset的对象)】 以获取用户请求报文中相应的属性
* 给状态码赋值
* 01 状态码的设置 响应报文中有表示响应报文状态的状态码 需要根据标准 自己设置 用字典结构存储 一个状态码对应着一个解释
* 02 报文段的设置 获取报文段的长度 创建报文段对象 以给报文段赋值
* 03 组装响应报文 用 StringBuilder 存储 ;AppendLine整行添加
* 可以将响应报文大致分为两个部分,一部分:响应报文行 + 响应报文头 + 空白行 一部分:响应报文体
* 两部分分别用byte[]数组存储,最后用byte[]数组合并,返回响应报文
*/
#region 0.0 构造函数
private HttpRequest request;
public HttpResponse() { }
public HttpResponse(HttpRequest request)
{
this.request = request;
//设置状态码
stateDic.Add(200, "OK");
stateDic.Add(404, "File Not Found");
stateDic.Add(500, "Internal Server Error");
}
#endregion
#region 1.0 设置状态码
/// <summary>
/// 存储状态码 一个状态码 有对应的解释
/// </summary>
Dictionary<int, string> stateDic = new Dictionary<int, string>();
int stateCode = 200;
/// <summary>
/// 响应状态码
/// </summary>
public int StateCode
{
get { return stateCode; }
set { stateCode = value; }
}
string stataString;
/// <summary>
/// 响应状态码对应的解释字符串
/// </summary>
public string StataString
{
get { return stateDic[StateCode]; }
}
#endregion
#region 2.0 报文段属性设置
int contentLength;
/// <summary>
/// 报文长度
/// </summary>
public int ContentLength
{
get { return ContentBody.Length; }
}
byte[] contentBody = new byte[0];
/// <summary>
/// 储存相应报文体的字符数组
/// </summary>
public byte[] ContentBody
{
get { return contentBody; }
set { contentBody = value; }
}
StringBuilder contentBodyStr = new StringBuilder(500);
/// <summary>
/// 提供给外部方法调用的方法,将响应报文体的数据存储到contentBody中
/// </summary>
/// <param name="contentBody"></param>
public void Write(string contentBody)
{
//用StringBuilder存储响应报文体,然后将其转变为byte[]数据流类型赋值给ContentBody
contentBodyStr.Append(contentBody);
//将字符串转为byte[]数组数据
ContentBody = Encoding.UTF8.GetBytes(contentBodyStr.ToString());
}
#endregion
#region 3.0 组成响应报文 +byte[] GetResponseMessage()
/// <summary>
/// 组装响应报文
/// </summary>
/// <returns></returns>
public byte[] GetResponseMessage()
{
System.Text.StringBuilder lineHead = new StringBuilder();
//01 组装响应 报文行 HTTP/1.1 200 OK
lineHead.AppendLine(request.HttpVerb + " " + StateCode + " " + StataString);
//02 组装响应 报文头 Content-Type: text/html;charset=utf-8
lineHead.AppendLine("Content-Type: text/html;charset=utf-8");
//Content-Length: 325
lineHead.AppendLine("Content-Length: " + ContentLength);
//Server: Mini IIS
lineHead.AppendLine("Server: Mini IIS");
//03 组装响应 空白行
lineHead.AppendLine("");
//04 组装响应 报文体
//将响应报文头转换为byte[]数组
byte[] headByte = System.Text.Encoding.UTF8.GetBytes(lineHead.ToString());
//响应报文长度
byte[] responseByte = new byte[headByte.Length + ContentLength];
//将headByte 与 报文体合并
headByte.CopyTo(responseByte, 0);
ContentBody.CopyTo(responseByte, headByte.Length);
//05 返回响应报文
return responseByte;
}
#endregion
}
}
//3.0 HttpServerUtility
namespace 小型IIS服务器
{
/// <summary>
/// 帮助类
/// </summary>
public class HttpServerUtility
{
/// <summary>
/// 根据虚拟路径获取物理路径
/// </summary>
/// <param name="virtualPath">虚拟路径</param>
public string MapPath(string virtualPath)
{
string basePath = AppDomain.CurrentDomain.BaseDirectory;
return basePath + virtualPath;
}
}
}