Beispiel #1
0
        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);
        }
Beispiel #2
0
        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);
        }
Beispiel #3
0
        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;
        }
Beispiel #4
0
        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);
        }
Beispiel #5
0
        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 beagled 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);
        }