private void Run() { this.unix_listener.Start(); if (!Shutdown.WorkerStart(this, String.Format("server '{0}'", socket_path))) { return; } while (this.running) { UnixClient client; try { // This will block for an incoming connection. // FIXME: But not really, it'll only wait a second. // see the FIXME in UnixListener for more info. client = this.unix_listener.AcceptUnixClient(); } catch (SocketException) { // If the listener is stopped while we // wait for a connection, a // SocketException is thrown. break; } // FIXME: This is a hack to work around a mono // bug. See the FIXMEs in UnixListener.cs for // more info, but client should never be null, // because AcceptUnixClient() should be // throwing a SocketException when the // listener is shut down. So when that is // fixed, remove the if conditional. // If client is null, the socket timed out. if (client != null) { ConnectionHandler handler = new UnixConnectionHandler(client); lock (live_handlers) live_handlers [handler] = handler; ExceptionHandlingThread.Start(new ThreadStart(handler.HandleConnection)); } } Shutdown.WorkerFinished(this); Logger.Log.Debug("Server '{0}' shut down", this.socket_path); }
private bool WorkerStartNoLock(object o) { if (!Shutdown.WorkerStart(o)) { return(false); } DateTime now = DateTime.Now; per_worker_started_time [o] = now; ++workers; if (workers == 1) { started_time = now; if (StartedEvent != null) { StartedEvent(this); } } return(true); }
private void HttpRun() { http_listener = new HttpListener(); string prefix = null; int port = 4000; bool success = false; string host = "localhost"; if (enable_network_svc) { host = "*"; } do { prefix = String.Format("http://{0}:{1}/", host, port); success = true; try { http_listener.Prefixes.Add(prefix); http_listener.Start(); } catch (SocketException) { http_listener.Prefixes.Remove(prefix); success = false; port++; } } while (!success); Shutdown.WorkerStart(this.http_listener, String.Format("HTTP Server '{0}'", prefix)); Log.Always("HTTP Server: Listening on {0}", prefix); while (this.running) { HttpListenerContext context = null; try { context = http_listener.GetContext(); } catch (Exception e) { // Log a warning if not due to shutdown if (!this.running || (!this.enable_network_svc && !this.webinterface)) { break; } Logger.Log.Warn(e, "HTTP Server: Exception while getting context:"); } if (context == null) { continue; } if (context.Request.HttpMethod == "GET") { try { WebServer.HandleStaticPages(context); } catch (IOException ex1) { // Socket was shut down Log.Debug("Exception while serving static page: " + ex1.Message); // FIXME: Should anything be done here to free "context" ? This context seems to remain in http_listener's ctxt table } catch (SocketException ex2) { // Socket is not connected anymore Log.Debug("Exception while serving static page: " + ex2.Message); } continue; } if (context.Request.HttpMethod != "POST") { // FIXME: Send better HTTP error ? context.Response.StatusCode = 404; context.Response.Close(); continue; } if (context.Request.RawUrl == "/") { // We have received a new query request Guid guid = Guid.NewGuid(); HttpItemHandler item_handler = new HttpItemHandler(); item_handlers [guid] = item_handler; ConnectionHandler handler = new HttpConnectionHandler(guid, context, item_handler); lock (live_handlers) live_handlers [handler] = handler; ExceptionHandlingThread.Start(new ThreadStart(handler.HandleConnection)); } else { // We have received a hit request Uri uri = context.Request.Url; string path = null; // Second Uri segment contains the Guid string g = uri.Segments [1]; if (g [g.Length - 1] == '/') { g = g.Remove(g.Length - 1, 1); } Guid guid = Guid.Empty; try { guid = new Guid(g); } catch (FormatException) { // FIXME: return HTTP error Logger.Log.Debug("HTTP Server: Invalid query guid '{0}'", g); context.Response.Close(); continue; } if (uri.Query.Length > 0) { path = uri.Query.Remove(0, 1); } else { // FIXME: return HTTP error Logger.Log.Debug("HTTP Server: Empty query string in item request"); context.Response.Close(); continue; } System.Uri item_uri = new Uri(path); HttpItemHandler handler = (HttpItemHandler)item_handlers [guid]; if (handler == null) { // FIXME: return HTTP error Logger.Log.Debug("HTTP Server: Query ({0}) does not exist", g); context.Response.Close(); } else { Logger.Log.Debug("HTTP Server: Asked for item '{0}' on query '{1}'", path, g); handler.HandleRequest(context, item_uri); } } } Shutdown.WorkerFinished(http_listener); Logger.Log.Info("HTTP Server: '{0}' shut down...", prefix); http_listener = null; }
public override void HandleConnection() { this.thread = Thread.CurrentThread; bool force_close_connection = false; // Read the data off the socket and store it in a // temporary memory buffer. Once the end-of-message // character has been read, discard remaining data // and deserialize the request. byte[] network_data = new byte [4096]; MemoryStream buffer_stream = new MemoryStream(); int bytes_read, total_bytes = 0, end_index = -1; // We use the network_data array as an object to represent this worker. Shutdown.WorkerStart(network_data, String.Format("HandleConnection ({0})", ++connection_count)); do { bytes_read = 0; try { lock (this.blocking_read_lock) this.in_blocking_read = true; lock (this.client_lock) { // The connection may have been closed within this loop. if (this.client != null) { bytes_read = this.client.GetStream().Read(network_data, 0, 4096); } } lock (this.blocking_read_lock) this.in_blocking_read = false; } catch (Exception e) { // Aborting the thread mid-read will // cause an IOException to be thorwn, // which sets the ThreadAbortException // as its InnerException.MemoryStream if (!(e is IOException || e is ThreadAbortException)) { throw; } // Reset the unsightly ThreadAbortException Thread.ResetAbort(); Logger.Log.Debug("Bailing out of HandleConnection -- shutdown requested"); this.thread = null; Server.MarkHandlerAsKilled(this); Shutdown.WorkerFinished(network_data); return; } total_bytes += bytes_read; if (bytes_read > 0) { // 0xff signifies end of message end_index = Array.IndexOf <byte> (network_data, (byte)0xff); buffer_stream.Write(network_data, 0, end_index == -1 ? bytes_read : end_index); } } while (bytes_read > 0 && end_index == -1); // Something just connected to our socket and then // hung up. The IndexHelper (among other things) does // this to check that a server is still running. It's // no big deal, so just clean up and close without // running any handlers. if (total_bytes == 0) { force_close_connection = true; goto cleanup; } buffer_stream.Seek(0, SeekOrigin.Begin); HandleConnection(buffer_stream); cleanup: buffer_stream.Close(); if (force_close_connection) { Close(); } else { SetupWatch(); } Server.MarkHandlerAsKilled(this); Shutdown.WorkerFinished(network_data); }
public override void HandleConnection() { //Logger.Log.Debug ("HTTP Server: Serving request for {0}", context.Request.Url); // Query request: read content and forward to base.HandleConnection for processing context.Response.KeepAlive = true; context.Response.ContentType = "text/txt; charset=utf-8"; context.Response.SendChunked = true; Shutdown.WorkerStart(this.context.Request.InputStream, String.Format("HandleConnection ({0})", ++connection_count)); // Read the data off the socket and store it in a // temporary memory buffer. Once the end-of-message // character has been read, discard remaining data // and deserialize the request. byte[] network_data = new byte [4096]; MemoryStream buffer_stream = new MemoryStream(); int bytes_read, total_bytes = 0, end_index = -1; do { bytes_read = 0; try { lock (this.blocking_read_lock) this.in_blocking_read = true; lock (this.client_lock) { // The connection may have been closed within this loop. if (this.context != null) { bytes_read = this.context.Request.InputStream.Read(network_data, 0, 4096); } } lock (this.blocking_read_lock) this.in_blocking_read = false; } catch (Exception e) { // Aborting the thread mid-read will // cause an IOException to be thorwn, // which sets the ThreadAbortException // as its InnerException.MemoryStream if (!(e is IOException || e is ThreadAbortException)) { throw; } // Reset the unsightly ThreadAbortException Thread.ResetAbort(); Logger.Log.Debug("Bailing out of HandleConnection -- shutdown requested"); this.thread = null; Server.MarkHandlerAsKilled(this); Shutdown.WorkerFinished(context.Request.InputStream); return; } total_bytes += bytes_read; if (bytes_read > 0) { // 0xff signifies end of message end_index = Array.IndexOf <byte> (network_data, (byte)0xff); buffer_stream.Write(network_data, 0, end_index == -1 ? bytes_read : end_index); } } while (bytes_read > 0 && end_index == -1); //Logger.Log.Debug ("HTTP Server: Handling received request message"); // The 0xff bytes from a remote beagrepd comes in a separate http request // and causes havoc by creating empty messages. HTTP streams do not behave // like a continous stream like UnixStream if (total_bytes > 0) { buffer_stream.Seek(0, SeekOrigin.Begin); base.HandleConnection(buffer_stream); } Server.MarkHandlerAsKilled(this); Shutdown.WorkerFinished(context.Request.InputStream); }