From 75cfb666e8faa09b13a07df848adc5073db74253 Mon Sep 17 00:00:00 2001 From: Stephen von Takach Date: Sat, 29 Jul 2023 14:32:22 +1000 Subject: [PATCH] feat: breakout CoAP header allows for improved payload processing as we can check if the data is possibly good before processing or buffering --- shard.lock | 4 ++-- shard.yml | 2 +- src/coap/client.cr | 6 +++--- src/coap/client/request.cr | 8 ++++---- src/coap/message.cr | 10 ++++++++-- 5 files changed, 18 insertions(+), 12 deletions(-) diff --git a/shard.lock b/shard.lock index 8af909e..7dc5e4f 100644 --- a/shard.lock +++ b/shard.lock @@ -2,11 +2,11 @@ version: 2.0 shards: ameba: git: https://github.com/veelenga/ameba.git - version: 0.14.2 + version: 1.5.0 bindata: git: https://github.com/spider-gazelle/bindata.git - version: 1.8.3 + version: 1.11.1 dtls: git: https://github.com/spider-gazelle/crystal-dtls.git diff --git a/shard.yml b/shard.yml index 559241a..6740002 100644 --- a/shard.yml +++ b/shard.yml @@ -1,5 +1,5 @@ name: coap -version: 1.1.0 +version: 1.2.0 crystal: ">= 0.36.1" dependencies: diff --git a/src/coap/client.cr b/src/coap/client.cr index dd09364..04e06ca 100644 --- a/src/coap/client.cr +++ b/src/coap/client.cr @@ -25,10 +25,10 @@ class CoAP::Client end def self.new(uri : URI, tls : TLSContext = nil) - scheme = uri.scheme.not_nil!.downcase + scheme = uri.scheme.as(String).downcase port = uri.port || URI.default_port(scheme) || raise("unable to infer CoAP port for #{uri}") raise "TLS required for coaps" if tls == false && scheme == "coaps" - self.new(uri.host.not_nil!, port, tls) + self.new(uri.host.as(String), port, tls) end @mutex = Mutex.new(:reentrant) @@ -131,7 +131,7 @@ class CoAP::Client end def exec!(request : CoAP::Request) : CoAP::ResponseHandler - exec(request).not_nil! + exec(request).as(CoAP::ResponseHandler) end # message_id => token id diff --git a/src/coap/client/request.cr b/src/coap/client/request.cr index e819d9e..8590645 100644 --- a/src/coap/client/request.cr +++ b/src/coap/client/request.cr @@ -23,14 +23,14 @@ class CoAP::Request < HTTP::Request message.code_detail = CoAP::MethodCode.parse(self.method.upcase).to_u8 options = self.path.split('/').compact_map { |segment| CoAP::Option.new.string(segment).type(CoAP::Options::Uri_Path) if segment.presence } - options << CoAP::Option.new.string(self.query.not_nil!).type(CoAP::Options::Uri_Query) if self.query.presence + options << CoAP::Option.new.string(self.query.as(String)).type(CoAP::Options::Uri_Query) if self.query.presence if origin = self.headers.delete("Origin") uri = URI.parse origin - default_port = URI.default_port(uri.scheme.not_nil!.downcase) + default_port = URI.default_port(uri.scheme.as(String).downcase) port = uri.port || default_port || raise("unable to infer CoAP port for #{origin}") - options << CoAP::Option.new.string(uri.host.not_nil!).type(CoAP::Options::Uri_Host) + options << CoAP::Option.new.string(uri.host.as(String)).type(CoAP::Options::Uri_Host) options << CoAP::Option.new.uri_port(port).type(CoAP::Options::Uri_Port) unless port == default_port else raise "no 'Origin' header provided" @@ -79,7 +79,7 @@ class CoAP::Request < HTTP::Request # Extract the payload buffer = IO::Memory.new buf = Bytes.new(64) - while ((bytes = data.read(buf)) > 0) + while (bytes = data.read(buf)) > 0 buffer.write(buf[0, bytes]) end message.payload_data = buffer.to_slice diff --git a/src/coap/message.cr b/src/coap/message.cr index 48f8d02..0607a3c 100644 --- a/src/coap/message.cr +++ b/src/coap/message.cr @@ -5,8 +5,7 @@ require "./option" # coap:// default port 5683 # coaps:// default port 5684 -# https://tools.ietf.org/html/rfc7252#section-3 -class CoAP::Message < BinData +class CoAP::Header < BinData endian big enum Type @@ -25,7 +24,14 @@ class CoAP::Message < BinData enum_bits 2, type : Type = Type::Confirmable bits 4, :token_length, value: ->{ token.size.to_u8 } + end +end +# https://tools.ietf.org/html/rfc7252#section-3 +class CoAP::Message < CoAP::Header + endian big + + bit_field do # https://tools.ietf.org/html/rfc7252#section-12.1 enum_bits 3, code_class : CodeClass = CodeClass::Method