//--- Constructors ---

        /// <summary>
        /// Create a new message.
        /// </summary>
        /// <param name="status">Http status.</param>
        /// <param name="headers">Header collection.</param>
        public DreamMessage(DreamStatus status, DreamHeaders headers)
        {
            this.Status  = status;
            this.Headers = new DreamHeaders(headers);
            _bytes       = new byte[0];
            _noContent   = true;
        }
Пример #2
0
        internal static XDoc ExecuteFork(Plug env, DreamHeaders headers, XDoc fork)
        {
            // execute script commands
            XDoc   reply = new XDoc("results");
            string ID    = fork["@ID"].Contents;

            if (!string.IsNullOrEmpty(ID))
            {
                reply.Attr("ID", ID);
            }

            // TODO (steveb): we should use a 'fixed capacity' cue which marks itself as done when 'count' is reached

            XDoc forks = fork.Elements;

            foreach (XDoc cmd in forks)
            {
                // TODO (steveb): we should be doing this in parallel, not sequentially!

                try {
                    reply.Add(ExecuteCommand(env, headers, cmd));
                } catch (Exception e) {
                    reply.Add(new XException(e));
                }
            }
            return(reply);
        }
        /// <summary>
        /// Create a new message.
        /// </summary>
        /// <param name="status">Http status.</param>
        /// <param name="headers">Header collection.</param>
        /// <param name="contentType">Content Mime-Type.</param>
        /// <param name="bytes">Message body.</param>
        public DreamMessage(DreamStatus status, DreamHeaders headers, MimeType contentType, byte[] bytes)
        {
            if (bytes == null)
            {
                throw new ArgumentNullException("bytes");
            }
            this.Status  = status;
            this.Headers = new DreamHeaders(headers);
            this.Headers.ContentLength = bytes.LongLength;
            this.Headers.ContentType   = contentType ?? MimeType.DefaultMimeType;

            // set bytes
            _bytes = bytes;
        }
        /// <summary>
        /// Create a new message.
        /// </summary>
        /// <param name="status">Http status.</param>
        /// <param name="headers">Header collection.</param>
        /// <param name="contentType">Content Mime-Type</param>
        /// <param name="contentLength">Content byte langth</param>
        /// <param name="stream">Stream to uas as the source for the message's content.</param>
        public DreamMessage(DreamStatus status, DreamHeaders headers, MimeType contentType, long contentLength, Stream stream)
        {
            this.Status  = status;
            this.Headers = new DreamHeaders(headers);
            if (contentLength != -1)
            {
                this.Headers.ContentLength = contentLength;
            }
            this.Headers.ContentType = contentType ?? MimeType.DefaultMimeType;

            // set stream
            _stream     = stream ?? Stream.Null;
            _streamOpen = !_stream.IsStreamMemorized();
        }
Пример #5
0
        /// <summary>
        /// WARNING: This method is thread-blocking.  Please avoid using it if possible.
        /// </summary>
        internal static XDoc ExecutePipe(Plug env, DreamHeaders headers, XDoc pipe)
        {
            DreamMessage message = null;

            foreach (XDoc action in pipe["action"])
            {
                string verb = action["@verb"].Contents;
                string path = action["@path"].Contents;
                XUri   uri;
                if (!XUri.TryParse(path, out uri))
                {
                    uri = env.Uri.AtPath(path);
                }

                // create first message
                if (message == null)
                {
                    message = DreamMessage.Ok(GetActionBody(action));
                }
                message.Headers.AddRange(headers);

                // apply headers
                foreach (XDoc header in action["header"])
                {
                    message.Headers[header["@name"].Contents] = header.Contents;
                }

                // execute action
                message = Plug.New(uri).Invoke(verb, message);
                if (!message.IsSuccessful)
                {
                    break;
                }
            }

            // prepare response
            if (message == null)
            {
                return(XDoc.Empty);
            }
            XDoc   result = new XMessage(message);
            string ID     = pipe["@ID"].Contents;

            if (!string.IsNullOrEmpty(ID))
            {
                result.Root.Attr("ID", ID);
            }
            return(result);
        }
Пример #6
0
        internal static XDoc ExecuteScript(Plug env, DreamHeaders headers, XDoc script)
        {
            // execute script commands
            XDoc   reply = new XDoc("results");
            string ID    = script["@ID"].Contents;

            if (!string.IsNullOrEmpty(ID))
            {
                reply.Attr("ID", ID);
            }
            foreach (XDoc cmd in script.Elements)
            {
                reply.Add(ExecuteCommand(env, headers, cmd));
            }
            return(reply);
        }
Пример #7
0
        /// <summary>
        /// WARNING: This method is thread-blocking.  Please avoid using it if possible.
        /// </summary>
        internal static XDoc ExecuteAction(Plug env, DreamHeaders headers, XDoc action)
        {
            string verb = action["@verb"].Contents;
            string path = action["@path"].Contents;

            if ((path.Length > 0) && (path[0] == '/'))
            {
                path = path.Substring(1);
            }
            XUri uri;

            if (!XUri.TryParse(path, out uri))
            {
                uri = env.Uri.AtAbsolutePath(path);
            }

            // create message
            DreamMessage message = DreamMessage.Ok(GetActionBody(action));

            message.Headers.AddRange(headers);

            // apply headers
            foreach (XDoc header in action["header"])
            {
                message.Headers[header["@name"].Contents] = header.Contents;
            }

            // BUG #814: we need to support events

            // execute action
            DreamMessage reply = Plug.New(uri).Invoke(verb, message);

            // prepare response
            XDoc   result = new XMessage(reply);
            string ID     = action["@ID"].Contents;

            if (!string.IsNullOrEmpty(ID))
            {
                result.Root.Attr("ID", ID);
            }
            return(result);
        }
Пример #8
0
        /// <summary>
        /// Add a range of headers.
        /// </summary>
        /// <param name="headers">Header collection</param>
        /// <returns>Current instance.</returns>
        public DreamHeaders AddRange(DreamHeaders headers)
        {
            if (headers != null)
            {
                // add entries
                foreach (KeyValuePair <string, Entry> header in headers._headers)
                {
                    Entry existing;

                    // find existing entry
                    if (_headers.TryGetValue(header.Key, out existing))
                    {
                        existing = existing.Last;
                    }

                    // add new entries
                    for (Entry other = header.Value; other != null; other = other.Next)
                    {
                        if (existing == null)
                        {
                            existing             = new Entry(other.Value);
                            _headers[header.Key] = existing;
                        }
                        else
                        {
                            existing.Next = new Entry(other.Value);
                            existing      = existing.Next;
                        }
                    }
                }

                // add cookies
                if (headers.HasCookies)
                {
                    foreach (DreamCookie cookie in headers.Cookies)
                    {
                        Cookies.Add(cookie);
                    }
                }
            }
            return(this);
        }
        /// <summary>
        /// Create a new message.
        /// </summary>
        /// <param name="status">Http status.</param>
        /// <param name="headers">Header collection.</param>
        /// <param name="contentType">Content Mime-Type.</param>
        /// <param name="doc">Message body.</param>
        public DreamMessage(DreamStatus status, DreamHeaders headers, MimeType contentType, XDoc doc)
        {
            if (doc == null)
            {
                throw new ArgumentNullException("doc");
            }
            this.Status  = status;
            this.Headers = new DreamHeaders(headers);

            // check if document is empty
            if (doc.IsEmpty)
            {
                // we store empty XML documents as text content; it causes less confusion for browsers
                this.Headers.ContentType   = MimeType.TEXT;
                this.Headers.ContentLength = 0L;
                _doc   = doc;
                _bytes = new byte[0];
            }
            else
            {
                this.Headers.ContentType = contentType ?? MimeType.XML;
                _doc = doc.Clone();
            }
        }
Пример #10
0
        //--- Methods ---
        internal static XDoc ExecuteCommand(Plug env, DreamHeaders headers, XDoc cmd)
        {
            try {
                switch (cmd.Name.ToLowerInvariant())
                {
                case "script":
                    return(ExecuteScript(env, headers, cmd));

                case "fork":
                    return(ExecuteFork(env, headers, cmd));

                case "action":
                    return(ExecuteAction(env, headers, cmd));

                case "pipe":
                    return(ExecutePipe(env, headers, cmd));

                default:
                    throw new DreamException(string.Format("unregonized script command: " + cmd.Name.ToString()));
                }
            } catch (Exception e) {
                return(new XException(e));
            }
        }
 /// <summary>
 /// Create a new message.
 /// </summary>
 /// <param name="status">Http status.</param>
 /// <param name="headers">Header collection.</param>
 /// <param name="contentType">Content Mime-Type.</param>
 /// <param name="text">Message body.</param>
 public DreamMessage(DreamStatus status, DreamHeaders headers, MimeType contentType, string text)
     : this(status, headers, contentType, contentType.CharSet.GetBytes(text))
 {
 }
 /// <summary>
 /// Create a new message.
 /// </summary>
 /// <param name="status">Http status.</param>
 /// <param name="headers">Header collection.</param>
 /// <param name="doc">Message body.</param>
 public DreamMessage(DreamStatus status, DreamHeaders headers, XDoc doc) : this(status, headers, MimeType.XML, doc)
 {
 }
Пример #13
0
 /// <summary>
 /// Create new instance.
 /// </summary>
 /// <param name="headers">Headers to copy into new instance.</param>
 public DreamHeaders(DreamHeaders headers)
 {
     AddRange(headers);
 }