Example #1
0
        /// <summary>
        /// Gets the http headers from a list of CoAP options. The method iterates
        /// over the list looking for a translation of each option in the predefined
        /// mapping. This process ignores the proxy-uri and the content-type because
        /// they are managed differently. If a mapping is present, the content of the
        /// option is mapped to a string accordingly to its original format and set
        /// as the content of the header.
        /// </summary>
        /// <param name="optionList"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static NameValueCollection GetHttpHeaders(IList <Option> optionList)
        {
            if (optionList == null)
            {
                ThrowHelper.ArgumentNullException("optionList");
            }

            NameValueCollection headers = new NameValueCollection(optionList.Count);

            foreach (Option opt in optionList)
            {
                // skip content-type because it should be translated while handling
                // the payload; skip proxy-uri because it has to be translated in a
                // different way
                if (opt.Type == OptionType.ContentType || opt.Type == OptionType.ProxyUri)
                {
                    continue;
                }

                String headerName;
                if (!coap2httpHeader.TryGetValue(opt.Type, out headerName))
                {
                    continue;
                }

                // format the value
                String       headerValue = null;
                OptionFormat format      = Option.GetFormatByType(opt.Type);
                if (format == OptionFormat.Integer)
                {
                    headerValue = opt.IntValue.ToString();
                }
                else if (format == OptionFormat.String)
                {
                    headerValue = opt.StringValue;
                }
                else if (format == OptionFormat.Opaque)
                {
                    headerValue = ByteArrayUtils.ToHexStream(opt.RawValue);
                }
                else
                {
                    continue;
                }

                // custom handling for max-age
                // format: cache-control: max-age=60
                if (opt.Type == OptionType.MaxAge)
                {
                    headerValue = "max-age=" + headerValue;
                }
                headers[headerName] = headerValue;
            }

            return(headers);
        }
Example #2
0
        /// <summary>
        /// Stringify options in a message.
        /// </summary>
        public static String OptionsToString(Message msg)
        {
            Boolean first = true;
            Action <StringBuilder, String, String> appendIfNotNullOrEmpty =
                delegate(StringBuilder builder, String header, String value)
            {
                if (String.IsNullOrEmpty(value))
                {
                    return;
                }

                if (first)
                {
                    first = false;
                }
                else
                {
                    builder.Append(", ");
                }
                builder.Append(header).Append("=").Append(value);
            };

            StringBuilder sb = new StringBuilder();

            appendIfNotNullOrEmpty(sb, "If-Match", ToString(msg.IfMatches, bs => ByteArrayUtils.ToHexString(bs)));
            if (msg.HasOption(OptionType.UriHost))
            {
                appendIfNotNullOrEmpty(sb, "URI-Host", msg.UriHost);
            }
            appendIfNotNullOrEmpty(sb, "ETag", ToString(msg.ETags, bs => ByteArrayUtils.ToHexString(bs)));
            if (msg.IfNoneMatch)
            {
                appendIfNotNullOrEmpty(sb, "If-None-Match", msg.IfNoneMatch.ToString());
            }
            if (msg.UriPort > 0)
            {
                appendIfNotNullOrEmpty(sb, "URI-Port", msg.UriPort.ToString());
            }
            appendIfNotNullOrEmpty(sb, "Location-Path", ToString(msg.LocationPaths));
            appendIfNotNullOrEmpty(sb, "URI-Path", ToString(msg.UriPaths));
            if (msg.ContentType != MediaType.Undefined)
            {
                appendIfNotNullOrEmpty(sb, "Content-Type", MediaType.ToString(msg.ContentType));
            }
            if (msg.HasOption(OptionType.MaxAge))
            {
                appendIfNotNullOrEmpty(sb, "Max-Age", msg.MaxAge.ToString());
            }
            appendIfNotNullOrEmpty(sb, "URI-Query", ToString(msg.UriQueries));
            if (msg.Accept != MediaType.Undefined)
            {
                appendIfNotNullOrEmpty(sb, "Accept", MediaType.ToString(msg.Accept));
            }
            appendIfNotNullOrEmpty(sb, "Location-Query", ToString(msg.LocationQueries));
            if (msg.HasOption(OptionType.ProxyUri))
            {
                appendIfNotNullOrEmpty(sb, "Proxy-URI", msg.ProxyUri.ToString());
            }
            appendIfNotNullOrEmpty(sb, "Proxy-Scheme", msg.ProxyScheme);
            if (msg.Block1 != null)
            {
                appendIfNotNullOrEmpty(sb, "Block1", msg.Block1.ToString());
            }
            if (msg.Block2 != null)
            {
                appendIfNotNullOrEmpty(sb, "Block2", msg.Block2.ToString());
            }
            if (msg.Observe.HasValue)
            {
                appendIfNotNullOrEmpty(sb, "Observe", msg.Observe.ToString());
            }
            return(sb.ToString());
        }
Example #3
0
        /// <summary>
        /// Gets the coap options starting from an array of http headers. The
        /// content-type is not handled by this method. The method iterates over an
        /// array of headers and for each of them tries to find a predefined mapping
        /// if the mapping does not exists it skips the header
        /// ignoring it. The method handles separately certain headers which are
        /// translated to options (such as accept or cache-control) whose content
        /// should be semantically checked or requires ad-hoc translation. Otherwise,
        /// the headers content is translated with the appropriate format required by
        /// the mapped option.
        /// </summary>
        /// <param name="headers"></param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        public static IEnumerable <Option> GetCoapOptions(NameValueCollection headers)
        {
            if (headers == null)
            {
                ThrowHelper.ArgumentNullException("headers");
            }

            List <Option> list = new List <Option>();

            foreach (String key in headers.AllKeys)
            {
                OptionType ot;
                if (!http2coapOption.TryGetValue(key, out ot))
                {
                    continue;
                }

                // ignore the content-type because it will be handled within the payload
                if (ot == OptionType.ContentType)
                {
                    continue;
                }

                String headerValue = headers[key].Trim();
                if (ot == OptionType.Accept)
                {
                    // if it contains the */* wildcard, no CoAP Accept is set
                    if (!headerValue.Contains("*/*"))
                    {
                        // remove the part where the client express the weight of each
                        // choice
                        headerValue = headerValue.Split(';')[0].Trim();

                        // iterate for each content-type indicated
                        foreach (String headerFragment in headerValue.Split(','))
                        {
                            // translate the content-type
                            IEnumerable <Int32> coapContentTypes;
                            if (headerFragment.Contains("*"))
                            {
                                coapContentTypes = MediaType.ParseWildcard(headerFragment);
                            }
                            else
                            {
                                coapContentTypes = new Int32[] { MediaType.Parse(headerFragment) }
                            };

                            // if is present a conversion for the content-type, then add
                            // a new option
                            foreach (int coapContentType in coapContentTypes)
                            {
                                if (coapContentType != MediaType.Undefined)
                                {
                                    // create the option
                                    Option option = Option.Create(ot);
                                    option.IntValue = coapContentType;
                                    list.Add(option);
                                }
                            }
                        }
                    }
                }
                else if (ot == OptionType.MaxAge)
                {
                    int maxAge = 0;
                    if (!headerValue.Contains("no-cache"))
                    {
                        headerValue = headerValue.Split(',')[0];
                        if (headerValue != null)
                        {
                            Int32 index = headerValue.IndexOf('=');
                            if (!Int32.TryParse(headerValue.Substring(index + 1).Trim(), out maxAge))
                            {
                                continue;
                            }
                        }
                    }
                    // create the option
                    Option option = Option.Create(ot);
                    option.IntValue = maxAge;
                    list.Add(option);
                }
                else
                {
                    Option option = Option.Create(ot);
                    switch (Option.GetFormatByType(ot))
                    {
                    case OptionFormat.Integer:
                        option.IntValue = Int32.Parse(headerValue);
                        break;

                    case OptionFormat.Opaque:
                        option.RawValue = ByteArrayUtils.FromHexStream(headerValue);
                        break;

                    case OptionFormat.String:
                    default:
                        option.StringValue = headerValue;
                        break;
                    }
                    list.Add(option);
                }
            }

            return(list);
        }