private bool DefaultHelpHandler(HttpServerRequestInfo info) { var items = new List <string>(); foreach (var p in Prefixes) { if (p == null || p == "" || p == "help") { continue; } if (p.EndsWith(".GET")) { items.Add(p.Sub(0, -4)); continue; } if (p.EndsWith(".POST")) { items.Add(p.Sub(0, -5)); continue; } if (p.EndsWith(".PUT")) { items.Add(p.Sub(0, -4)); continue; } if (p.EndsWith(".DELETE")) { items.Add(p.Sub(0, -7)); continue; } items.Add(p); } info.Context.SendReply(items.Distinct().Join(", ")); return(true); }
public void Start() { lock (m_lock) { if (m_isRunning) { Report.Line(5, "WARNING: HttpServer already running - doing nothing"); return; } m_isRunning = true; } // listen on default uri if no user-specified prefix is given // default is: http:\\<first local ip address>:4242/ if (m_listener.Prefixes.Count == 0) { if (s_defaultPrefix == null) { var localIP = Dns.GetHostAddresses(Dns.GetHostName()) .Where(x => x.AddressFamily == AddressFamily.InterNetwork) .FirstOrDefault() ; if (localIP != null) { s_defaultPrefix = string.Format("http://{0}:4242/", localIP.ToString()); } else { s_defaultPrefix = "http://localhost:4242/"; } } m_listener.Prefixes.Add(s_defaultPrefix); } try { Report.Line(4, "[starting] kernel http server"); m_listener.Start(); Report.Line(4, "[started ] kernel http server"); Report.Line(4, " listening on {0}", m_listener.Prefixes.Select(x => x).Join(", ") ); } catch (Exception e) { // catch all - if listening fails for any reason // then report exception and continue without kernel http server Report.Line("[info] failed to listen on {0}", s_defaultPrefix); Report.Line(" {0}", e.ToString()); lock (m_lock) m_isRunning = false; return; // do not start server loop } // http server loop Task.Factory.StartNew(delegate { while (!m_stop) { try { var context = m_listener.GetContext(); if (m_stop) { break; } #region Init HttpServerRequestInfo var info = new HttpServerRequestInfo() { Context = context }; // init route var route = context.Request.RawUrl; var queryStartIndex = route.IndexOf('?'); if (queryStartIndex >= 0) { // cut off query part of uri route = route.Substring(0, queryStartIndex); } if (route.Length > 0 && route.Right(1) == "/") { // cut off trailing '/' route = route.Substring(0, route.Length - 1); } info.Route = route; // init verb switch (context.Request.HttpMethod) { case "GET": info.Verb = Http.Verb.GET; break; case "POST": info.Verb = Http.Verb.POST; break; case "PUT": info.Verb = Http.Verb.PUT; break; case "DELETE": info.Verb = Http.Verb.DELETE; break; } // init query var query = context.Request.QueryString; for (int i = 0; i < query.Count; i++) { info.Query[query.GetKey(i)] = query.GetValues(i).Join(";"); } #endregion if (m_dispatcher2 == null) { // dispatch (old-style) Task.Factory.StartNew(delegate { try { bool handled = m_dispatcher.Dispatch(info); // if no handler matches reply "not found" if (!handled) { context.SendReply(s_notFoundReply, HttpStatusCode.NotFound); } } catch (Exception e) { Report.Warn("HttpServer: {0}", e.ToString()); } }); } else { // dispatch new-style var match = m_dispatcher2.Dispatch(info.Route, info.Verb, info.Query); if (match == null) { Task.Factory.StartNew(delegate { context.SendReply(s_notFoundReply, HttpStatusCode.NotFound); }); } else { Task.Factory.StartNew(delegate { match.Handler(info); }); } } } catch (Exception e) { // catch all - the server loop must not end // [ISSUE 20080715 sm> handle case when the thread itself dies // -> has to be resurrected by the kernel Report.Line(4, "HttpServer: {0}", e.ToString()); Thread.Sleep(100); } } m_stop = false; lock (m_lock) m_isRunning = false; }); }
/// <summary> /// Returns true if route has been handled. /// </summary> internal bool Dispatch(HttpServerRequestInfo info) { string route = info.Route; bool routeHasBeenHandled = false; // 0. preconditions // (e.g. "/foo/bar/woohoo" -> "foo/bar/woohoo") if (route != null && route.Length > 0 && route[0] == '/') { route = route.Substring(1); } // 1. split route into head and tail string head, tail; int separatorIndex = route.IndexOf('/'); if (separatorIndex < 0) { head = route; tail = ""; } else { head = route.Substring(0, separatorIndex); tail = route.Substring(separatorIndex + 1); } // 2. call handlers & dispatchers List <Func <HttpServerRequestInfo, bool> > handlers; if (m_handlers.TryGetValue("", out handlers)) { foreach (var handler in handlers) { routeHasBeenHandled |= handler(info); } } var storeRoute = info.Route; var storeHead = info.Head; info.Route = tail; info.Head = head; if (m_handlers.TryGetValue(head, out handlers)) { foreach (var handler in handlers) { routeHasBeenHandled |= handler(info); } } if (m_handlers.TryGetValue(head + "." + info.Verb.ToString(), out handlers)) { foreach (var handler in handlers) { routeHasBeenHandled |= handler(info); } } List <HttpServerDispatcher> dispatchers; if (m_dispatchers.TryGetValue(head, out dispatchers)) { foreach (var dispatcher in dispatchers) { routeHasBeenHandled |= dispatcher.Dispatch(info); } } info.Head = storeHead; info.Route = storeRoute; return(routeHasBeenHandled); }