/// <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; }