SimpleHttpServer.cs 13 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333
  1. using System;
  2. using System.Collections.Generic;
  3. using System.Diagnostics;
  4. using System.Drawing;
  5. using System.Drawing.Imaging;
  6. using System.IO;
  7. using System.Text;
  8. using LJLib.Net.SPI.Com;
  9. using LJLib.Net.SPI.Server;
  10. using LJLib.Text.Parser;
  11. using LJLib.Tools.Helper;
  12. using LJLib.Tools.Utils;
  13. using JLHHJSvr.LJLib.HttpServer;
  14. using System.Web;
  15. using System.Linq;
  16. using Newtonsoft.Json;
  17. namespace LJLib.HttpServer
  18. {
  19. public class SimpleHttpServer : LJHttpServer
  20. {
  21. private ILJServer server;
  22. private IFileDBModel fileModel;
  23. private static LJParser parser = new LJParser();
  24. private static Dictionary<string, byte[]> files = new Dictionary<string, byte[]>();
  25. public SimpleHttpServer(int port, ILJServer server, IFileDBModel fileModel)
  26. : base(port)
  27. {
  28. this.server = server;
  29. this.fileModel = fileModel;
  30. }
  31. public override void HandleGetRequest(LJHttpProcessor p)
  32. {
  33. //转到POST统一处理
  34. HandlePostRequest(p, null);
  35. }
  36. public override void HandlePostRequest(LJHttpProcessor p, StreamReader inputData)
  37. {
  38. string bufferedBody = string.Empty;
  39. if (inputData != null)
  40. {
  41. bufferedBody = inputData.ReadToEnd();
  42. }
  43. if (p.http_method.Equals("POST"))
  44. {
  45. if (p.http_url.StartsWith("/api.ashx"))
  46. {
  47. if (server == null)
  48. {
  49. throw new Exception("未定义server成员");
  50. }
  51. var postParamDic = p.POSTqueryParams(inputData);
  52. if (!postParamDic.ContainsKey("method"))
  53. {
  54. p.WriteError("无效的请求接口");
  55. return;
  56. }
  57. string method = postParamDic["method"];//接口名称apiName
  58. string requestbody = string.Empty;//请求类JSON字符串
  59. if (postParamDic.ContainsKey("requestbody"))
  60. {
  61. requestbody = postParamDic["requestbody"];
  62. }
  63. // 处理请求
  64. handleAPI(p, method, requestbody);
  65. return;
  66. }
  67. else if (p.http_url.StartsWith("/api/common/"))
  68. {
  69. var apiName = p.http_url.Substring(12);
  70. var requestbody = bufferedBody;
  71. handleAPI(p, apiName, requestbody);
  72. return;
  73. }
  74. }
  75. else if (p.http_method.Equals("GET"))
  76. {
  77. // 图片/文件获取接口
  78. if (p.http_url.StartsWith("/img.ashx"))
  79. {
  80. var parms = p.GETqueryParams();
  81. string filemd5 = string.Empty;
  82. if (!parms.ContainsKey("filename"))
  83. {
  84. Trace.Write("请求img.ashx不包含filename参数");
  85. }
  86. else
  87. {
  88. filemd5 = parms["filename"];
  89. }
  90. byte[] body = null;
  91. if (files.ContainsKey(filemd5))
  92. {
  93. body = files[filemd5];
  94. }
  95. else
  96. {
  97. body = fileModel.GetBytes(filemd5);
  98. }
  99. var ext = MIMEHelper.GetExType(body);
  100. var contentType = MIMEHelper.ContentType("." + ext);
  101. if (!string.IsNullOrEmpty(ext) && parms.ContainsKey("w") && parms.ContainsKey("h"))
  102. {
  103. int width;
  104. int height;
  105. if (int.TryParse(parms["w"], out width) && int.TryParse(parms["h"], out height))
  106. {
  107. using (var ms = new MemoryStream(body))
  108. using (var img = Image.FromStream(ms))
  109. using (var oImg = ImgHelper.NewBMPFrom(img, width, height))
  110. using (var oms = new MemoryStream())
  111. {
  112. oImg.Save(oms, ImageFormat.Png);
  113. body = oms.ToArray();
  114. contentType = MIMEHelper.ContentType(".png");
  115. }
  116. }
  117. }
  118. p.WriteResponse(body, contentType);
  119. return;
  120. }
  121. else if (p.http_url.StartsWith("/dist") || p.http_url.StartsWith("/html") ||
  122. p.http_url.StartsWith("/App_Files"))
  123. {
  124. string basePath = AppDomain.CurrentDomain.BaseDirectory;
  125. string requestPath;
  126. requestPath = p.http_url.Substring(1);
  127. string filePath = basePath + "/" + requestPath;
  128. if (!File.Exists(filePath))
  129. {
  130. p.WriteError("未找到文件");
  131. return;
  132. }
  133. string fileName = p.http_url.Substring(p.http_url.LastIndexOf('.')).ToLower();
  134. string fileType = MIMEHelper.ContentType(fileName);
  135. byte[] body;
  136. using (var ms = new MemoryStream())
  137. using (var fs = File.OpenRead(filePath))
  138. {
  139. StreamHelper.StreamCopy(ms, fs);
  140. body = ms.ToArray();
  141. }
  142. if (fileType.StartsWith("text/html"))
  143. {
  144. fileType += "; charset=utf-8";
  145. }
  146. p.WriteResponse(Encoding.UTF8.GetString(body), fileType);
  147. return;
  148. }
  149. else
  150. {
  151. string basePath = AppDomain.CurrentDomain.BaseDirectory;
  152. string filePath = basePath + "/App_Files/";
  153. var sourceDir = new DirectoryInfo(filePath);
  154. var enabledSubWeb = sourceDir.GetDirectories().Select(x => x.Name);
  155. var subUrl = p.http_url;
  156. var subDirs = subUrl.Split('/').Where(x => !string.IsNullOrEmpty(x)).ToList();
  157. var subDir = "Web";
  158. if (subDirs.Any())
  159. {
  160. if (enabledSubWeb.Contains(subDirs.First()))
  161. {
  162. subDir = subDirs.First();
  163. var firstblock = $"/{subDir}/";
  164. var removeidx = subUrl.IndexOf(firstblock);
  165. subUrl = subUrl.Substring(removeidx + firstblock.Length - 1);
  166. }
  167. }
  168. filePath += subDir;
  169. if (subUrl.IndexOf(".") > 0)
  170. {
  171. if (File.Exists(filePath + subUrl))
  172. {
  173. filePath += subUrl;
  174. }
  175. else
  176. {
  177. filePath += "/index.html";
  178. }
  179. }
  180. else
  181. {
  182. filePath += "/index.html";
  183. }
  184. if (!File.Exists(filePath))
  185. {
  186. p.WriteResponse(
  187. new[]
  188. {
  189. "HTTP/1.0 404 Not Found",
  190. "Content-Type: text/plain",
  191. "Connection: close"
  192. }, "The resource you requested ('" + p.http_url + "') could not be found.");
  193. }
  194. else
  195. {
  196. byte[] body;
  197. string fileType = null;
  198. string ext = null;
  199. if (filePath.Contains("."))
  200. {
  201. ext = filePath.Substring(filePath.LastIndexOf("."));
  202. fileType = MIMEHelper.ContentType(ext);
  203. }
  204. using (var ms = new MemoryStream())
  205. using (var fs = File.OpenRead(filePath))
  206. {
  207. StreamHelper.StreamCopy(ms, fs);
  208. body = ms.ToArray();
  209. if (string.IsNullOrEmpty(fileType))
  210. {
  211. ext = MIMEHelper.GetExType(body);
  212. fileType = MIMEHelper.ContentType("." + ext);
  213. }
  214. }
  215. if (fileType.StartsWith("text/html"))
  216. {
  217. fileType += "; charset=utf-8";
  218. p.WriteResponse(new[]
  219. {
  220. "HTTP/1.0 200 OK",
  221. "Content-Type: " + fileType,
  222. "Connection: close"
  223. }, Encoding.UTF8.GetString(body));
  224. }
  225. else
  226. {
  227. p.WriteResponse(new[]
  228. {
  229. "HTTP/1.0 200 OK",
  230. "Content-Type: " + fileType,
  231. "Content-Length: " + body.Length,
  232. "Connection: close"
  233. }, body);
  234. }
  235. }
  236. return;
  237. }
  238. }
  239. p.WriteFailure();
  240. }
  241. private void handleAPI(LJHttpProcessor p, string method, string requestbody)
  242. {
  243. LJResponse responselist = null;
  244. string str = string.Empty;
  245. perf_event_log perf = null;
  246. var dataArriveTime = DateTime.Now; // 接口处理开始
  247. try
  248. {
  249. if (!requestbody.StartsWith("{"))
  250. {
  251. requestbody = HttpUtility.UrlDecode(requestbody);
  252. if (!requestbody.StartsWith("{"))
  253. {
  254. Trace.Write("请求格式错误" + requestbody);
  255. throw new Exception("请求格式错误");
  256. }
  257. }
  258. ILJRequest requestlist = null;
  259. string apiName = method;
  260. Type requestType = server.GetRequestType(apiName);
  261. string body = requestbody;
  262. requestlist = JsonConvert.DeserializeObject(body, requestType) as ILJRequest;
  263. //requestlist = parser.JsonParse(requestType, body) as ILJRequest;
  264. var dataReadTime = DateTime.Now; // 请求解析完成
  265. responselist = server.DoExcute(requestlist, null);
  266. var doneTime = DateTime.Now; // 接口处理完成
  267. if (!string.IsNullOrEmpty(responselist.ErrMsg))
  268. {
  269. Trace.Write(requestlist.GetApiName() + ":" + responselist.ErrMsg);
  270. }
  271. perf = requestlist.perf;
  272. if (perf != null)
  273. {
  274. perf.EventName = requestlist.GetApiName();
  275. if (perf.clientinfo == null)
  276. {
  277. perf.clientinfo = string.Empty;
  278. }
  279. if (perf.dtList == null)
  280. {
  281. perf.dtList = string.Empty;
  282. }
  283. perf.clientinfo += "http\r\n";
  284. perf.dtList += $"{dataArriveTime:yyyy-MM-dd HH:mm:ss.fff} 接口处理开始\r\n"; // 2. 接收:数据到达
  285. perf.dtList += $"{dataReadTime:yyyy-MM-dd HH:mm:ss.fff} 请求解析完成\r\n"; // 3. 解析: 读数完成转LJRequest
  286. perf.dtList += $"{doneTime:yyyy-MM-dd HH:mm:ss.fff} 接口处理完成\r\n"; // 4. 后台处理: 解析完进行处理
  287. }
  288. responselist.perf = perf;
  289. //Dictionary<string, byte[]> fil = new Dictionary<string, byte[]>();
  290. //str = parser.ToJson(responselist, fil, "/img.ashx?filename=");
  291. str = JsonConvert.SerializeObject(responselist);
  292. }
  293. catch (Exception ex)
  294. {
  295. Trace.Write(ex.ToString());
  296. responselist = new ErrResponse(ex.ToString());
  297. str = parser.ToJson(responselist);
  298. }
  299. p.WriteResponse(
  300. new[]{
  301. "HTTP/1.0 200 OK",
  302. "Content-Type: text/plain; charset=utf-8",
  303. "Connection: close"
  304. },
  305. str);
  306. }
  307. }
  308. }