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