using HttpMultipartParser; using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Linq; using System.Net; using System.Text; using System.Threading; using System.Threading.Tasks; using System.Web; namespace ssgrestserver { public class NetManager { const string TAG = "NETMANAGER"; HttpListener listener = null; bool doListen = false; Thread mListenTaskWorker = null; ManualResetEvent mThreadCloseObserver = new ManualResetEvent(false); internal void stop() { doListen = false; listener.Stop(); mThreadCloseObserver.WaitOne(); } internal bool IsAlive() { if (mListenTaskWorker == null || !mListenTaskWorker.IsAlive) { return false; } else { return true; } } internal void start() { doListen = true; mListenTaskWorker = new Thread(listenTask); mListenTaskWorker.IsBackground = true; mListenTaskWorker.Start(); } private void listenTask() { listener = new HttpListener(); string port = Program.mainForm.txbPort.Text; listener.Prefixes.Add("http://+:" + port + "/"); listener.Start(); Program.mainForm.recvLog(TAG, "httpListener Start!! ---- " + DateTime.Now.ToLongDateString() + " " + DateTime.Now.ToLongTimeString()); while (doListen) { try { //string requestURL = listener.GetContext().Request.RawUrl; //ThreadPool.QueueUserWorkItem(HandleRequest, new object[] { requestURL }); ThreadPool.QueueUserWorkItem(HandleRequest, new object[] { listener.GetContext() }); } catch (Exception ex) { Program.mainForm.recvLog(TAG, ex.ToString()); } } mThreadCloseObserver.Set(); Program.mainForm.recvLog(TAG, "Listener Closed"); } private Stream GetBody(HttpListenerContext context) { if (!context.Request.HasEntityBody) { return null; } System.IO.Stream body = context.Request.InputStream; // Stream형식으로 받아오기 return body; } public static byte[] streamToByteArray(Stream input) { MemoryStream ms = new MemoryStream(); input.CopyTo(ms); return ms.ToArray(); } private void HandleRequest(object state) { HttpListenerContext context = (HttpListenerContext)((object[])state)[0]; HttpListenerRequest request = context.Request; try { //데이터핸들링부분 if (request.RawUrl != "/favicon.ico") { Program.mainForm.recvLog(TAG, request.RemoteEndPoint.ToString() + " " + request.RawUrl + " - Response Arrival" + DateTime.Now.ToString("yyyyMMdd HH:mm:ss") + Environment.NewLine); Console.WriteLine(request.RawUrl); //업로드 if (request.HttpMethod.Equals("POST") && HttpUtility.UrlDecode(request.RawUrl).Equals("/파일업로드")){ Stream stream = GetBody(context); var parser = MultipartFormDataParser.Parse(stream); //stream: Request Body (stream형식) //Image Parse int nCnt = parser.Files.Count; //파싱할 파일의 개수 byte[] arrByte; string filename = ""; if (nCnt > 0) //파싱할 파일의 개수가 0보다 크면, { var file = parser.Files.First(); filename = file.FileName; Stream data = file.Data; //stream 형식으로 읽기 arrByte = streamToByteArray(data); //Byte Array로 변환 var path = Path.Combine($"Image"); if (!Directory.Exists(path)) Directory.CreateDirectory(path); // 웹 서비스 내 업로드폴더가 없을 경우 자동생성을 위한 처리 DataCenter.getInstance().setFileStatus(filename, DataCenter.FILE_STATUS_CODE.UPLOADING); FileStream fileStream = new FileStream(@"Image\" + filename, FileMode.Create); fileStream.Write(arrByte, 0, arrByte.Length); fileStream.Close(); DataCenter.getInstance().setFileStatus(filename, DataCenter.FILE_STATUS_CODE.UPDATE_COMPLETED); } context.Response.Headers.Clear(); //context.Response.SendChunked = false; context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); context.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET"); context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With"); context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.StatusDescription = "OK"; string returnValue = filename + " 파일업로드 완료"; var bytes = Encoding.UTF8.GetBytes(returnValue); context.Response.KeepAlive = false; context.Response.OutputStream.Write(bytes, 0, bytes.Length); context.Response.OutputStream.Close(); Console.WriteLine(returnValue); Program.mainForm.recvLog(TAG, returnValue + Environment.NewLine); } //다운로드 else if (HttpUtility.UrlDecode(request.RawUrl).Contains("/파일다운로드")) { string 파일이름 = HttpUtility.UrlDecode(request.RawUrl).Replace("/파일다운로드/", ""); var path = Environment.CurrentDirectory + @"\image\"; path = Path.Combine(path, 파일이름); if (System.IO.File.Exists(path)) { byte[] bytes; using (FileStream file = new FileStream(path: path, mode: FileMode.Open)) // 배포환경에선 다운로드폴더에 대한 권한설정작업이 필요할 수 있다. { try { bytes = new byte[file.Length]; file.Read(bytes, 0, bytes.Length); context.Response.Headers.Clear(); //context.Response.SendChunked = false; context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); context.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET"); context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With"); context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.StatusDescription = "OK"; context.Response.KeepAlive = false; context.Response.OutputStream.Write(bytes, 0, bytes.Length); context.Response.OutputStream.Close(); return; } catch (Exception ex) { } } } else { } } //기존방식의 값들 else { string returnValue = ARequestObject.create(HttpUtility.UrlDecode(request.RawUrl)); context.Response.Headers.Clear(); //context.Response.SendChunked = false; context.Response.Headers.Add("Access-Control-Allow-Origin", "*"); context.Response.Headers.Add("Access-Control-Allow-Methods", "POST, GET"); context.Response.Headers.Add("Access-Control-Allow-Headers", "Content-Type, Accept, X-Requested-With"); context.Response.StatusCode = (int)HttpStatusCode.OK; context.Response.StatusDescription = "OK"; var bytes = Encoding.UTF8.GetBytes(returnValue); context.Response.KeepAlive = false; context.Response.OutputStream.Write(bytes, 0, bytes.Length); context.Response.OutputStream.Close(); Console.WriteLine(returnValue); Program.mainForm.recvLog(TAG, returnValue + Environment.NewLine); return; } } } catch (Exception ex) { try { //var bytes = Encoding.UTF8.GetBytes(ex.ToString() + "____" + ex.Message + "____" + request.RawUrl); //context.Response.OutputStream.Write(bytes, 0, bytes.Length); Console.WriteLine(DateTime.Now.ToShortTimeString() + " " + ex.ToString() + "____" + ex.Message + "____" + request.RawUrl); } catch (Exception ex2) { //var bytes = Encoding.UTF8.GetBytes("알수없는오류"); //context.Response.OutputStream.Write(bytes, 0, bytes.Length); Console.WriteLine(DateTime.Now.ToShortTimeString() + " " + ex2.ToString() + "____" + ex2.Message + "____" + request.RawUrl); } } context.Response.OutputStream.Close(); } } }