/// <summary> /// Pass the query across the network to the server side and get the responce back. /// In case of an remote sede exception inside MessageHandler delegate /// it will be raised localy as RemotingHandlerException /// </summary> /// <param name="parameters">Hold input key value pairs and gets output up on return</param> public void Query(RemotingParams parameters) { foreach (KeyValuePair<string, string> kvp in parameters.Input) { wr.WriteLine("{0} {1}", kvp.Key.Replace('\r', ' ').Replace('\n', ' '), kvp.Value.Length); wr.Write(kvp.Value); wr.Flush(); string confirm = rd.ReadLine(); if (confirm != "202 OK") throw new RemotingProtocolException("Unexpected remoting server response " + confirm); } wr.WriteLine("EXEC"); wr.Flush(); string response = rd.ReadLine(); string[] result = response.Split(new char[] { ' ' }); if (result.Length == 3) { if ((result[0] == "500") && (result[1] == "EXCEPTION")) { throw new RemotingHandlerException(ResponseBlock(result[2],response)); } if ((result[0] == "200") && (result[1] == "OK")) { parameters.Output.Clear(); int count = 0; try { count = int.Parse(result[2]); for (int i = 0; i < count; i++) { response = rd.ReadLine(); int sep = response.LastIndexOf(' '); string field = sep < 0 ? null : response.Substring(0, sep); string value = response.Substring(sep + 1); parameters.Output[field] = ResponseBlock(value, response); } return; } catch { } } } throw new RemotingProtocolException("Unexpected remoting server response " + response); }
/// <summary> /// Main network dialog for each new connection /// </summary> /// <param name="socket"></param> private void HandleClient(object socket) { RemotingParams rp = new RemotingParams(); try { using (Stream strm = new NetworkStream((Socket)socket, false)) { StreamReader rd = new StreamReader(strm); StreamWriter wr = new StreamWriter(strm); rp.Phase = RemotingPhase.Established; handler(rp); wr.WriteLine("200 READY {0}",VERSION); wr.Flush(); rp.Phase = RemotingPhase.Query; while (!rd.EndOfStream) { string line = rd.ReadLine(); int sep = line.LastIndexOf(' '); if (line == string.Empty) { wr.WriteLine("204 BYE"); wr.Flush(); break; } string field = sep < 0 ? null : line.Substring(0, sep); string value = line.Substring(sep + 1); if (field == null) // command passed in value { if (value == "EXEC") { try { handler(rp); } catch (Exception ex) { string msg = ex.ToString(); wr.WriteLine("500 EXCEPTION {0}", msg.Length); wr.Write(msg); wr.Flush(); continue; } wr.WriteLine("200 OK {0}", rp.Output.Count); foreach (KeyValuePair<string, string> kvp in rp.Output) { wr.WriteLine("{0} {1}", kvp.Key.Replace('\r', ' ').Replace('\n', ' '), kvp.Value.Length); wr.Write(kvp.Value); } wr.Flush(); rp.Input.Clear(); rp.Output.Clear(); continue; } wr.WriteLine("404 UNKNOWN"); wr.Flush(); continue; } int blocklen = 0; try { blocklen = int.Parse(value); } catch { wr.WriteLine("400 MAILFORMED"); wr.Flush(); continue; } if (blocklen > MAX_PARAM_LENGTH) { wr.WriteLine("406 OVERSIZE"); wr.Flush(); break; } char[] buf = new char[blocklen]; rd.ReadBlock(buf, 0, blocklen); rp.Input[field] = new string(buf); wr.WriteLine("202 OK"); wr.Flush(); } strm.Close(); } } catch { } finally { rp.Input.Clear(); rp.Output.Clear(); rp.Phase = RemotingPhase.Disposing; handler(rp); rp.Session.Clear(); } }