Ejemplo n.º 1
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;
        }