using System; using System.Collections.Generic; using System.Diagnostics; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Text; using LJLib.Net.SPI.Com; using LJLib.Net.SPI.Server; using LJLib.Text.Parser; using LJLib.Tools.Helper; using LJLib.Tools.Utils; using JLHHJSvr.LJLib.HttpServer; using System.Web; using System.Linq; using Newtonsoft.Json; namespace LJLib.HttpServer { public class SimpleHttpServer : LJHttpServer { private ILJServer server; private IFileDBModel fileModel; private static LJParser parser = new LJParser(); private static Dictionary files = new Dictionary(); public SimpleHttpServer(int port, ILJServer server, IFileDBModel fileModel) : base(port) { this.server = server; this.fileModel = fileModel; } public override void HandleGetRequest(LJHttpProcessor p) { //转到POST统一处理 HandlePostRequest(p, null); } public override void HandlePostRequest(LJHttpProcessor p, StreamReader inputData) { string bufferedBody = string.Empty; if (inputData != null) { bufferedBody = inputData.ReadToEnd(); } if (p.http_method.Equals("POST")) { if (p.http_url.StartsWith("/api.ashx")) { if (server == null) { throw new Exception("未定义server成员"); } var postParamDic = p.POSTqueryParams(inputData); if (!postParamDic.ContainsKey("method")) { p.WriteError("无效的请求接口"); return; } string method = postParamDic["method"];//接口名称apiName string requestbody = string.Empty;//请求类JSON字符串 if (postParamDic.ContainsKey("requestbody")) { requestbody = postParamDic["requestbody"]; } // 处理请求 handleAPI(p, method, requestbody); return; } else if (p.http_url.StartsWith("/api/common/")) { var apiName = p.http_url.Substring(12); var requestbody = bufferedBody; handleAPI(p, apiName, requestbody); return; } } else if (p.http_method.Equals("GET")) { // 图片/文件获取接口 if (p.http_url.StartsWith("/img.ashx")) { var parms = p.GETqueryParams(); string filemd5 = string.Empty; if (!parms.ContainsKey("filename")) { Trace.Write("请求img.ashx不包含filename参数"); } else { filemd5 = parms["filename"]; } byte[] body = null; if (files.ContainsKey(filemd5)) { body = files[filemd5]; } else { body = fileModel.GetBytes(filemd5); } var ext = MIMEHelper.GetExType(body); var contentType = MIMEHelper.ContentType("." + ext); if (!string.IsNullOrEmpty(ext) && parms.ContainsKey("w") && parms.ContainsKey("h")) { int width; int height; if (int.TryParse(parms["w"], out width) && int.TryParse(parms["h"], out height)) { using (var ms = new MemoryStream(body)) using (var img = Image.FromStream(ms)) using (var oImg = ImgHelper.NewBMPFrom(img, width, height)) using (var oms = new MemoryStream()) { oImg.Save(oms, ImageFormat.Png); body = oms.ToArray(); contentType = MIMEHelper.ContentType(".png"); } } } p.WriteResponse(body, contentType); return; } else if (p.http_url.StartsWith("/dist") || p.http_url.StartsWith("/html") || p.http_url.StartsWith("/App_Files")) { string basePath = AppDomain.CurrentDomain.BaseDirectory; string requestPath; requestPath = p.http_url.Substring(1); string filePath = basePath + "/" + requestPath; if (!File.Exists(filePath)) { p.WriteError("未找到文件"); return; } string fileName = p.http_url.Substring(p.http_url.LastIndexOf('.')).ToLower(); string fileType = MIMEHelper.ContentType(fileName); byte[] body; using (var ms = new MemoryStream()) using (var fs = File.OpenRead(filePath)) { StreamHelper.StreamCopy(ms, fs); body = ms.ToArray(); } if (fileType.StartsWith("text/html")) { fileType += "; charset=utf-8"; } p.WriteResponse(Encoding.UTF8.GetString(body), fileType); return; } else { string basePath = AppDomain.CurrentDomain.BaseDirectory; string filePath = basePath + "/App_Files/"; var sourceDir = new DirectoryInfo(filePath); var enabledSubWeb = sourceDir.GetDirectories().Select(x => x.Name); var subUrl = p.http_url; var subDirs = subUrl.Split('/').Where(x => !string.IsNullOrEmpty(x)).ToList(); var subDir = "Web"; if (subDirs.Any()) { if (enabledSubWeb.Contains(subDirs.First())) { subDir = subDirs.First(); var firstblock = $"/{subDir}/"; var removeidx = subUrl.IndexOf(firstblock); subUrl = subUrl.Substring(removeidx + firstblock.Length - 1); } } filePath += subDir; if (subUrl.IndexOf(".") > 0) { if (File.Exists(filePath + subUrl)) { filePath += subUrl; } else { filePath += "/index.html"; } } else { filePath += "/index.html"; } if (!File.Exists(filePath)) { p.WriteResponse( new[] { "HTTP/1.0 404 Not Found", "Content-Type: text/plain", "Connection: close" }, "The resource you requested ('" + p.http_url + "') could not be found."); } else { byte[] body; string fileType = null; string ext = null; if (filePath.Contains(".")) { ext = filePath.Substring(filePath.LastIndexOf(".")); fileType = MIMEHelper.ContentType(ext); } using (var ms = new MemoryStream()) using (var fs = File.OpenRead(filePath)) { StreamHelper.StreamCopy(ms, fs); body = ms.ToArray(); if (string.IsNullOrEmpty(fileType)) { ext = MIMEHelper.GetExType(body); fileType = MIMEHelper.ContentType("." + ext); } } if (fileType.StartsWith("text/html")) { fileType += "; charset=utf-8"; p.WriteResponse(new[] { "HTTP/1.0 200 OK", "Content-Type: " + fileType, "Connection: close" }, Encoding.UTF8.GetString(body)); } else { p.WriteResponse(new[] { "HTTP/1.0 200 OK", "Content-Type: " + fileType, "Content-Length: " + body.Length, "Connection: close" }, body); } } return; } } p.WriteFailure(); } private void handleAPI(LJHttpProcessor p, string method, string requestbody) { LJResponse responselist = null; string str = string.Empty; try { if (!requestbody.StartsWith("{")) { requestbody = HttpUtility.UrlDecode(requestbody); if (!requestbody.StartsWith("{")) { Trace.Write("请求格式错误" + requestbody); throw new Exception("请求格式错误"); } } ILJRequest requestlist = null; string apiName = method; Type requestType = server.GetRequestType(apiName); string body = requestbody; requestlist = parser.JsonParse(requestType, body) as ILJRequest; responselist = server.DoExcute(requestlist, null); if (!string.IsNullOrEmpty(responselist.ErrMsg)) { Trace.Write(requestlist.GetApiName() + ":" + responselist.ErrMsg); } //Dictionary fil = new Dictionary(); //str = parser.ToJson(responselist, fil, "/img.ashx?filename="); str = JsonConvert.SerializeObject(responselist); } catch (Exception ex) { Trace.Write(ex.ToString()); responselist = new ErrResponse(ex.ToString()); str = parser.ToJson(responselist); } p.WriteResponse( new[]{ "HTTP/1.0 200 OK", "Content-Type: text/plain; charset=utf-8", "Connection: close" }, str); } } }