HttpProcessor.cs 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321
  1. using Newtonsoft.Json;
  2. using System;
  3. using System.Collections;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Linq;
  7. using System.Net.Sockets;
  8. using System.Text;
  9. using System.Threading;
  10. using System.Threading.Tasks;
  11. using MqttMsgServer.HttpService.dto;
  12. using ConsoleHttp.Model;
  13. using MqttMsgServer.Dao;
  14. using MqttMsgServer.Model;
  15. using MqttMsgServer.Service.Client;
  16. using MqttMsgServer.Tools;
  17. namespace MqttMsgServer.HttpService
  18. {
  19. public class HttpProcessor
  20. {
  21. public TcpClient Socket;
  22. public HttpServer Srv;
  23. private Stream _inputStream;
  24. public StreamWriter OutputStream;
  25. public string HttpMethod;
  26. public string HttpUrl;
  27. public string HttpProtocolVersionsString;
  28. public Hashtable HttpHeaders = new Hashtable();
  29. private static int MAX_POST_SIZE = 10 * 1024 * 1024;//10M
  30. public HttpProcessor(TcpClient s, HttpServer srv)
  31. {
  32. this.Socket = s;
  33. this.Srv = srv;
  34. }
  35. private string StreamReadLine(Stream inputStream)
  36. {
  37. string data = "";
  38. while (true)
  39. {
  40. var nextChar = inputStream.ReadByte();
  41. if (nextChar == '\n') { break; }
  42. if (nextChar == '\r') { continue; }
  43. if (nextChar == -1)
  44. {
  45. Thread.Sleep(1);
  46. continue;
  47. }
  48. data += Convert.ToChar(nextChar);
  49. }
  50. return data;
  51. }
  52. public void Process()
  53. {
  54. _inputStream = new BufferedStream(Socket.GetStream());
  55. OutputStream = new StreamWriter(new BufferedStream(Socket.GetStream()));
  56. try
  57. {
  58. ParseRequest();
  59. ReadHeaders();
  60. if (HttpMethod.Equals("GET"))
  61. {
  62. HandleGetRequest();
  63. }
  64. else if (HttpMethod.Equals("POST"))
  65. {
  66. HandlePostRequest();
  67. }
  68. }
  69. catch (Exception e)
  70. {
  71. //Console.WriteLine("Exception: " + e.ToString());
  72. this.LogDebug("Exception: " + e.ToString());
  73. WriteFailure();
  74. }
  75. OutputStream.Flush();
  76. // bs.Flush(); // flush any remaining output
  77. _inputStream = null; OutputStream = null; // bs = null;
  78. Socket.Close();
  79. }
  80. public void ParseRequest()
  81. {
  82. string request = StreamReadLine(_inputStream);
  83. string[] tokens = request.Split(' ');
  84. if (tokens.Length != 3)
  85. {
  86. throw new Exception("invalid http request line!");
  87. }
  88. HttpMethod = tokens[0].ToUpper();
  89. HttpUrl = tokens[1];
  90. HttpProtocolVersionsString = tokens[2];
  91. // Console.WriteLine("starting:" + request);
  92. this.LogDebug("starting:" + request);
  93. }
  94. public void ReadHeaders()
  95. {
  96. // Console.WriteLine("readHeaders()");
  97. this.LogDebug("readHeaders()");
  98. string line;
  99. while ((line = StreamReadLine(_inputStream)) != null)
  100. {
  101. if (line.Equals(""))
  102. {
  103. // Console.WriteLine("got headers");
  104. this.LogDebug("got headers");
  105. return;
  106. }
  107. int separator = line.IndexOf(':');
  108. if (separator == -1)
  109. {
  110. throw new Exception("invalid http header line:" + line);
  111. }
  112. string name = line.Substring(0, separator);
  113. int pos = separator + 1;
  114. while ((pos < line.Length) && (line[pos] == ' '))
  115. {
  116. pos++;
  117. }
  118. string value = line.Substring(pos, line.Length - pos);
  119. //Console.WriteLine("header: {0}:{1}", name, value);
  120. this.LogDebug($"header: {name}:{value}");
  121. HttpHeaders[name.ToLower()] = value;
  122. }
  123. }
  124. public void HandleGetRequest()
  125. {
  126. Srv.HandleGetRequest(this);
  127. }
  128. private const int BUF_SIZE = 4096;
  129. public void HandlePostRequest()
  130. {
  131. // this post data processing just reads everything into a memory stream.
  132. // this is fine for smallish things, but for large stuff we should really
  133. // hand an input stream to the request processor. However, the input stream
  134. // we hand him needs to let him see the "end of the stream" at this content
  135. // length, because otherwise he won't know when he's seen it all!
  136. // Console.WriteLine("get post data start");
  137. this.LogDebug("get post data start");
  138. int content_len = 0;
  139. MemoryStream ms = new MemoryStream();
  140. if (this.HttpHeaders.ContainsKey("Content-Length".ToLower()))
  141. {
  142. content_len = Convert.ToInt32(this.HttpHeaders["Content-Length".ToLower()]);
  143. if (content_len > MAX_POST_SIZE)
  144. {
  145. throw new Exception(
  146. $"POST Content-Length({content_len}) too big for this simple server");
  147. }
  148. byte[] buf = new byte[BUF_SIZE];
  149. int to_read = content_len;
  150. while (to_read > 0)
  151. {
  152. //Console.WriteLine("starting Read, to_read={0}", to_read);
  153. this.LogDebug($"starting Read, to_read={to_read}");
  154. int numread = this._inputStream.Read(buf, 0, Math.Min(BUF_SIZE, to_read));
  155. //Console.WriteLine("read finished, numread={0}", numread);
  156. this.LogDebug($"read finished, numread={numread}" );
  157. if (numread == 0)
  158. {
  159. if (to_read == 0)
  160. {
  161. break;
  162. }
  163. throw new Exception("client disconnected during post");
  164. }
  165. to_read -= numread;
  166. ms.Write(buf, 0, numread);
  167. }
  168. ms.Seek(0, SeekOrigin.Begin);
  169. }
  170. //Console.WriteLine("get post data end");
  171. this.LogDebug("get post data end");
  172. Srv.HandlePostRequest(this, new StreamReader(ms));
  173. }
  174. public void WriteSuccess(string type = "")
  175. {
  176. OutputStream.WriteLine("HTTP/1.0 200 OK");
  177. switch (type)
  178. {
  179. case "json":
  180. OutputStream.WriteLine("Content-Type: application/json; charset=UTF-8");
  181. break;
  182. default:
  183. OutputStream.WriteLine("Content-Type: text/html;charset=utf-8");
  184. break;
  185. }
  186. OutputStream.WriteLine("Connection: close");
  187. OutputStream.WriteLine("");
  188. }
  189. public void WriteFailure()
  190. {
  191. OutputStream.WriteLine("HTTP/1.0 404 File not found");
  192. OutputStream.WriteLine("Connection: close");
  193. OutputStream.WriteLine("");
  194. }
  195. }
  196. public abstract class HttpServer
  197. {
  198. protected int Port;
  199. private TcpListener _listener;
  200. private bool _isActive = true;
  201. public HttpServer(int port)
  202. {
  203. this.Port = port;
  204. }
  205. [Obsolete]
  206. public void Listen()
  207. {
  208. _listener = new TcpListener(Port);
  209. _listener.Start();
  210. while (_isActive)
  211. {
  212. try
  213. {
  214. TcpClient s = _listener.AcceptTcpClient();
  215. HttpProcessor processor = new HttpProcessor(s, this);
  216. Thread thread = new Thread(processor.Process);
  217. thread.Start();
  218. Thread.Sleep(1);
  219. }
  220. catch (Exception e)
  221. {
  222. this.LogError(e.Message);
  223. }
  224. }
  225. }
  226. public abstract void HandleGetRequest(HttpProcessor p);
  227. public abstract void HandlePostRequest(HttpProcessor p, StreamReader inputData);
  228. }
  229. public class MyHttpServer : HttpServer
  230. {
  231. public MyHttpServer(int port) : base(port)
  232. {
  233. }
  234. public override void HandleGetRequest(HttpProcessor p)
  235. {
  236. //Console.WriteLine("request: {0}", p.HttpUrl);
  237. this.LogDebug($"request--Get:{p.HttpUrl}");
  238. p.WriteSuccess();
  239. string response = "{\"url\":\""+p.HttpUrl+"\"}";
  240. p.OutputStream.WriteLine(response);
  241. //p.outputStream.WriteLine("<html><body><h1>test server</h1>");
  242. //p.outputStream.WriteLine("Current Time: " + DateTime.Now.ToString());
  243. //p.outputStream.WriteLine("url : {0}", p.http_url);
  244. //
  245. //p.outputStream.WriteLine("<form method=post action=/form>");
  246. //p.outputStream.WriteLine("<input type=text name=foo value=foovalue>");
  247. //p.outputStream.WriteLine("<input type=submit name=bar value=barvalue>");
  248. //p.outputStream.WriteLine("</form>");
  249. }
  250. public override void HandlePostRequest(HttpProcessor p, StreamReader inputData)
  251. {
  252. ResponseResult result = new ResponseResult();
  253. try
  254. {
  255. // Console.WriteLine("POST request: {0}", p.HttpUrl);
  256. this.LogDebug($"request--Post:{p.HttpUrl}");
  257. string data = inputData.ReadToEnd();
  258. this.LogError("请求:===" + data);
  259. if (string.IsNullOrEmpty(data))
  260. {
  261. p.OutputStream.WriteLine("{\"result\":\"参数为空!\"}");
  262. }
  263. p.WriteSuccess("json");
  264. if (!p.HttpUrl.EndsWith("regClient"))
  265. {
  266. p.OutputStream.WriteLine("{\"result\":\"404\"}");
  267. }
  268. var clientDto = JsonConvert.DeserializeObject<ClientDto>(data);
  269. ClientInfoService cs = new ClientInfoService();
  270. result = cs.AddOrUpdateClient(clientDto);
  271. p.OutputStream.WriteLine(JsonConvert.SerializeObject(result));
  272. }
  273. catch (Exception e)
  274. {
  275. result.IsSuccess = false;
  276. result.ErrorMessage = e.Message;
  277. this.LogError(e.StackTrace);
  278. p.OutputStream.WriteLine(JsonConvert.SerializeObject(result));
  279. }
  280. }
  281. }
  282. }