Example #1
0
        /// <summary>
        /// Gets the CoAP response from an incoming HTTP response. No null value is
	    /// returned. The response is created from a predefined mapping of the HTTP
        /// response codes. If the code is 204, which has
	    /// multiple meaning, the mapping is handled looking on the request method
	    /// that has originated the response. The options are set thorugh the HTTP
	    /// headers and the option max-age, if not indicated, is set to the default
	    /// value (60 seconds). if the response has an enclosing entity, it is mapped
	    /// to a CoAP payload and the content-type of the CoAP message is set
        /// properly.
        /// </summary>
        /// <param name="httpResponse">the http response</param>
        /// <param name="coapRequest">the coap response</param>
        /// <returns></returns>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="TranslationException"></exception>
        public static Response GetCoapResponse(HttpWebResponse httpResponse, Request coapRequest)
        {
            if (httpResponse == null)
                throw ThrowHelper.ArgumentNull("httpResponse");
            if (coapRequest == null)
                throw ThrowHelper.ArgumentNull("coapRequest");

            HttpStatusCode httpCode = httpResponse.StatusCode;
            StatusCode coapCode = 0;

            // the code 204-"no content" should be managed
            // separately because it can be mapped to different coap codes
            // depending on the request that has originated the response
            if (httpCode == HttpStatusCode.NoContent)
            {
                if (coapRequest.Method == Method.DELETE)
                    coapCode = StatusCode.Deleted;
                else
                    coapCode = StatusCode.Changed;
            }
            else
            {
                if (!http2coapCode.TryGetValue(httpCode, out coapCode))
                    throw ThrowHelper.TranslationException("Cannot convert the HTTP status " + httpCode);
            }

            // create the coap reaponse
            Response coapResponse = new Response(coapCode);

            // translate the http headers in coap options
            IEnumerable<Option> coapOptions = GetCoapOptions(httpResponse.Headers);
            coapResponse.SetOptions(coapOptions);

            // the response should indicate a max-age value (CoAP 10.1.1)
            if (!coapResponse.HasOption(OptionType.MaxAge))
            {
                // The Max-Age Option for responses to POST, PUT or DELETE requests
                // should always be set to 0 (draft-castellani-core-http-mapping).
                coapResponse.MaxAge = coapRequest.Method == Method.GET ? CoapConstants.DefaultMaxAge : 0;
            }

            Byte[] buffer = new Byte[4096];
            using (Stream ms = new MemoryStream(buffer.Length), dataStream = httpResponse.GetResponseStream())
            {
                Int32 read;
                while ((read = dataStream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    ms.Write(buffer, 0, read);
                }
                Byte[] payload = ((MemoryStream)ms).ToArray();
                if (payload.Length > 0)
                {
                    coapResponse.Payload = payload;
                    coapResponse.ContentType = GetCoapMediaType(httpResponse.GetResponseHeader("content-type"));
                }
            }

            return coapResponse;
        }