/* *┌──────────────────────────────────┐ *│  Copyright(C) 2017 by Antiphon.All rights reserved. │ *│ Author:by Locke Xie 2017-01-13           │ *└──────────────────────────────────┘ * * 功 能: http * 类 名: HttpNetSys.cs * * 修改历史: * * */ using System; using System.Collections; using System.Collections.Generic; using System.IO; using System.Linq; using System.Net.Sockets; using System.Text; using System.Threading; using System.Web; using UnityEngine; namespace Assets.Scripts.Model { class HttpNetSys { private static int Max_Post_Size = 10 * 1024 * 1024;//10m private const int BUFF_SIZE = 4096; private Stream inputStream; public StreamWriter OutputStream; public String http_method; public String http_url; public String http_protocol_versionstring; public Hashtable httpHeaders = new Hashtable(); internal TcpClient _Socket; /// /// 这个是服务器收到有效链接初始化 /// internal HttpNetSys(TcpClient client) { this._Socket = client; inputStream = new BufferedStream(_Socket.GetStream()); OutputStream = new StreamWriter(new BufferedStream(_Socket.GetStream()), UTF8Encoding.Default); ParseRequest(); } internal void process(string bind) { try { if(http_method.Equals("GET")) { //ListenersBox.Instance.MessagePool.ActiveHttp(this, bind, GetRequestExec()); } else if(http_method.Equals("POST")) { //ListenersBox.Instance.MessagePool.ActiveHttp(this, bind, PostRequestExec()); } } catch(Exception e) { Debug.LogError("ActiveHttp Exception: " + e); WriteFailure(); } } public void Close() { OutputStream.Flush(); inputStream.Dispose(); inputStream = null; OutputStream.Dispose(); OutputStream = null; // bs = null; this._Socket.Close(); } #region 读取流的一行 private string ReadLine() /// /// 读取流的一行 /// /// private string ReadLine() { int next_char; string data = ""; while(true) { next_char = this.inputStream.ReadByte(); if(next_char == '\n') { break; } if(next_char == '\r') { continue; } if(next_char == -1) { Thread.Sleep(1); continue; }; data += Convert.ToChar(next_char); } return data; } #endregion #region 转化出 Request private void ParseRequest() /// /// 转化出 Request /// private void ParseRequest() { String request = ReadLine(); if(request != null) { string[] tokens = request.Split(' '); if(tokens.Length != 3) { throw new Exception("invalid http request line"); } http_method = tokens[0].ToUpper(); http_url = tokens[1].ToLower(); http_protocol_versionstring = tokens[2]; } String line; while((line = ReadLine()) != null) { if(line.Equals("")) { break; } int separator = line.IndexOf(':'); if(separator == -1) { throw new Exception("invalid http header line: " + line); } String name = line.Substring(0, separator); int pos = separator + 1; while((pos < line.Length) && (line[pos] == ' ')) { pos++;//过滤键值对的空格 } string value = line.Substring(pos, line.Length - pos); httpHeaders[name] = value; } } #endregion #region 读取Get数据 private Dictionary GetRequestExec() /// /// 读取Get数据 /// /// private Dictionary GetRequestExec() { Dictionary datas = new Dictionary(); int index = http_url.IndexOf("?", 0); if(index >= 0) { string data = http_url.Substring(index + 1); datas = getData(data); } WriteSuccess(); return datas; } #endregion #region 读取提交的数据 private void handlePOSTRequest() /// /// 读取提交的数据 /// private Dictionary PostRequestExec() { int content_len = 0; MemoryStream ms = new MemoryStream(); if(this.httpHeaders.ContainsKey("Content-Length")) { //内容的长度 content_len = Convert.ToInt32(this.httpHeaders["Content-Length"]); if(content_len > Max_Post_Size) { throw new Exception(String.Format("POST Content-Length({0}) 对于这个简单的服务器太大", content_len)); } byte[] buf = new byte[BUFF_SIZE]; int to_read = content_len; while(to_read > 0) { int numread = this.inputStream.Read(buf, 0, Math.Min(BUFF_SIZE, to_read)); if(numread == 0) { if(to_read == 0) { break; } else { throw new Exception("client disconnected during post"); } } to_read -= numread; ms.Write(buf, 0, numread); } ms.Seek(0, SeekOrigin.Begin); } StreamReader inputData = new StreamReader(ms); string data = inputData.ReadToEnd(); WriteSuccess(); return getData(data); } #endregion #region 输出状态 /// /// 输出200状态 /// public void WriteSuccess() { OutputStream.WriteLine("HTTP/1.0 200 OK"); OutputStream.WriteLine("Content-Type: text/html"); OutputStream.WriteLine(""); } /// /// 输出状态404 /// public void WriteFailure() { OutputStream.WriteLine("HTTP/1.0 404 File not found"); OutputStream.WriteLine("Content-Type: text/html"); OutputStream.WriteLine("Connection: close"); OutputStream.WriteLine(""); } #endregion /// /// 分析http提交数据分割 /// /// /// private static Dictionary getData(string rawData) { var rets = new Dictionary(); string[] rawParams = rawData.Split('&'); WWWForm form = new WWWForm(); foreach(string param in rawParams) { string[] kvPair = param.Split('='); string key = kvPair[0]; string value = HttpUtility.UrlDecode(kvPair[1]); rets[key] = value; } return rets; } } }