HTTP-CoAP Mapping draft 정리

(이 포스트는 IETF Core WG의 draft
"Guidelines for HTTP-CoAP Mapping Implementations"의
내용을 정리한 것입니다.)

CoAP은 센서와 원활한 REST 기반의 통신을 하기 위한 프로토콜이다. 센서와 통신하기 위해서는 클라이언트에서도 CoAP이 구현되어 있어야 하는데,
우리가 접할 수 있는 대부분의 단말 (스마트폰, PC, ...)에는 당연히(!) 구현되어 있지 않다.

그러나 만약 CoAP을 HTTP와 같은 대중적인 프로토콜로 변환할 수 있는 장비를
중간에 둔다면 웹 브라우저나 curl 등 일반적인 HTTP 클라이언트를 통해서도
센서와 통신할 수 있을 것이다.

중간의 이와 같은 CoAP-HTTP 변환 역할을 해주는 장비를
HTTP-CoAP Proxy (줄여서 HC proxy)라 한다.

참고로 proxy는 크게 forward proxy와 reverse proxy로 나뉘는데,
HTTP를 예로 들어 간단하게 설명하자면 전자는 (회사 등) 특정 사이트 안에 있는 사용자가 외부 웹에 접근할 때 사용자를 대신하여 대상 웹 서버에 접근하는 proxy이고, 후자는 반대로 외부로부터 특정 사이트의 웹 서버에 접근할 때 그 앞단에서 해당 서버와의 연결을 간접적으로 처리하는 proxy이다.

HC proxy의 경우 forward proxy 방식은 CoAP RFC 문서에서 정의하고 있고, 본 draft에서는 reverse proxy 방식에 대해서 설명한다. 해당 draft에서는 HC proxy 동작의 정의를 다음과 같은 범주로 나누어 설명하고 있다:

  1. URI mapping
  2. Discovery
  3. Media type mapping
  4. Response code mapping
  5. Cache & congestion control, etc.

1. URI mapping

사용자는는 기본적으로 HC proxy를 가리키는 URI (base URI)와
CoAP 센서의 특정 리소스를 가리키는 URI (target CoAP URI)를 조합한 hosting HTTP URI로 만들어 사용한다.

이 중 target CoAP URI를 어떠한 방식으로 변환하여 조합할 지는
사전에 정의한 URI mapping template에 따라 명시적으로 정의된다.
이러한 정보는 다음 Discovery 섹션에서 설명하는 바와 같이
CoAP resource discovery 과정을 통해 클라이언트에게 전달된다.

URI mapping template에서 사용하는 요소는 다음과 같다:

  • cu: coap URI
  • su: coaps URI
  • tu: cu or su
  • s: "coap" or "coaps"
  • hp: host [":" port]
  • p: path-abempty
  • q: query
  • qq: ["?" query] where qq is empty iff 'query' is empty

예로 base URI와 target CoAP URI가 다음과 같을 때,

hosting HTTP URI는 template에 따라 다음과 같이 조합할 수 있다.

'?coap_target_uri={+cu}'
    http://p.example.com/hc?coap_target_uri=coap://s.example.com/light
    http://p.example.com/hc?coap_target_uri=s.example.com/light
'?coaps_target_uri={+su}'
    http://p.example.com/hc?coaps_target_uri=coaps://s.example.com/light
'?target_uri={+tu}'
    http://p.example.com/hc?target_uri=coap://s.example.com/light
    http://p.example.com/hc?target_uri=coaps://s.example.com/light
'/{+tu}'
    http://p.example.com/hc/coap://s.example.com/light
    http://p.example.com/hc/coaps://s.example.com/light
'{+s}{+hp}{+p}{+qq}'
    http://p.example.com/hc/coap/s.example.com/light
    http://p.example.com/hc/coap/s.example.com/light?on
'?s={+s}&hp={+hp}&p={+p}&q={+q}'
    http://p.example.com/hc?s=coap&hp=s.example.com&p=light&q=
    http://p.example.com/hc?s=coap&hp=s.example.com&p=light&q=on

2. Discovery

CoAP을 지원하는 센서에서는 CoRE Link Format에 따라 자신의 리소스 정보를 제공한다. 본 draft에서는 여기에 맞춰 HC proxy 정보를 제공할 수 있는 resource type과 target attribute를 추가 정의하였다.

센서에서 이용 가능한 HC proxy 정보는 core.hc resource type을 새로 정의하여 제공한다.

Req: GET coap://[ff02::1]/.well-known/core?rt=core.hc
Res: 2.05 Content
     </hc>;anchor="http://p.example.com";rt="core.hc"

hct target attribute를 추가하여 URI mapping template 정보를 명시적으로 클라이언트에게
전달할 수도 있다.

Req: GET coap://[ff02::1]/.well-known/core?rt=core.hc
Res: 2.05 Content
     </hc>;anchor="http://p.example.com";rt="core.hc;hct={+tu}"

HC proxy의 HTTP 측으로는 클라이언트에게 아래와 같이 proxy 접근 정보를 제공할 수 있다.

Req: GET /.well-known/core?rt=core.hc HTTP/1.1
     Host: p.example.com
Res: HTTP/1.1 200 OK
     Content-Type: application/link-format
     Content-Length: 18

     </hc>;rt="core.hc"

아래는 link format 정보를 JSON 형식으로 제공하는 예이다.

Req: GET /.well-known/core?rt=core.hc HTTP/1.1
     Host: p.example.com
Res: HTTP/1.1 200 OK
     Content-Type: application/link-format+json
     Content-Length: 31

     [{"href":"/hc", "rt":"core.hc"}]

HTTP payload 대신 Link 헤더에 실어 보낸 경우이다.

Req: GET /.well-known/core?rt=core.hc HTTP/1.1
     Host: p.example.com
Res: HTTP/1.1 200 OK
     Link: </hc>;rt="core.hc"

또는 아래와 같이 coap 또는 coaps에 따라 두 개의 다른 base URI를 노출할 수도 있다.

Req: GET /.well-known/core?rt=core.hc HTTP/1.1
     Host: p.example.com
Res: HTTP/1.1 200 OK
     Content-Type: application/link-format+json
     Content-Length: 111

     [
       {"href":"/hc/plaintext", "rt":"core.hc", "hct":"{+cu}"},
       {"href":"/hc/secure", "rt":"core.hc", "hct":"{+su}"}
     ]

3. Media type mapping

HTTP의 Content-TypeContent-Encoding 헤더의 값과 CoAP의 Content-Format 옵션 값 사이의 변환, 그리고 HTTP의 AcceptAccept-Encoding 헤더의 값과 CoAP Accept 옵션 값 사이의 변환을 포함한다.

서로 정확하게 1:1 변환이 되면 좋겠지만, 앞에서 보다시피
HTTP의 두 개 헤더를 CoAP의 한 개 옵션과 mapping해야 하고, HTTP 쪽은 이미 1000개가 넘는 media type이 등록되어 있는 반면에 CoAP 쪽은 10개도 채 안되기 때문에 기계적인 변환이 어렵다. 변환 메카니즘을 구성하는데 필요한 요소는 다음과 같다.

Tight/Loose coupling

tight coupling 방식은 말 그대로 정확히 일치하는 HTTP internet media type과 CoAP content format 사이의 변환만 진행하는 것이다. 반면 loose coupling은 비슷한 부류끼리 일반화된 media type으로 묶은 뒤 그에 맞는 CoAP content format으로 변환하는 것이다. 다음 표는 그 예이다.

 Internet media typeGeneralized media type  application/*+xmlapplication/xml  applicatoin/*+jsonapplication/json  text/xmlapplication/xml  text/*text/plain  */*application/octet-stream

Media type to Content format mapping algorithm

HTTP의 Content-Type, Content-Encoding 헤더 값을 갖고 fail 처리 혹은 CoAP Content-Format으로 변환하기 위한 동작 알고리즘을 명시한다. 위에서 설명한 generalized media type 표를 통한 loose coupling도 포함하고 있다. 알고리즘 자체는 draft 6.4절에 도시된 내용으로 대신한다.

알고리즘은 완벽한 1:1 변환을 보장해주지 않으며, 일부 type 정보의 유실이나 다른 일반화된
type으로의 변환 등 side effect 문제를 포함하고 있다.

Content transcoding

선택적으로 적용 가능한 것으로, 가령
XML을 EXI (efficient XML interchange)로 대체하거나 JSON을 CBOR (concise binary object representation)으로 바꾸는 등 서로 호환되면서 동일 내용을 보다 효율적으로 전송할 수 있는 content format으로 대체하는 것을 말한다. 이 또한 앞서 언급한 side effect 문제를 일으키는 원인 중 하나다.

Unrecognized value

만약 HTTP internet media type을 CoAP content format으로 변환하는데 실패한 경우,
HTTP 415 Unsupported Media Type으로 반송한다.

반대로 HC proxy에서 수신한 CoAP 메시지의 content format이 인식할 수 없는 값이면 HTTP 메시지의 Content-Type 헤더에 'application/coap-payload' type으로 설정하고 여기에 cf 파라미터를 추가하여 CoAP Content-Format 옵션 값을 같이 보낼 수 있다.

Content-Type: application/coap-payload;cf=60

4. Response code mapping

다음 표 하나로 설명을 대체할 수 있을 듯 하다.

 CoAP Response CodeHTTP Status CodeNotes  2.01 Created201 Created1  2.02 Deleted200 OK2  204 No Content2  2.03 Valid304 Not Modified3  200 OK4  2.04 Changed200 OK2  204 No Content2  2.05 Content200 OK  4.00 Bad Request400 Bad Request  4.01 Unauthorized401 Unauthorized5  4.02 Bad Option400 Bad Request6  4.03 Forbidden403 Forbidden  4.04 Not Found404 Not Found  4.05 Method Not Allowed400 Bad Request7  4.06 Not Acceptable406 Not Acceptable  4.12 Precondition Failed412 Precondition Failed  4.13 Request Ent. Too Large413 Request Repr. Too Large  4.15 Unsupported Media Type415 Unsupported Media Type  5.00 Internal Server Error500 Internal Server Error  5.01 Not Implemented501 Not Implemented  5.02 Bad Gateway502 Bad Gateway  5.03 Service Unavailable503 Service Unavailable8  5.04 Gateway Timeout504 Gateway Timeout  5.05 Proxying Not Supported502 Bad Gateway9

note:

  1. 반드시 CoAP payload를 같이 보내야 한다.
  2. PUT, POST, DELETE에 대한 응답은 200으로, 그 외에는 204로 보낸다.
  3. HTTP conditional request에 대해 CoAP 2.04 응답이 온 경우에 304로 응답한다.
  4. HTTP conditional request가 아니고 ETag 헤더를 포함할 때.
  5. WWW-Authenticate 헤더를 포함해야 한다.
  6. CoAP 4.02를 받으면 proxy는 HTTP 400 응답으로 바꿔 보내기 전에 우선 옵션 몇 개를 생략하고 다시 CoAP 요청을 시도해야 한다. HTTP 402 응답 코드를 사용하면 안된다.
  7. CoAP 4.05는 반드시 HTTP 400으로 바꿔야 한다.
  8. HTTP Retry-After 헤더 값은 CoAP Max-Age 옵션으로부터 얻는다.
  9. CoAP 5.05는 proxy가 forward proxy일 때만 발생되어야 한다.

5. Cache & congestion control, etc.

본 절에서는 draft의 8장 Additional Mapping Guidelines 내용의 일부만 소개한다.

  1. 만약 HTTP 연결 타임아웃으로 인해 HTTP 클라이언트에서 연결을 종료해도, HC proxy에서는 CoAP 응답이 수신될 때까지 기다렸다가 cache에 저장할 수 있어야 한다.
  2. HC proxy에서는 혼잡 제어를 위해 CoAP 서버 별로 동시 NSTART 이내로 요청을 제한해야 한다. 이 값은 CoAP RFC에 기본으로 1로 정의되어 있다. 또한 전체 센서 망에 유입되는 동시 CoAP request 수를 제한해야 하며 이를 위해 queueing 또는 drop 시키고 '503 Service Unavailable' HTTP 응답을 보내는 것으로 처리한다.
  3. HC proxy는 HTTP payload가 BLOCKWISE_THRESHOLD 보다 클 경우 blockwise 방식에 기반하여 전송한다.
  4. BLOCKWISE_THRESHOLD는 다양한 방법으로 결정되는데, CoAP 서버용 UDP 버퍼 크기, link-layer frame size, IP MTU 크기, 또는 path MTU 크기가 그 대상이 될 수 있다.