static private void Process(object parameter) { object[] tmp = parameter as object[]; GXServer server = tmp[0] as GXServer; HttpListenerContext context = tmp[1] as HttpListenerContext; IPrincipal user = tmp[2] as IPrincipal; try { ProcessRequest(server, context, user); } catch (HttpListenerException) { //Client has close connection. This is ok. } catch (Exception ex) { if (server.onError != null) { server.onError(server, new ErrorEventArgs(ex)); } context.Response.StatusCode = (int)HttpStatusCode.InternalServerError; GXErrorWrapper err = new GXErrorWrapper(ex); using (TextWriter writer = new StreamWriter(context.Response.OutputStream, Encoding.ASCII)) { GXJsonParser parser = new GXJsonParser(); string data = parser.Serialize(err); context.Response.ContentLength64 = data.Length; writer.Write(data); } } }
/// <summary> /// Listen clients as long as server is up and running. /// </summary> /// <param name="parameter"></param> void ListenThread(object parameter) { IPrincipal user; HttpListenerContext c = null; GXServer tmp = parameter as GXServer; HttpListener Listener = tmp.Listener; while (Listener.IsListening) { bool accept = false; string username, password; AutoResetEvent h = new AutoResetEvent(false); IAsyncResult result = Listener.BeginGetContext(delegate(IAsyncResult ListenerCallback) { HttpListener listener = (HttpListener)ListenerCallback.AsyncState; //If server is not closed. if (listener.IsListening) { bool html = false; try { c = listener.EndGetContext(ListenerCallback); } catch (Exception ex) { if (onError != null) { onError(this, new ErrorEventArgs(ex)); } h.Set(); return; } if (c.Request.HttpMethod == "GET" && c.Request.AcceptTypes != null) { foreach (var it in c.Request.AcceptTypes) { if (it == "text/html") { Thread thread = new Thread(new ParameterizedThreadStart(ShowServices)); thread.Start(new object[] { tmp, c }); html = true; accept = true; break; } if (it.Contains("image")) { html = true; accept = true; break; } } } if (!html) { GXWebServiceModule.TryAuthenticate(tmp.MessageMap, c.Request, out username, out password); //Anonymous access is allowed. if (username == null && password == null) { accept = true; user = null; } else { user = TryAuthenticate(username, password); accept = user != null; } if (accept) { Thread thread = new Thread(new ParameterizedThreadStart(Process)); thread.Start(new object[] { tmp, c, user }); } else { c.Response.StatusCode = 401; c.Response.StatusDescription = "Access Denied"; c.Response.AddHeader("WWW-Authenticate", "Basic Realm"); GXErrorWrapper err = new GXErrorWrapper(new HttpException(401, "Access Denied")); using (TextWriter writer = new StreamWriter(c.Response.OutputStream, Encoding.ASCII)) { GXJsonParser parser = new GXJsonParser(); string data = parser.Serialize(err); c.Response.ContentLength64 = data.Length; writer.Write(data); } c.Response.Close(); } } h.Set(); } }, Listener); EventWaitHandle.WaitAny(new EventWaitHandle[] { h, Closing }); if (!accept || !Listener.IsListening) { result.AsyncWaitHandle.WaitOne(1000); Closed.Set(); break; } } }