public void EvalChart(RCRunner runner, RCClosure closure, RCLong right) { RCCube result = new RCCube(new RCArray <string> ("S")); DoChart <long> (result, RCSymbolScalar.Empty, 0, 0, right); runner.Yield(closure, result); }
public void EvalHttpTest(RCRunner runner, RCClosure closure, RCString left, RCLong right) { RequestInfo info; Cookie cookie; runner.Yield(closure, new RCBoolean(DoHttpTest(left, right, out info, out cookie))); }
public void EvalTrace(RCRunner runner, RCClosure closure, RCSymbol right) { try { // This read is different from all others in that it has force on and fill off. // force causes duplicate values to be written. // fill causes prior values to be filled into the results. // This read gives you exactly what exists in the blackboard. RCLong args = new RCLong(0, 0); Section section = GetSection(right); Read(runner, closure, right, new ReadSpec(section._counter, right, args, 0, false, true, false, true)); } catch (Exception) { throw; } }
public void EvalHttpBody(RCRunner runner, RCClosure closure, RCLong right) { if (right.Count > 1) { throw new Exception("httpbody only allows one request per call"); } RequestInfo info; lock (_lock) { info = _contexts[(int)right[0]]; } string body = new StreamReader(info.Context.Request.InputStream).ReadToEnd(); // ParseQueryString really means ParseUrlEncodedForm. NameValueCollection values = HttpUtility.ParseQueryString(body); RCBlock result = RCBlock.Empty; for (int i = 0; i < values.AllKeys.Length; ++i) { string key = values.AllKeys[i]; result = new RCBlock(result, key, ":", new RCString(values[key])); } runner.Yield(closure, result); }
public void Kill(object other) { RCAsyncState state = (RCAsyncState)other; try { RCLong signal = (RCLong)state.Other; RCSystem.Log.Record(null, "exec", Handle, "killx", signal[0]); lock (this) { #if __MonoCS__ Mono.Unix.Native.Syscall.kill( (int)_pid, (Mono.Unix.Native.Signum)signal[0]); #else KillById((int)_pid); #endif } state.Runner.Yield(state.Closure, signal); } catch (Exception ex) { state.Runner.Report(state.Closure, ex); } }
protected bool DoHttpTest(RCString left, RCLong right, out RequestInfo info, out Cookie cookie) { // Let's have only one listener at a time, at least for now. if (right.Count > 1) { throw new Exception("Can only httprecv from one listener per call"); } if (left.Count == 0) { throw new Exception( "Left argument must have the form \"id\" \"SESSION_ID1\" \"SESSION_ID2\""); } lock (_lock) { info = _contexts[(int)right[0]]; } cookie = info.Context.Request.Cookies[left[0]]; bool cookieCheckPassed = false; if (cookie != null) { for (int i = 1; i < left.Count; ++i) { if (cookie.Value.Equals(left[i])) { cookieCheckPassed = true; } if (cookieCheckPassed) { break; } } } return(cookieCheckPassed); }
public void EvalHttpCheck(RCRunner runner, RCClosure closure, RCString left, RCLong right) { RequestInfo info; Cookie cookie; bool cookieCheckPassed = DoHttpTest(left, right, out info, out cookie); if (!cookieCheckPassed) { info.Context.Response.StatusCode = 401; // I wanted to add a Set-Cookie header to blow away any bad // cookies and force the user to log out, but it simply refuses // to add it (or other headers such as Location) // This problem goes away if you don't return an Error status. // This is a bug in HttpListener according to this: // https://stackoverflow.com/questions/21554280/can-cookies-be-set-from-4xx-responses // Otherwise something like this ought to work // cookie.Name = left[0]; // cookie.Value = ""; // cookie.Expires = DateTime.UtcNow.AddDays (-1); // info.Context.Response.AppendCookie (cookie); // Here is also an rclt test for this if it comes time to implement // httpcheck_cookie_invalid:{ // src:{ // ID1:"id" & guid 1 // ID2:"id" & guid 1 // serve:{ // loop:{ // :($ID2 httpcheck httprecv $R) httpsend { // status:200 // body:"super content" // } // <-loop $R // } // :try {<-loop $R} // <-serve $R // } // b:bot {<-serve httpstart "http://*:6235/foo/"} // junk:"; Expires=Fri, 08-Dec-2017 00:45:41 GMT; Path=/" // response:(eval { // Cookie:"=" delimit $ID1 // }) getw "http://localhost:6235/foo" // :"$response.status assert 400" // :"$response.body assert \"Unauthorized\"" // :$response.head assert {'Set-Cookie':""} // response:(eval {Cookie:"=" delimit $ID2}) getw "http://localhost:6235/foo" // :$response.status assert 401 // :$response.body assert "Unauthorized" // :kill $b // } // } info.Context.Response.OutputStream.Close(); RCSystem.Log.Record(closure, "http", right[0], "session", cookie != null ? cookie.Value : "null"); throw new RCException(closure, RCErrors.Session, "Invalid session id"); } runner.Yield(closure, right); }
public void EvalPage(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong right) { int pageNumber = 0; if (right.Count > 0) { pageNumber = (int)right[0]; } int pageSize = int.MaxValue; if (right.Count > 1) { pageSize = (int)right[1]; } // Page lets you access the blackboard by page number and page size, rather than row // numbers. // Good for building tools for looking at blackboard contents. lock (_readWriteLock) { Section s = GetSection(symbol); int skipFirst = pageNumber * pageSize; int stopAfter = pageSize; ReadSpec spec = new ReadSpec(s._counter, symbol, skipFirst, stopAfter, false); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); runner.Yield(closure, result); } }
public void EvalGawk(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong right) { int limit = (int)right[0]; lock (_readWriteLock) { Section s = GetSection(symbol); ReadSpec spec = s._counter.GetReadSpec(symbol, limit, false, true); Satisfy canSatisfy = s._counter.CanSatisfy(spec); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); if ((spec.SymbolUnlimited && result.Count > 0) || (!spec.SymbolUnlimited && result.Count >= symbol.Count * Math.Abs(spec.SymbolLimit))) { if (canSatisfy != Satisfy.Yes) { throw new Exception(); } runner.Yield(closure, result); } else { if (canSatisfy != Satisfy.No) { throw new Exception(); } s._dispatchWaiters.Enqueue(symbol, closure); } } }
public void EvalPeek(RCRunner runner, RCClosure closure, RCSymbol left, RCLong right) { int limit = (int)right[0]; lock (_readWriteLock) { Section s = GetSection(left); ReadSpec spec = s._counter.GetReadSpec(left, limit, false, true); Satisfy canSatisfy = s._counter.CanSatisfy(spec); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); if ((spec.SymbolUnlimited && result.Count > 0) || (!spec.SymbolUnlimited && result.Count >= left.Count * Math.Abs(spec.SymbolLimit))) { // If dispatch would yield, return lines. if (canSatisfy != Satisfy.Yes) { throw new Exception(); } runner.Yield(closure, RCBoolean.True); } else { if (canSatisfy != Satisfy.No) { throw new Exception(); } runner.Yield(closure, RCBoolean.False); } } }
public void EvalHttpHeader(RCRunner runner, RCClosure closure, RCLong right) { if (right.Count > 1) { throw new Exception("httpheader only allows one request per call"); } RequestInfo info; lock (_lock) { info = _contexts[(int)right[0]]; } NameValueCollection values = info.Context.Request.Headers; RCBlock result = RCBlock.Empty; result = new RCBlock(result, "Verb", ":", new RCString(info.Context.Request.HttpMethod)); result = new RCBlock(result, "RawUrl", ":", new RCString(info.Context.Request.RawUrl)); result = new RCBlock(result, "Url", ":", new RCString( info.Context.Request.Url.AbsolutePath)); for (int i = 0; i < values.AllKeys.Length; ++i) { string key = values.AllKeys[i]; result = new RCBlock(result, key, ":", new RCString(values[key])); } runner.Yield(closure, result); }
public void HttpWait(RCRunner runner, RCClosure closure, RCLong right) { lock (_lock) { this._timeout = (int)right[0]; } RCSystem.Log.Record(closure, "web", 0, "httptimeout", right[0]); runner.Yield(closure, right); }
protected RCValue ReorderColumn <T> (RCLong rank, RCVector <T> column) where T : IComparable <T> { return(RCVectorBase.FromArray( VectorMath.MonadicOp <long, T> (rank.Data, delegate(long r) { return column[(int)r]; }))); }
public void EvalSelect(RCRunner runner, RCClosure closure, RCSymbol left, RCCube right) { RCLong args = new RCLong(0, 0); ReadCounter counter = new ReadCounter(right); ReadSpec spec = new ReadSpec(counter, left, args, 0, false, false, true, false); RCCube result = right.Read(spec, counter, true, right.Count); runner.Yield(closure, result); }
public void HttpRetry(RCRunner runner, RCClosure closure, RCLong right) { lock (_lock) { this._retry = (int)right[0]; } RCSystem.Log.Record(closure, "web", 0, "httpretry", right[0]); runner.Yield(closure, right); }
public void EvalTo(RCRunner runner, RCClosure closure, RCLong left, RCLong right) { long[] result = new long[right[0] - left[0] + 1]; for (long i = 0; i < result.Length; ++i) { result[i] = left[0] + i; } runner.Yield(closure, new RCLong(result)); }
protected void DoAccept(RCRunner runner, RCClosure closure, RCLong left, RCLong right) { RCBot bot = runner.GetBot(closure.Bot); for (int i = 0; i < left.Count; ++i) { Server server = (Server)bot.Get(left[i]); server.Accept(runner, closure, right[0]); } }
public void EvalPad(RCRunner runner, RCClosure closure, RCString left, RCLong right) { RCArray <string> result = new RCArray <string> (right.Count); for (int i = 0; i < right.Count; ++i) { string padding = "".PadRight((int)right[i], left[0][0]); result.Write(padding); } runner.Yield(closure, new RCString(result)); }
public void EvalPoll(RCRunner runner, RCClosure closure, RCSymbol symbol, RCLong starts) { // Poll is like read but it will never block. lock (_readWriteLock) { Section s = GetSection(symbol); ReadSpec spec = s._counter.GetReadSpec(symbol, starts, false, true); RCCube result = s._blackboard.Read(spec, s._counter, true, s._blackboard.Count); runner.Yield(closure, result); } }
public static RCBlock DoAt(RCClosure closure, RCBlock left, RCLong right) { RCBlock result = RCBlock.Empty; for (int i = 0; i < right.Count; ++i) { RCBlock next = left.GetName(right[i]); result = new RCBlock(result, next.Name, next.Evaluator, next.Value); } return(result); }
public void EvalAscii(RCRunner runner, RCClosure closure, RCLong right) { byte[] bytes = new byte[right.Count]; for (int i = 0; i < bytes.Length; ++i) { bytes[i] = (byte)right[i]; } string result = Encoding.ASCII.GetString(bytes); runner.Yield(closure, new RCString(result)); }
public void EvalHttpSend(RCRunner runner, RCClosure closure, RCLong left, RCBlock right) { try { DoHttpSend(runner, closure, left, right); } catch (Exception) { throw; } }
public void EvalSwitch(RCRunner runner, RCClosure closure, RCLong left, RCBlock right) { // What on earth was I thinking... we need to make this work. Picker <long> picker = delegate(long val, out bool eval) { RCBlock variable = right.GetName(val); eval = !variable.Evaluator.Pass; return(variable.Value); }; DoSwitch <long> (runner, closure, left, right, picker); }
public void EvalGuid(RCRunner runner, RCClosure closure, RCLong right) { int guids = (int)right[0]; RCArray <string> result = new RCArray <string> (guids); for (int i = 0; i < guids; ++i) { Guid guid = Guid.NewGuid(); result.Write(guid.ToString()); } runner.Yield(closure, new RCString(result)); }
public void EvalTime(RCRunner runner, RCClosure closure, RCSymbol left, RCLong right) { RCArray <RCTimeScalar> result = new RCArray <RCTimeScalar> (); string name = left[0].Part(0).ToString(); RCTimeType type = (RCTimeType)Enum.Parse(typeof(RCTimeType), name, true); for (int i = 0; i < right.Count; ++i) { result.Write(new RCTimeScalar(new DateTime(right[i]), type)); } runner.Yield(closure, new RCTime(result)); }
public void EvalHttpSend(RCRunner runner, RCClosure closure, RCLong left, RCByte right) { try { // Maybe we should send multiple here? DoHttpSend(runner, closure, left, right.ToArray()); } catch (Exception) { throw; } }
public void EvalTree(RCRunner runner, RCClosure closure, RCLong right) { RCCube result = new RCCube(new RCArray <string> ("S")); TreeNode root = new TreeNode(RCSymbolScalar.Empty, RCSymbolScalar.Empty); root.children = new RCArray <TreeNode> (); DoTree <long> (root, right, ref root.n, ref root.g, Areal, Formatl); LayoutBottomUp(root, 0); LayoutTree(0, root); WriteTree(result, root); runner.Yield(closure, result); }
public void EvalRandomd(RCRunner runner, RCClosure closure, RCLong left, RCLong right) { int seed = (int)left[0]; Random random = new Random(seed); long count = right[0]; double[] result = new double[count]; for (long i = 0; i < count; ++i) { result[i] = random.NextDouble(); } runner.Yield(closure, new RCDouble(result)); }
public void EvalGet(RCRunner runner, RCClosure closure, RCLong left, RCBlock right) { if (left.Count != 1) { throw new Exception("left argument may only contain a single index"); } RCValue result = right.Get(left[0]); if (result == null) { throw new RCException(closure, RCErrors.Range, "Index " + left[0] + " is out of range"); } runner.Yield(closure, result); }
protected void DoHttpSend(RCRunner runner, RCClosure closure, RCLong left, string message) { RCBlock result = RCBlock.Empty; int total = 0; try { for (int i = 0; i < left.Count; ++i) { RequestInfo info; lock (_lock) { info = _contexts[(int)left[i]]; } try { byte[] payload = Encoding.UTF8.GetBytes(message); byte[] buffer = new byte[1024 * 16]; MemoryStream stream = new MemoryStream(payload); int nbytes; while ((nbytes = stream.Read(buffer, 0, buffer.Length)) > 0) { info.Context.Response.OutputStream.Write(buffer, 0, nbytes); total += nbytes; } result = CreateLogEntry(info, left[i], total); } catch (Exception ex) { runner.Report(closure, ex); result = CreateLogEntry(info, left[i], 0); } finally { RCSystem.Log.Record(closure, "http", left[i], "send", result); info.Context.Response.OutputStream.Close(); info.Context.Request.InputStream.Close(); lock (_lock) { _contexts.Remove((int)left[i]); } } } } catch (Exception ex) { runner.Report(closure, ex); } runner.Yield(closure, result); }